Changeset c10daa8 in mainline
- Timestamp:
- 2017-10-13T12:32:57Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 063dfe8
- Parents:
- 366e9b6
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 5 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 /** -
uspace/drv/bus/usb/xhci/bus.h
r366e9b6 rc10daa8 52 52 */ 53 53 54 hash_table_t endpoints;54 hash_table_t devices; 55 55 } xhci_bus_t; 56 56 -
uspace/drv/bus/usb/xhci/endpoint.c
r366e9b6 rc10daa8 50 50 51 51 endpoint_init(ep, bus); 52 53 /* FIXME: Set xhci_ep->slot_id */ 52 xhci_ep->device = NULL; 54 53 55 54 usb_log_debug("XHCI Endpoint %d:%d initialized.", ep->target.address, ep->target.endpoint); … … 69 68 } 70 69 70 int xhci_device_init(xhci_device_t *dev, xhci_bus_t *bus) 71 { 72 memset(&dev->endpoints, 0, sizeof(dev->endpoints)); 73 dev->active_endpoint_count = 0; 74 return EOK; 75 } 76 77 void xhci_device_fini(xhci_device_t *dev) 78 { 79 // TODO: Check that all endpoints are dead. 80 } 81 82 int xhci_device_add_endpoint(xhci_device_t *dev, xhci_endpoint_t *ep) 83 { 84 assert(dev->address == ep->base.target.address); 85 assert(!dev->endpoints[ep->base.target.endpoint]); 86 assert(!ep->device); 87 88 ep->device = dev; 89 dev->endpoints[ep->base.target.endpoint] = ep; 90 ++dev->active_endpoint_count; 91 return EOK; 92 } 93 94 int xhci_device_remove_endpoint(xhci_device_t *dev, xhci_endpoint_t *ep) 95 { 96 assert(dev->address == ep->base.target.address); 97 assert(dev->endpoints[ep->base.target.endpoint]); 98 assert(dev == ep->device); 99 100 ep->device = NULL; 101 dev->endpoints[ep->base.target.endpoint] = NULL; 102 --dev->active_endpoint_count; 103 return EOK; 104 } 105 106 xhci_endpoint_t * xhci_device_get_endpoint(xhci_device_t *dev, usb_endpoint_t ep) 107 { 108 return dev->endpoints[ep]; 109 } 110 71 111 /** 72 112 * @} -
uspace/drv/bus/usb/xhci/endpoint.h
r366e9b6 rc10daa8 43 43 #include <usb/host/hcd.h> 44 44 45 typedef struct xhci_device xhci_device_t; 45 46 typedef struct xhci_endpoint xhci_endpoint_t; 46 47 typedef struct xhci_bus xhci_bus_t; 48 49 #define XHCI_DEVICE_MAX_ENDPOINTS 32 47 50 48 51 enum { … … 61 64 endpoint_t base; /**< Inheritance. Keep this first. */ 62 65 66 xhci_device_t *device; 67 } xhci_endpoint_t; 68 69 typedef struct xhci_device { 70 usb_address_t address; 71 63 72 uint32_t slot_id; 64 } xhci_endpoint_t; 73 74 xhci_endpoint_t *endpoints[XHCI_DEVICE_MAX_ENDPOINTS]; 75 uint8_t active_endpoint_count; 76 } xhci_device_t; 65 77 66 78 int xhci_endpoint_init(xhci_endpoint_t *, xhci_bus_t *); 67 79 void xhci_endpoint_fini(xhci_endpoint_t *); 80 81 int xhci_device_init(xhci_device_t *, xhci_bus_t *); 82 void xhci_device_fini(xhci_device_t *); 83 84 int xhci_device_add_endpoint(xhci_device_t *, xhci_endpoint_t *); 85 int xhci_device_remove_endpoint(xhci_device_t *, xhci_endpoint_t *); 86 xhci_endpoint_t * xhci_device_get_endpoint(xhci_device_t *, usb_endpoint_t); 68 87 69 88 static inline xhci_endpoint_t * xhci_endpoint_get(endpoint_t *ep) -
uspace/drv/bus/usb/xhci/transfers.c
r366e9b6 rc10daa8 150 150 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(batch->ep); 151 151 152 uint8_t slot_id = xhci_ep-> slot_id;152 uint8_t slot_id = xhci_ep->device->slot_id; 153 153 xhci_trb_ring_t* ring = hc->dcbaa_virt[slot_id].trs[0]; 154 154 … … 234 234 235 235 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(batch->ep); 236 uint8_t slot_id = xhci_ep-> slot_id;236 uint8_t slot_id = xhci_ep->device->slot_id; 237 237 xhci_trb_ring_t* ring = hc->dcbaa_virt[slot_id].trs[batch->ep->target.endpoint]; 238 238
Note:
See TracChangeset
for help on using the changeset viewer.