Changeset a4e26882 in mainline
- 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
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/bus.c
r2c091a6 ra4e26882 118 118 xhci_device_t *xhci_dev = xhci_device_get(dev); 119 119 120 // TODO: Release remaining EPs 120 /* Release remaining endpoints. */ 121 for (size_t i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) { 122 if (!xhci_dev->endpoints[i]) 123 continue; 124 125 // FIXME: ignoring return code 126 bus_release_endpoint(&bus->base, &xhci_dev->endpoints[i]->base); 127 } 121 128 122 129 hashed_device_t *hashed_dev; … … 270 277 xhci_bus_t *bus = bus_to_xhci_bus(bus_base); 271 278 assert(bus); 272 279 273 280 xhci_endpoint_t *ep; 274 281 int res = xhci_endpoint_find_by_target(bus, target, &ep); -
uspace/drv/bus/usb/xhci/endpoint.c
r2c091a6 ra4e26882 182 182 assert(ep); 183 183 184 /* Offline devices don't create new endpoints other than EP0. */ 185 if (!dev->online) { 186 return EAGAIN; 187 } 188 184 189 int err = ENOMEM; 185 190 const usb_endpoint_t ep_num = ep->base.target.endpoint; -
uspace/drv/bus/usb/xhci/endpoint.h
r2c091a6 ra4e26882 94 94 /** Flag indicating whether the device is USB3 (it's USB2 otherwise). */ 95 95 bool usb3; 96 97 /** True if the device can add new endpoints and schedule transfers. */ 98 volatile bool online; 96 99 } xhci_device_t; 97 100 98 101 int xhci_endpoint_init(xhci_endpoint_t *, xhci_bus_t *); 99 102 void xhci_endpoint_fini(xhci_endpoint_t *); 100 101 int xhci_device_init(xhci_device_t *, xhci_bus_t *, usb_address_t);102 void xhci_device_fini(xhci_device_t *);103 103 104 104 uint8_t xhci_endpoint_dci(xhci_endpoint_t *); -
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. -
uspace/drv/bus/usb/xhci/transfers.c
r2c091a6 ra4e26882 248 248 } 249 249 250 int xhci_transfer_abort(xhci_transfer_t *transfer) 251 { 252 usb_transfer_batch_t *batch = &transfer->batch; 253 batch->error = EAGAIN; 254 batch->transfered_size = 0; 255 usb_transfer_batch_finish(batch); 256 return EOK; 257 } 258 250 259 int xhci_handle_transfer_event(xhci_hc_t* hc, xhci_trb_t* trb) 251 260 { … … 304 313 assert(xhci_ep); 305 314 315 xhci_device_t *xhci_dev = xhci_ep_to_dev(xhci_ep); 316 317 /* Offline devices don't schedule transfers other than on EP0. */ 318 if (!xhci_dev->online && xhci_ep->base.target.endpoint) { 319 return EAGAIN; 320 } 321 306 322 const usb_transfer_type_t type = batch->ep->transfer_type; 307 323 assert(type >= 0 && type < ARRAY_SIZE(transfer_handlers)); … … 321 337 return err; 322 338 323 const uint8_t slot_id = xhci_ ep_to_dev(xhci_ep)->slot_id;339 const uint8_t slot_id = xhci_dev->slot_id; 324 340 const uint8_t target = xhci_endpoint_index(xhci_ep) + 1; /* EP Doorbells start at 1 */ 325 341 return hc_ring_doorbell(hc, slot_id, target); -
uspace/drv/bus/usb/xhci/transfers.h
r2c091a6 ra4e26882 55 55 56 56 xhci_transfer_t* xhci_transfer_create(endpoint_t *); 57 int xhci_transfer_schedule(xhci_hc_t*, usb_transfer_batch_t *); 58 int xhci_handle_transfer_event(xhci_hc_t*, xhci_trb_t*); 59 void xhci_transfer_destroy(xhci_transfer_t*); 57 int xhci_transfer_schedule(xhci_hc_t *, usb_transfer_batch_t *); 58 int xhci_transfer_abort(xhci_transfer_t *); 59 int xhci_handle_transfer_event(xhci_hc_t *, xhci_trb_t *); 60 void xhci_transfer_destroy(xhci_transfer_t *); 60 61 61 62 static inline xhci_transfer_t *xhci_transfer_from_batch(usb_transfer_batch_t *batch)
Note:
See TracChangeset
for help on using the changeset viewer.