Changeset c10daa8 in mainline for uspace/drv/bus/usb/xhci/bus.c
- Timestamp:
- 2017-10-13T12:32:57Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 063dfe8
- Parents:
- 366e9b6
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/bus.c
r366e9b6 rc10daa8 50 50 ht_link_t link; 51 51 52 /** Endpoint*/53 xhci_ endpoint_t *endpoint;54 } hashed_ endpoint_t;52 /** Device */ 53 xhci_device_t *device; 54 } hashed_device_t; 55 55 56 56 /** Ops receive generic bus_t pointer. */ … … 85 85 } 86 86 87 static int endpoint_find_by_target(xhci_bus_t *bus, usb_target_t target, hashed_endpoint_t **ep)88 { 89 ht_link_t *link = hash_table_find(&bus-> endpoints, &target.packed);87 static int hashed_device_find_by_address(xhci_bus_t *bus, usb_address_t address, hashed_device_t **dev) 88 { 89 ht_link_t *link = hash_table_find(&bus->devices, &address); 90 90 if (link == NULL) 91 91 return ENOENT; 92 92 93 *ep = hash_table_get_inst(link, hashed_endpoint_t, link); 94 return EOK; 95 } 96 97 static int register_endpoint(bus_t *bus_base, endpoint_t *ep) 98 { 99 xhci_bus_t *bus = bus_to_xhci_bus(bus_base); 100 assert(bus); 101 102 hashed_endpoint_t *hashed_ep = 103 (hashed_endpoint_t *) malloc(sizeof(hashed_endpoint_t)); 104 if (!hashed_ep) 105 return ENOMEM; 106 107 hashed_ep->endpoint = xhci_endpoint_get(ep); 108 hash_table_insert(&bus->endpoints, &hashed_ep->link); 109 110 return EOK; 111 } 112 113 static int release_endpoint(bus_t *bus_base, endpoint_t *ep) 114 { 115 xhci_bus_t *bus = bus_to_xhci_bus(bus_base); 116 assert(bus); 117 118 hashed_endpoint_t *hashed_ep; 119 int res = endpoint_find_by_target(bus, ep->target, &hashed_ep); 93 *dev = hash_table_get_inst(link, hashed_device_t, link); 94 return EOK; 95 } 96 97 static int xhci_endpoint_find_by_target(xhci_bus_t *bus, usb_target_t target, xhci_endpoint_t **ep) 98 { 99 hashed_device_t *dev; 100 int res = hashed_device_find_by_address(bus, target.address, &dev); 120 101 if (res != EOK) 121 102 return res; 122 103 123 hash_table_remove(&bus->endpoints, &ep->target.packed); 124 free(hashed_ep); 104 xhci_endpoint_t *ret_ep = xhci_device_get_endpoint(dev->device, target.endpoint); 105 if (!ret_ep) 106 return ENOENT; 107 108 *ep = ret_ep; 109 return EOK; 110 } 111 112 static int hashed_device_create(xhci_bus_t *bus, hashed_device_t **hashed_dev) 113 { 114 int res; 115 xhci_device_t *dev = (xhci_device_t *) malloc(sizeof(xhci_device_t)); 116 if (!dev) { 117 res = ENOMEM; 118 goto err_xhci_dev_alloc; 119 } 120 121 res = xhci_device_init(dev, bus); 122 if (res != EOK) { 123 goto err_xhci_dev_init; 124 } 125 126 // TODO: Set device data. 127 128 hashed_device_t *ret_dev = (hashed_device_t *) malloc(sizeof(hashed_device_t)); 129 if (!ret_dev) { 130 res = ENOMEM; 131 goto err_hashed_dev_alloc; 132 } 133 134 ret_dev->device = dev; 135 136 hash_table_insert(&bus->devices, &ret_dev->link); 137 *hashed_dev = ret_dev; 138 return EOK; 139 140 err_hashed_dev_alloc: 141 err_xhci_dev_init: 142 free(dev); 143 err_xhci_dev_alloc: 144 return res; 145 } 146 147 static int hashed_device_remove(xhci_bus_t *bus, hashed_device_t *hashed_dev) 148 { 149 hash_table_remove(&bus->devices, &hashed_dev->device->address); 150 xhci_device_fini(hashed_dev->device); 151 free(hashed_dev->device); 152 free(hashed_dev); 153 154 return EOK; 155 } 156 157 static int register_endpoint(bus_t *bus_base, endpoint_t *ep) 158 { 159 xhci_bus_t *bus = bus_to_xhci_bus(bus_base); 160 assert(bus); 161 162 hashed_device_t *hashed_dev; 163 int res = hashed_device_find_by_address(bus, ep->target.address, &hashed_dev); 164 if (res != EOK && res != ENOENT) 165 return res; 166 167 if (res == ENOENT) { 168 res = hashed_device_create(bus, &hashed_dev); 169 170 if (res != EOK) 171 return res; 172 } 173 174 return xhci_device_add_endpoint(hashed_dev->device, xhci_endpoint_get(ep)); 175 } 176 177 static int release_endpoint(bus_t *bus_base, endpoint_t *ep) 178 { 179 xhci_bus_t *bus = bus_to_xhci_bus(bus_base); 180 assert(bus); 181 182 hashed_device_t *hashed_dev; 183 int res = hashed_device_find_by_address(bus, ep->target.address, &hashed_dev); 184 if (res != EOK) 185 return res; 186 187 xhci_device_remove_endpoint(hashed_dev->device, xhci_endpoint_get(ep)); 188 189 if (hashed_dev->device->active_endpoint_count == 0) { 190 res = hashed_device_remove(bus, hashed_dev); 191 192 if (res != EOK) 193 return res; 194 } 125 195 126 196 return EOK; … … 132 202 assert(bus); 133 203 134 hashed_endpoint_t *hashed_ep;135 int res = endpoint_find_by_target(bus, target, &hashed_ep);204 xhci_endpoint_t *ep; 205 int res = xhci_endpoint_find_by_target(bus, target, &ep); 136 206 if (res != EOK) 137 207 return NULL; 138 208 139 return & hashed_ep->endpoint->base;209 return &ep->base; 140 210 } 141 211 … … 205 275 }; 206 276 207 static size_t endpoint_ht_hash(const ht_link_t *item)208 { 209 hashed_ endpoint_t *ep = hash_table_get_inst(item, hashed_endpoint_t, link);210 return (size_t) hash_mix 32(ep->endpoint->base.target.packed);211 } 212 213 static size_t endpoint_ht_key_hash(void *key)214 { 215 return (size_t) hash_mix 32(*(uint32_t *)key);216 } 217 218 static bool endpoint_ht_key_equal(void *key, const ht_link_t *item)219 { 220 hashed_ endpoint_t *ep = hash_table_get_inst(item, hashed_endpoint_t, link);221 return ep->endpoint->base.target.packed == *(uint32_t *) key;222 } 223 224 /** Operations for the endpointhash table. */225 static hash_table_ops_t endpoint_ht_ops = {226 .hash = endpoint_ht_hash,227 .key_hash = endpoint_ht_key_hash,228 .key_equal = endpoint_ht_key_equal,277 static size_t device_ht_hash(const ht_link_t *item) 278 { 279 hashed_device_t *dev = hash_table_get_inst(item, hashed_device_t, link); 280 return (size_t) hash_mix(dev->device->address); 281 } 282 283 static size_t device_ht_key_hash(void *key) 284 { 285 return (size_t) hash_mix(*(usb_address_t *)key); 286 } 287 288 static bool device_ht_key_equal(void *key, const ht_link_t *item) 289 { 290 hashed_device_t *dev = hash_table_get_inst(item, hashed_device_t, link); 291 return dev->device->address == *(usb_address_t *) key; 292 } 293 294 /** Operations for the device hash table. */ 295 static hash_table_ops_t device_ht_ops = { 296 .hash = device_ht_hash, 297 .key_hash = device_ht_key_hash, 298 .key_equal = device_ht_key_equal, 229 299 .equal = NULL, 230 300 .remove_callback = NULL … … 237 307 bus_init(&bus->base); 238 308 239 if (!hash_table_create(&bus-> endpoints, 0, 0, &endpoint_ht_ops)) {309 if (!hash_table_create(&bus->devices, 0, 0, &device_ht_ops)) { 240 310 // FIXME: Dealloc base! 241 311 return ENOMEM; … … 248 318 void xhci_bus_fini(xhci_bus_t *bus) 249 319 { 250 hash_table_destroy(&bus->endpoints); 320 // FIXME: Make sure no devices are in the hash table. 321 322 hash_table_destroy(&bus->devices); 251 323 } 252 324 /**
Note:
See TracChangeset
for help on using the changeset viewer.