Changeset 2b61945 in mainline for uspace/drv/bus/usb/xhci/bus.c
- Timestamp:
- 2017-10-22T03:47:41Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2e5aea1
- Parents:
- 766043c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/bus.c
r766043c r2b61945 35 35 #include <adt/hash_table.h> 36 36 #include <adt/hash.h> 37 #include <usb/host/utils/malloc32.h> 37 38 #include <usb/host/ddf_helpers.h> 38 39 #include <usb/host/endpoint.h> … … 58 59 } hashed_device_t; 59 60 61 static int hashed_device_insert(xhci_bus_t *bus, hashed_device_t **hashed_dev, xhci_device_t *dev); 62 static int hashed_device_remove(xhci_bus_t *bus, hashed_device_t *hashed_dev); 63 static int hashed_device_find_by_address(xhci_bus_t *bus, usb_address_t address, hashed_device_t **dev); 64 60 65 /** TODO: Still some copy-pasta left... 61 66 */ … … 63 68 { 64 69 int err; 70 xhci_device_t *xhci_dev = xhci_device_get(dev); 65 71 66 72 /* TODO: get speed from the default address reservation */ … … 85 91 } 86 92 93 assert(bus->devices_by_slot[xhci_dev->slot_id] == NULL); 94 bus->devices_by_slot[xhci_dev->slot_id] = xhci_dev; 95 96 hashed_device_t *hashed_dev = NULL; 97 if ((err = hashed_device_insert(bus, &hashed_dev, xhci_dev))) 98 goto err_address; 99 87 100 /* Read the device descriptor, derive the match ids */ 88 101 if ((err = hcd_ddf_device_explore(hc->hcd, dev))) { 89 102 usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err)); 90 bus_release_address(&bus->base, dev->address); 91 return err; 92 } 93 94 return EOK; 103 goto err_hash; 104 } 105 106 return EOK; 107 108 err_hash: 109 bus->devices_by_slot[xhci_dev->slot_id] = NULL; 110 hashed_device_remove(bus, hashed_dev); 111 err_address: 112 bus_release_address(&bus->base, dev->address); 113 return err; 95 114 } 96 115 97 116 int xhci_bus_remove_device(xhci_bus_t *bus, xhci_hc_t *hc, device_t *dev) 98 117 { 99 // TODO: Implement me! 118 xhci_device_t *xhci_dev = xhci_device_get(dev); 119 120 // TODO: Release remaining EPs 121 122 hashed_device_t *hashed_dev; 123 int res = hashed_device_find_by_address(bus, dev->address, &hashed_dev); 124 if (res) 125 return res; 126 127 res = hashed_device_remove(bus, hashed_dev); 128 if (res != EOK) 129 return res; 130 131 // XXX: Ugly here. Move to device_destroy at endpoint.c? 132 free32(xhci_dev->dev_ctx); 133 hc->dcbaa[xhci_dev->slot_id] = 0; 100 134 return ENOTSUP; 101 135 } … … 134 168 xhci_bus_t *bus = bus_to_xhci_bus(base); 135 169 136 xhci_endpoint_t *ep = malloc(sizeof(xhci_endpoint_t));170 xhci_endpoint_t *ep = calloc(1, sizeof(xhci_endpoint_t)); 137 171 if (!ep) 138 172 return NULL; … … 179 213 } 180 214 181 static int hashed_device_create(xhci_bus_t *bus, hashed_device_t **hashed_dev, usb_address_t address) 182 { 183 int res; 184 xhci_device_t *dev = (xhci_device_t *) malloc(sizeof(xhci_device_t)); 185 if (!dev) { 186 res = ENOMEM; 187 goto err_xhci_dev_alloc; 188 } 189 190 res = xhci_device_init(dev, bus, address); 191 if (res != EOK) { 192 goto err_xhci_dev_init; 193 } 194 195 hashed_device_t *ret_dev = (hashed_device_t *) malloc(sizeof(hashed_device_t)); 196 if (!ret_dev) { 197 res = ENOMEM; 198 goto err_hashed_dev_alloc; 199 } 215 static int hashed_device_insert(xhci_bus_t *bus, hashed_device_t **hashed_dev, xhci_device_t *dev) 216 { 217 hashed_device_t *ret_dev = (hashed_device_t *) calloc(1, sizeof(hashed_device_t)); 218 if (!ret_dev) 219 return ENOMEM; 200 220 201 221 ret_dev->device = dev; 202 222 203 usb_log_info("Device(%d) registered to XHCI bus.", dev-> address);223 usb_log_info("Device(%d) registered to XHCI bus.", dev->base.address); 204 224 205 225 hash_table_insert(&bus->devices, &ret_dev->link); 206 226 *hashed_dev = ret_dev; 207 227 return EOK; 208 209 err_hashed_dev_alloc:210 err_xhci_dev_init:211 free(dev);212 err_xhci_dev_alloc:213 return res;214 228 } 215 229 216 230 static int hashed_device_remove(xhci_bus_t *bus, hashed_device_t *hashed_dev) 217 231 { 218 usb_log_info("Device(%d) released from XHCI bus.", hashed_dev->device->address); 219 220 hash_table_remove(&bus->devices, &hashed_dev->device->address); 221 xhci_device_fini(hashed_dev->device); 222 free(hashed_dev->device); 232 usb_log_info("Device(%d) released from XHCI bus.", hashed_dev->device->base.address); 233 234 hash_table_remove(&bus->devices, &hashed_dev->device->base.address); 223 235 free(hashed_dev); 224 236 … … 231 243 assert(bus); 232 244 233 hashed_device_t *hashed_dev;234 int res = hashed_device_find_by_address(bus, ep->target.address, &hashed_dev);235 if (res != EOK && res != ENOENT)236 return res;237 238 if (res == ENOENT) {239 res = hashed_device_create(bus, &hashed_dev, ep->target.address);240 241 if (res != EOK)242 return res;243 }244 245 245 usb_log_info("Endpoint(%d:%d) registered to XHCI bus.", ep->target.address, ep->target.endpoint); 246 246 247 return xhci_device_add_endpoint(hashed_dev->device, xhci_endpoint_get(ep)); 247 xhci_device_t *xhci_dev = xhci_device_get(ep->device); 248 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep); 249 return xhci_device_add_endpoint(xhci_dev, xhci_ep); 248 250 } 249 251 … … 255 257 usb_log_info("Endpoint(%d:%d) released from XHCI bus.", ep->target.address, ep->target.endpoint); 256 258 257 hashed_device_t *hashed_dev; 258 int res = hashed_device_find_by_address(bus, ep->target.address, &hashed_dev); 259 xhci_device_t *xhci_dev = xhci_device_get(ep->device); 260 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep); 261 const int res = xhci_device_remove_endpoint(xhci_dev, xhci_ep); 259 262 if (res != EOK) 260 263 return res; 261 264 262 res = xhci_device_remove_endpoint(hashed_dev->device, xhci_endpoint_get(ep));263 if (res != EOK)264 return res;265 266 if (hashed_dev->device->active_endpoint_count == 0) {267 res = hashed_device_remove(bus, hashed_dev);268 269 if (res != EOK)270 return res;271 }272 273 265 return EOK; 274 266 } … … 278 270 xhci_bus_t *bus = bus_to_xhci_bus(bus_base); 279 271 assert(bus); 280 272 281 273 xhci_endpoint_t *ep; 282 274 int res = xhci_endpoint_find_by_target(bus, target, &ep); … … 349 341 { 350 342 hashed_device_t *dev = hash_table_get_inst(item, hashed_device_t, link); 351 return (size_t) hash_mix(dev->device-> address);343 return (size_t) hash_mix(dev->device->base.address); 352 344 } 353 345 … … 360 352 { 361 353 hashed_device_t *dev = hash_table_get_inst(item, hashed_device_t, link); 362 return dev->device-> address == *(usb_address_t *) key;354 return dev->device->base.address == *(usb_address_t *) key; 363 355 } 364 356 … … 372 364 }; 373 365 374 int xhci_bus_init(xhci_bus_t *bus) 375 { 376 assert(bus); 377 378 bus_init(&bus->base, sizeof(device_t)); 366 int xhci_bus_init(xhci_bus_t *bus, xhci_hc_t *hc) 367 { 368 assert(bus); 369 370 bus_init(&bus->base, sizeof(xhci_device_t)); 371 372 bus->devices_by_slot = calloc(hc->max_slots, sizeof(xhci_device_t *)); 373 if (!bus->devices_by_slot) 374 return ENOMEM; 379 375 380 376 if (!hash_table_create(&bus->devices, 0, 0, &device_ht_ops)) { 381 // FIXME: Dealloc base!377 free(bus->devices_by_slot); 382 378 return ENOMEM; 383 379 }
Note:
See TracChangeset
for help on using the changeset viewer.