Changeset a4e26882 in mainline for uspace/drv/bus/usb/xhci/rh.c
- Timestamp:
- 2017-10-22T16:37:44Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4594baa
- Parents:
- 2c091a6
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/rh.c
r2c091a6 ra4e26882 68 68 rh->hc = hc; 69 69 rh->max_ports = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_PORTS); 70 rh->devices = (xhci_device_t **) malloc(rh->max_ports *sizeof(xhci_device_t *));70 rh->devices = (xhci_device_t **) calloc(rh->max_ports, sizeof(xhci_device_t *)); 71 71 hc->rh.hc_device = device; 72 73 memset(rh->devices, 0, rh->max_ports * sizeof(xhci_device_t *));74 72 75 73 return device_init(&hc->rh.device); … … 149 147 usb_log_debug2("Obtained USB address: %d.\n", dev->address); 150 148 149 /* From now on, the device is officially online, yay! */ 150 fibril_mutex_lock(&dev->guard); 151 xhci_dev->online = true; 152 fibril_mutex_unlock(&dev->guard); 153 151 154 // XXX: Going around bus, duplicating code 152 155 ep0_base->device = dev; … … 264 267 static int handle_disconnected_device(xhci_rh_t *rh, uint8_t port_id) 265 268 { 269 assert(rh); 270 int err; 271 266 272 /* Find XHCI device by the port. */ 267 273 xhci_device_t *dev = rh->devices[port_id - 1]; 268 274 if (!dev) { 269 /* Must be extraneous call */275 /* Must be extraneous call. */ 270 276 return EOK; 271 277 } 272 278 273 usb_log_info("Device at port %u has been disconnected.", port_id); 274 275 // TODO: Destroy DDF function using _gone. 276 // TODO: Remove device endpoints on the bus. 279 usb_log_info("Device '%s' at port %u has been disconnected.", ddf_fun_get_name(dev->base.fun), port_id); 280 281 /* Block creation of new endpoints and transfers. */ 282 fibril_mutex_lock(&dev->base.guard); 283 dev->online = false; 284 fibril_mutex_unlock(&dev->base.guard); 285 286 fibril_mutex_lock(&rh->device.guard); 287 list_remove(&dev->base.link); 288 fibril_mutex_unlock(&rh->device.guard); 289 290 rh->devices[port_id - 1] = NULL; 291 usb_log_debug2("Aborting all active transfers to '%s'.", ddf_fun_get_name(dev->base.fun)); 292 293 /* Abort running transfers. */ 294 for (size_t i = 0; i < ARRAY_SIZE(dev->endpoints); ++i) { 295 xhci_endpoint_t *ep = dev->endpoints[i]; 296 if (!ep || !ep->base.active) 297 continue; 298 299 if ((err = xhci_transfer_abort(&ep->active_transfer))) { 300 usb_log_warning("Failed to abort active %s transfer to " 301 " endpoint %d of detached device '%s': %s", 302 usb_str_transfer_type(ep->base.transfer_type), 303 ep->base.target.endpoint, ddf_fun_get_name(dev->base.fun), 304 str_error(err)); 305 } 306 } 307 308 /* Make DDF (and all drivers) forget about the device. */ 309 if ((err = ddf_fun_unbind(dev->base.fun))) { 310 usb_log_warning("Failed to unbind DDF function of detached device '%s': %s", 311 ddf_fun_get_name(dev->base.fun), str_error(err)); 312 } 313 314 /* FIXME: 315 * A deadlock happens on the previous line. For some reason, the HID driver 316 * does not fully release its DDF function (tracked it down to release_endpoint 317 * in usb_remote.c so far). 318 * 319 * For that reason as well, the following 3 lines are untested. 320 */ 321 322 xhci_bus_remove_device(&rh->hc->bus, rh->hc, &dev->base); 323 hc_disable_slot(rh->hc, dev->slot_id); 324 hcd_ddf_device_destroy(&dev->base); 325 277 326 // TODO: Free device context. 278 327 // TODO: Free TRB rings.
Note:
See TracChangeset
for help on using the changeset viewer.