Changeset 6832245 in mainline
- Timestamp:
- 2017-12-14T23:01:57Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 837d53d
- Parents:
- bd05140
- git-author:
- Ondřej Hlavatý <aearsis@…> (2017-12-14 23:01:54)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2017-12-14 23:01:57)
- Location:
- uspace
- Files:
-
- 33 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/ehci_bus.c
rbd05140 r6832245 79 79 /** Creates new hcd endpoint representation. 80 80 */ 81 static endpoint_t *ehci_endpoint_create( bus_t *bus)81 static endpoint_t *ehci_endpoint_create(device_t *dev, const usb_endpoint_desc_t *desc) 82 82 { 83 assert( bus);83 assert(dev); 84 84 85 85 ehci_endpoint_t *ehci_ep = malloc(sizeof(ehci_endpoint_t)); … … 87 87 return NULL; 88 88 89 endpoint_init(&ehci_ep->base, bus); 89 endpoint_init(&ehci_ep->base, dev, desc); 90 91 // TODO: extract USB2 information from desc 90 92 91 93 ehci_ep->qh = malloc32(sizeof(qh_t)); … … 114 116 115 117 116 static int ehci_register_ep( bus_t *bus_base, device_t *dev, endpoint_t *ep, const usb_endpoint_desc_t *desc)118 static int ehci_register_ep(endpoint_t *ep) 117 119 { 120 bus_t *bus_base = endpoint_get_bus(ep); 118 121 ehci_bus_t *bus = (ehci_bus_t *) bus_base; 119 122 ehci_endpoint_t *ehci_ep = ehci_endpoint_get(ep); 123 assert(fibril_mutex_is_locked(&bus_base->guard)); 120 124 121 // TODO utilize desc->usb2 122 123 const int err = bus->parent_ops.register_endpoint(bus_base, dev, ep, desc); 125 const int err = usb2_bus_ops.endpoint_register(ep); 124 126 if (err) 125 127 return err; … … 131 133 } 132 134 133 static int ehci_unregister_ep( bus_t *bus_base,endpoint_t *ep)135 static int ehci_unregister_ep(endpoint_t *ep) 134 136 { 137 bus_t *bus_base = endpoint_get_bus(ep); 135 138 ehci_bus_t *bus = (ehci_bus_t *) bus_base; 136 139 assert(bus); 137 140 assert(ep); 138 141 139 const int err = bus->parent_ops.unregister_endpoint(bus_base,ep);142 const int err = usb2_bus_ops.endpoint_unregister(ep); 140 143 if (err) 141 144 return err; … … 145 148 } 146 149 147 static usb_transfer_batch_t *ehci_ bus_create_batch(bus_t *bus,endpoint_t *ep)150 static usb_transfer_batch_t *ehci_create_batch(endpoint_t *ep) 148 151 { 149 152 ehci_transfer_batch_t *batch = ehci_transfer_batch_create(ep); … … 151 154 } 152 155 153 static void ehci_ bus_destroy_batch(usb_transfer_batch_t *batch)156 static void ehci_destroy_batch(usb_transfer_batch_t *batch) 154 157 { 155 158 ehci_transfer_batch_destroy(ehci_transfer_batch_get(batch)); 156 159 } 157 160 158 int ehci_bus_init(ehci_bus_t *bus, hc_t *hc) 161 static const bus_ops_t ehci_bus_ops = { 162 .parent = &usb2_bus_ops, 163 164 .endpoint_destroy = ehci_endpoint_destroy, 165 .endpoint_create = ehci_endpoint_create, 166 .endpoint_register = ehci_register_ep, 167 .endpoint_unregister = ehci_unregister_ep, 168 .endpoint_set_toggle = ehci_ep_toggle_set, 169 .endpoint_get_toggle = ehci_ep_toggle_get, 170 .endpoint_count_bw = bandwidth_count_usb11, 171 .batch_create = ehci_create_batch, 172 .batch_destroy = ehci_destroy_batch, 173 }; 174 175 int ehci_bus_init(ehci_bus_t *bus, hcd_t *hcd, hc_t *hc) 159 176 { 160 177 assert(hc); 161 178 assert(bus); 162 179 163 // FIXME: Implement the USB2 bw counting.164 usb2_bus_init(&bus->base, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);180 usb2_bus_t *usb2_bus = (usb2_bus_t *) bus; 181 bus_t *bus_base = (bus_t *) bus; 165 182 166 bus_ops_t *ops = &bus->base.base.ops; 167 bus->parent_ops = *ops; 168 ops->create_endpoint = ehci_endpoint_create; 169 ops->destroy_endpoint = ehci_endpoint_destroy; 170 ops->endpoint_set_toggle = ehci_ep_toggle_set; 171 ops->endpoint_get_toggle = ehci_ep_toggle_get; 172 173 ops->register_endpoint = ehci_register_ep; 174 ops->unregister_endpoint = ehci_unregister_ep; 175 176 ops->create_batch = ehci_bus_create_batch; 177 ops->destroy_batch = ehci_bus_destroy_batch; 183 usb2_bus_init(usb2_bus, hcd, BANDWIDTH_AVAILABLE_USB11); 184 bus_base->ops = &ehci_bus_ops; 178 185 179 186 bus->hc = hc; -
uspace/drv/bus/usb/ehci/ehci_bus.h
rbd05140 r6832245 59 59 usb2_bus_t base; 60 60 hc_t *hc; 61 62 /* Stored original ops from base, they are called in our handlers */63 bus_ops_t parent_ops;64 61 } ehci_bus_t; 65 62 66 int ehci_bus_init(ehci_bus_t *, hc_t *); 63 void ehci_bus_prepare_ops(void); 64 65 int ehci_bus_init(ehci_bus_t *, hcd_t *, hc_t *); 67 66 68 67 /** Get and convert assigned ehci_endpoint_t structure -
uspace/drv/bus/usb/ehci/hc.c
rbd05140 r6832245 149 149 * @return Error code 150 150 */ 151 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res)151 int hc_init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res) 152 152 { 153 153 assert(instance); … … 190 190 &instance->rh, instance->caps, instance->registers, "ehci rh"); 191 191 192 ehci_bus_init(&instance->bus, instance);192 ehci_bus_init(&instance->bus, hcd, instance); 193 193 return EOK; 194 194 } -
uspace/drv/bus/usb/ehci/hc.h
rbd05140 r6832245 85 85 } hc_t; 86 86 87 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res);87 int hc_init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res); 88 88 int hc_start(hc_t *instance, bool interrupts); 89 89 void hc_fini(hc_t *instance); -
uspace/drv/bus/usb/ehci/main.c
rbd05140 r6832245 81 81 return ENOMEM; 82 82 83 const int ret = hc_init(instance, res);83 const int ret = hc_init(instance, hcd, res); 84 84 if (ret == EOK) { 85 85 hcd_set_implementation(hcd, instance, &ehci_hc_driver.ops, &instance->bus.base.base); -
uspace/drv/bus/usb/ohci/main.c
rbd05140 r6832245 83 83 goto err; 84 84 85 if ((err = ohci_bus_init(&instance->bus, instance)))85 if ((err = ohci_bus_init(&instance->bus, hcd, instance))) 86 86 goto err; 87 87 -
uspace/drv/bus/usb/ohci/ohci_bus.c
rbd05140 r6832245 72 72 /** Creates new hcd endpoint representation. 73 73 */ 74 static endpoint_t *ohci_endpoint_create( bus_t *bus)74 static endpoint_t *ohci_endpoint_create(device_t *dev, const usb_endpoint_desc_t *desc) 75 75 { 76 assert( bus);76 assert(dev); 77 77 78 78 ohci_endpoint_t *ohci_ep = malloc(sizeof(ohci_endpoint_t)); … … 80 80 return NULL; 81 81 82 endpoint_init(&ohci_ep->base, bus);82 endpoint_init(&ohci_ep->base, dev, desc); 83 83 84 84 ohci_ep->ed = malloc32(sizeof(ed_t)); … … 115 115 116 116 117 static int ohci_register_ep( bus_t *bus_base, device_t *dev, endpoint_t *ep, const usb_endpoint_desc_t *desc)117 static int ohci_register_ep(endpoint_t *ep) 118 118 { 119 bus_t *bus_base = endpoint_get_bus(ep); 119 120 ohci_bus_t *bus = (ohci_bus_t *) bus_base; 120 121 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep); 121 122 122 const int err = bus->parent_ops.register_endpoint(bus_base, dev, ep, desc);123 const int err = usb2_bus_ops.endpoint_register(ep); 123 124 if (err) 124 125 return err; … … 130 131 } 131 132 132 static int ohci_unregister_ep( bus_t *bus_base,endpoint_t *ep)133 static int ohci_unregister_ep(endpoint_t *ep) 133 134 { 134 ohci_bus_t *bus = (ohci_bus_t *) bus_base; 135 assert(bus); 135 ohci_bus_t *bus = (ohci_bus_t *) endpoint_get_bus(ep); 136 136 assert(ep); 137 137 138 const int err = bus->parent_ops.unregister_endpoint(bus_base,ep);138 const int err = usb2_bus_ops.endpoint_unregister(ep); 139 139 if (err) 140 140 return err; … … 144 144 } 145 145 146 static usb_transfer_batch_t *ohci_ bus_create_batch(bus_t *bus,endpoint_t *ep)146 static usb_transfer_batch_t *ohci_create_batch(endpoint_t *ep) 147 147 { 148 148 ohci_transfer_batch_t *batch = ohci_transfer_batch_create(ep); … … 150 150 } 151 151 152 static void ohci_ bus_destroy_batch(usb_transfer_batch_t *batch)152 static void ohci_destroy_batch(usb_transfer_batch_t *batch) 153 153 { 154 154 ohci_transfer_batch_destroy(ohci_transfer_batch_get(batch)); 155 155 } 156 156 157 int ohci_bus_init(ohci_bus_t *bus, hc_t *hc) 157 static const bus_ops_t ohci_bus_ops = { 158 .parent = &usb2_bus_ops, 159 160 .endpoint_destroy = ohci_endpoint_destroy, 161 .endpoint_create = ohci_endpoint_create, 162 .endpoint_register = ohci_register_ep, 163 .endpoint_unregister = ohci_unregister_ep, 164 .endpoint_count_bw = bandwidth_count_usb11, 165 .endpoint_set_toggle = ohci_ep_toggle_set, 166 .endpoint_get_toggle = ohci_ep_toggle_get, 167 .batch_create = ohci_create_batch, 168 .batch_destroy = ohci_destroy_batch, 169 }; 170 171 172 int ohci_bus_init(ohci_bus_t *bus, hcd_t *hcd, hc_t *hc) 158 173 { 159 174 assert(hc); 160 175 assert(bus); 161 176 162 usb2_bus_init(&bus->base, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);163 177 164 bus_ops_t *ops = &bus->base.base.ops; 165 bus->parent_ops = *ops; 166 ops->create_endpoint = ohci_endpoint_create; 167 ops->destroy_endpoint = ohci_endpoint_destroy; 168 ops->endpoint_set_toggle = ohci_ep_toggle_set; 169 ops->endpoint_get_toggle = ohci_ep_toggle_get; 178 usb2_bus_t *usb2_bus = (usb2_bus_t *) bus; 179 bus_t *bus_base = (bus_t *) bus; 170 180 171 ops->register_endpoint = ohci_register_ep; 172 ops->unregister_endpoint = ohci_unregister_ep; 173 174 ops->create_batch = ohci_bus_create_batch; 175 ops->destroy_batch = ohci_bus_destroy_batch; 181 usb2_bus_init(usb2_bus, hcd, BANDWIDTH_AVAILABLE_USB11); 182 bus_base->ops = &ohci_bus_ops; 176 183 177 184 bus->hc = hc; -
uspace/drv/bus/usb/ohci/ohci_bus.h
rbd05140 r6832245 60 60 usb2_bus_t base; 61 61 hc_t *hc; 62 63 /* Stored original ops from base, they are called in our handlers */64 bus_ops_t parent_ops;65 62 } ohci_bus_t; 66 63 67 int ohci_bus_init(ohci_bus_t *, hc _t *);64 int ohci_bus_init(ohci_bus_t *, hcd_t *, hc_t *); 68 65 69 66 /** Get and convert assigned ohci_endpoint_t structure -
uspace/drv/bus/usb/uhci/hc.c
rbd05140 r6832245 95 95 96 96 static void hc_init_hw(const hc_t *instance); 97 static int hc_init_mem_structures(hc_t *instance );97 static int hc_init_mem_structures(hc_t *instance, hcd_t *); 98 98 static int hc_init_transfer_lists(hc_t *instance); 99 99 … … 215 215 * interrupt fibrils. 216 216 */ 217 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res)217 int hc_init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res) 218 218 { 219 219 assert(instance); … … 238 238 hw_res->io_ranges.ranges[0].size); 239 239 240 ret = hc_init_mem_structures(instance );240 ret = hc_init_mem_structures(instance, hcd); 241 241 if (ret != EOK) { 242 242 usb_log_error("Failed to init UHCI memory structures: %s.\n", … … 309 309 } 310 310 311 static usb_transfer_batch_t *create_transfer_batch( bus_t *bus,endpoint_t *ep)311 static usb_transfer_batch_t *create_transfer_batch(endpoint_t *ep) 312 312 { 313 313 uhci_transfer_batch_t *batch = uhci_transfer_batch_create(ep); … … 319 319 uhci_transfer_batch_destroy(uhci_transfer_batch_get(batch)); 320 320 } 321 322 static const bus_ops_t uhci_bus_ops = { 323 .parent = &usb2_bus_ops, 324 325 .endpoint_count_bw = bandwidth_count_usb11, 326 .batch_create = create_transfer_batch, 327 .batch_destroy = destroy_transfer_batch, 328 }; 321 329 322 330 /** Initialize UHCI hc memory structures. … … 330 338 * - frame list page (needs to be one UHCI hw accessible 4K page) 331 339 */ 332 int hc_init_mem_structures(hc_t *instance )340 int hc_init_mem_structures(hc_t *instance, hcd_t *hcd) 333 341 { 334 342 int err; 335 343 assert(instance); 336 344 337 if ((err = usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11)))345 if ((err = usb2_bus_init(&instance->bus, hcd, BANDWIDTH_AVAILABLE_USB11))) 338 346 return err; 339 347 340 instance->bus.base.ops.create_batch = create_transfer_batch;341 instance->bus.base.ops.destroy_batch = destroy_transfer_batch;348 bus_t *bus = (bus_t *) &instance->bus; 349 bus->ops = &uhci_bus_ops; 342 350 343 351 /* Init USB frame list page */ -
uspace/drv/bus/usb/uhci/hc.h
rbd05140 r6832245 126 126 } hc_t; 127 127 128 extern int hc_init(hc_t *, const hw_res_list_parsed_t *);128 extern int hc_init(hc_t *, hcd_t *, const hw_res_list_parsed_t *); 129 129 extern void hc_start(hc_t *); 130 130 extern void hc_fini(hc_t *); -
uspace/drv/bus/usb/uhci/main.c
rbd05140 r6832245 80 80 return ENOMEM; 81 81 82 if ((err = hc_init(instance, res)) != EOK)82 if ((err = hc_init(instance, hcd, res)) != EOK) 83 83 goto err; 84 84 -
uspace/drv/bus/usb/vhc/main.c
rbd05140 r6832245 69 69 return ret; 70 70 } 71 vhc_init(vhc );71 vhc_init(vhc, dev_to_hcd(dev)); 72 72 return EOK; 73 73 } -
uspace/drv/bus/usb/vhc/transfer.c
rbd05140 r6832245 157 157 } 158 158 159 int vhc_init(vhc_data_t *instance) 159 static const bus_ops_t vhc_bus_ops = { 160 .parent = &usb2_bus_ops, 161 .endpoint_count_bw = bandwidth_count_usb11, 162 }; 163 164 int vhc_init(vhc_data_t *instance, hcd_t *hcd) 160 165 { 161 166 assert(instance); 162 167 list_initialize(&instance->devices); 163 168 fibril_mutex_initialize(&instance->guard); 164 usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11); 169 usb2_bus_init(&instance->bus, hcd, BANDWIDTH_AVAILABLE_USB11); 170 instance->bus.base.ops = &vhc_bus_ops; 165 171 instance->magic = 0xDEADBEEF; 166 172 return virthub_init(&instance->hub, "root hub"); -
uspace/drv/bus/usb/vhc/vhcd.h
rbd05140 r6832245 77 77 void vhc_virtdev_unplug(vhc_data_t *, uintptr_t); 78 78 79 int vhc_init(vhc_data_t *instance );79 int vhc_init(vhc_data_t *instance, hcd_t *); 80 80 int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 81 81 int vhc_transfer_queue_processor(void *arg); -
uspace/drv/bus/usb/xhci/bus.c
rbd05140 r6832245 58 58 }; 59 59 60 static int prepare_endpoint(xhci_endpoint_t *ep, const usb_endpoint_desc_t *desc) 61 { 62 /* Extract information from endpoint_desc */ 63 ep->base.endpoint = desc->endpoint_no; 64 ep->base.direction = desc->direction; 65 ep->base.transfer_type = desc->transfer_type; 66 ep->base.max_packet_size = desc->max_packet_size; 67 ep->base.packets = desc->packets; 68 ep->max_streams = desc->usb3.max_streams; 69 ep->max_burst = desc->usb3.max_burst; 70 ep->mult = desc->usb3.mult; 71 72 if (ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) { 73 if (ep->base.device->speed <= USB_SPEED_HIGH) { 74 ep->isoch_max_size = desc->max_packet_size * (desc->packets + 1); 75 } 76 else if (ep->base.device->speed == USB_SPEED_SUPER) { 77 ep->isoch_max_size = desc->usb3.bytes_per_interval; 78 } 79 /* Technically there could be superspeed plus too. */ 80 81 /* Allocate and setup isochronous-specific structures. */ 82 ep->isoch_enqueue = 0; 83 ep->isoch_dequeue = XHCI_ISOCH_BUFFER_COUNT - 1; 84 ep->isoch_started = false; 85 86 fibril_mutex_initialize(&ep->isoch_guard); 87 fibril_condvar_initialize(&ep->isoch_avail); 88 } 89 90 return xhci_endpoint_alloc_transfer_ds(ep); 91 } 92 93 static endpoint_t *create_endpoint(bus_t *base); 94 95 static int address_device(xhci_hc_t *hc, xhci_device_t *dev) 60 static endpoint_t *endpoint_create(device_t *, const usb_endpoint_desc_t *); 61 62 static int address_device(xhci_bus_t *bus, xhci_device_t *dev) 96 63 { 97 64 int err; 98 65 99 66 /* Enable new slot. */ 100 if ((err = hc_enable_slot( hc, &dev->slot_id)) != EOK)67 if ((err = hc_enable_slot(bus->hc, &dev->slot_id)) != EOK) 101 68 return err; 102 69 usb_log_debug2("Obtained slot ID: %u.\n", dev->slot_id); 103 70 104 71 /* Create and configure control endpoint. */ 105 endpoint_t *ep0_base = create_endpoint(&hc->bus.base);72 endpoint_t *ep0_base = endpoint_create(&dev->base, &ep0_initial_desc); 106 73 if (!ep0_base) 107 74 goto err_slot; … … 112 79 xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base); 113 80 114 if ((err = prepare_endpoint(ep0, &ep0_initial_desc)))81 if ((err = xhci_endpoint_alloc_transfer_ds(ep0))) 115 82 goto err_ep; 116 83 … … 120 87 121 88 /* Address device */ 122 if ((err = hc_address_device( hc, dev, ep0)))89 if ((err = hc_address_device(bus->hc, dev, ep0))) 123 90 goto err_added; 124 91 … … 135 102 endpoint_del_ref(ep0_base); 136 103 err_slot: 137 hc_disable_slot( hc, dev);104 hc_disable_slot(bus->hc, dev); 138 105 return err; 139 106 } … … 164 131 } 165 132 166 int xhci_bus_enumerate_device(xhci_bus_t *bus, xhci_hc_t *hc,device_t *dev)133 int xhci_bus_enumerate_device(xhci_bus_t *bus, device_t *dev) 167 134 { 168 135 int err; … … 184 151 185 152 /* Assign an address to the device */ 186 if ((err = address_device( hc, xhci_dev))) {153 if ((err = address_device(bus, xhci_dev))) { 187 154 usb_log_error("Failed to setup address of the new device: %s", str_error(err)); 188 155 return err; … … 195 162 fibril_mutex_unlock(&bus->base.guard); 196 163 197 if ((err = setup_ep0_packet_size( hc, xhci_dev))) {164 if ((err = setup_ep0_packet_size(bus->hc, xhci_dev))) { 198 165 usb_log_error("Failed to setup control endpoint of the new device: %s", str_error(err)); 199 166 goto err_address; … … 201 168 202 169 /* Read the device descriptor, derive the match ids */ 203 if ((err = hcd_ddf_device_explore( hc->hcd,dev))) {170 if ((err = hcd_ddf_device_explore(dev))) { 204 171 usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err)); 205 172 goto err_address; … … 213 180 } 214 181 215 static int unregister_endpoint(bus_t *,endpoint_t *);216 217 int xhci_bus_remove_device(xhci_bus_t *bus, xhci_hc_t *hc,device_t *dev)182 static int endpoint_unregister(endpoint_t *); 183 184 int xhci_bus_remove_device(xhci_bus_t *bus, device_t *dev) 218 185 { 219 186 int err; … … 246 213 /* Disable the slot, dropping all endpoints. */ 247 214 const uint32_t slot_id = xhci_dev->slot_id; 248 if ((err = hc_disable_slot( hc, xhci_dev))) {215 if ((err = hc_disable_slot(bus->hc, xhci_dev))) { 249 216 usb_log_warning("Failed to disable slot of device " XHCI_DEV_FMT ": %s", 250 217 XHCI_DEV_ARGS(*xhci_dev), str_error(err)); … … 258 225 continue; 259 226 260 if ((err = unregister_endpoint(&bus->base,&xhci_dev->endpoints[i]->base))) {227 if ((err = endpoint_unregister(&xhci_dev->endpoints[i]->base))) { 261 228 usb_log_warning("Failed to unregister endpoint " XHCI_EP_FMT ": %s", 262 229 XHCI_EP_ARGS(*xhci_dev->endpoints[i]), str_error(err)); … … 278 245 } 279 246 280 static int enumerate_device(bus_t *bus_base, hcd_t *hcd, device_t *dev) 281 { 282 xhci_hc_t *hc = hcd_get_driver_data(hcd); 283 assert(hc); 284 285 xhci_bus_t *bus = bus_to_xhci_bus(bus_base); 286 assert(bus); 287 288 return xhci_bus_enumerate_device(bus, hc, dev); 289 } 290 291 static int remove_device(bus_t *bus_base, hcd_t *hcd, device_t *dev) 292 { 293 xhci_hc_t *hc = hcd_get_driver_data(hcd); 294 assert(hc); 295 296 xhci_bus_t *bus = bus_to_xhci_bus(bus_base); 297 assert(bus); 298 299 return xhci_bus_remove_device(bus, hc, dev); 300 } 301 302 static int online_device(bus_t *bus_base, hcd_t *hcd, device_t *dev_base) 303 { 304 int err; 305 306 xhci_hc_t *hc = hcd_get_driver_data(hcd); 307 assert(hc); 308 309 xhci_bus_t *bus = bus_to_xhci_bus(bus_base); 247 static int device_enumerate(device_t *dev) 248 { 249 xhci_bus_t *bus = bus_to_xhci_bus(dev->bus); 250 return xhci_bus_enumerate_device(bus, dev); 251 } 252 253 static int device_remove(device_t *dev) 254 { 255 xhci_bus_t *bus = bus_to_xhci_bus(dev->bus); 256 return xhci_bus_remove_device(bus, dev); 257 } 258 259 static int device_online(device_t *dev_base) 260 { 261 int err; 262 263 xhci_bus_t *bus = bus_to_xhci_bus(dev_base->bus); 310 264 assert(bus); 311 265 … … 314 268 315 269 /* Transition the device from the Addressed to the Configured state. */ 316 if ((err = hc_configure_device( hc, dev->slot_id))) {270 if ((err = hc_configure_device(bus->hc, dev->slot_id))) { 317 271 usb_log_warning("Failed to configure device " XHCI_DEV_FMT ".", XHCI_DEV_ARGS(*dev)); 318 272 } … … 331 285 } 332 286 333 static int offline_device(bus_t *bus_base, hcd_t *hcd, device_t *dev_base) 334 { 335 int err; 336 337 xhci_hc_t *hc = hcd_get_driver_data(hcd); 338 assert(hc); 339 340 xhci_bus_t *bus = bus_to_xhci_bus(bus_base); 287 static int device_offline(device_t *dev_base) 288 { 289 int err; 290 291 xhci_bus_t *bus = bus_to_xhci_bus(dev_base->bus); 341 292 assert(bus); 342 293 … … 370 321 371 322 /* Issue one HC command to simultaneously drop all endpoints except zero. */ 372 if ((err = hc_deconfigure_device( hc, dev->slot_id))) {323 if ((err = hc_deconfigure_device(bus->hc, dev->slot_id))) { 373 324 usb_log_warning("Failed to deconfigure device " XHCI_DEV_FMT ".", 374 325 XHCI_DEV_ARGS(*dev)); … … 388 339 } 389 340 390 static endpoint_t *create_endpoint(bus_t *base) 391 { 392 xhci_bus_t *bus = bus_to_xhci_bus(base); 393 341 static endpoint_t *endpoint_create(device_t *dev, const usb_endpoint_desc_t *desc) 342 { 394 343 xhci_endpoint_t *ep = calloc(1, sizeof(xhci_endpoint_t)); 395 344 if (!ep) 396 345 return NULL; 397 346 398 if (xhci_endpoint_init(ep, bus)) {347 if (xhci_endpoint_init(ep, dev, desc)) { 399 348 free(ep); 400 349 return NULL; … … 404 353 } 405 354 406 static void destroy_endpoint(endpoint_t *ep)355 static void endpoint_destroy(endpoint_t *ep) 407 356 { 408 357 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep); … … 412 361 } 413 362 414 static int register_endpoint(bus_t *bus_base, device_t *device, endpoint_t *ep_base, const usb_endpoint_desc_t *desc)415 { 416 int err; 417 xhci_bus_t *bus = bus_to_xhci_bus( bus_base);363 static int endpoint_register(endpoint_t *ep_base) 364 { 365 int err; 366 xhci_bus_t *bus = bus_to_xhci_bus(endpoint_get_bus(ep_base)); 418 367 xhci_endpoint_t *ep = xhci_endpoint_get(ep_base); 419 368 420 xhci_device_t *dev = xhci_device_get( device);421 422 if ((err = prepare_endpoint(ep, desc)))369 xhci_device_t *dev = xhci_device_get(ep_base->device); 370 371 if ((err = xhci_endpoint_alloc_transfer_ds(ep))) 423 372 return err; 424 373 … … 443 392 } 444 393 445 static int unregister_endpoint(bus_t *bus_base,endpoint_t *ep_base)446 { 447 int err; 448 xhci_bus_t *bus = bus_to_xhci_bus( bus_base);394 static int endpoint_unregister(endpoint_t *ep_base) 395 { 396 int err; 397 xhci_bus_t *bus = bus_to_xhci_bus(endpoint_get_bus(ep_base)); 449 398 xhci_endpoint_t *ep = xhci_endpoint_get(ep_base); 450 399 xhci_device_t *dev = xhci_device_get(ep_base->device); … … 470 419 } 471 420 472 static endpoint_t* find_endpoint(bus_t *bus_base,device_t *dev_base, usb_target_t target, usb_direction_t direction)421 static endpoint_t* device_find_endpoint(device_t *dev_base, usb_target_t target, usb_direction_t direction) 473 422 { 474 423 xhci_device_t *dev = xhci_device_get(dev_base); … … 487 436 } 488 437 489 static size_t count_bw(endpoint_t *ep, size_t size)490 {491 // TODO: Implement me!492 return 0;493 }494 495 438 /* Endpoint ops, optional (have generic fallback) */ 496 439 static bool endpoint_get_toggle(endpoint_t *ep) … … 525 468 } 526 469 527 static usb_transfer_batch_t * create_batch(bus_t *bus,endpoint_t *ep)470 static usb_transfer_batch_t *batch_create(endpoint_t *ep) 528 471 { 529 472 xhci_transfer_t *transfer = xhci_transfer_create(ep); … … 531 474 } 532 475 533 static void destroy_batch(usb_transfer_batch_t *batch)476 static void batch_destroy(usb_transfer_batch_t *batch) 534 477 { 535 478 xhci_transfer_destroy(xhci_transfer_from_batch(batch)); … … 538 481 static const bus_ops_t xhci_bus_ops = { 539 482 #define BIND_OP(op) .op = op, 540 BIND_OP(enumerate_device)541 BIND_OP(remove_device)542 543 BIND_OP(online_device)544 BIND_OP(offline_device)545 546 BIND_OP(create_endpoint)547 BIND_OP(destroy_endpoint)548 549 BIND_OP(register_endpoint)550 BIND_OP(unregister_endpoint)551 BIND_OP(find_endpoint)552 553 483 BIND_OP(reserve_default_address) 554 484 BIND_OP(release_default_address) 555 556 485 BIND_OP(reset_toggle) 557 BIND_OP(count_bw) 558 486 487 BIND_OP(device_enumerate) 488 BIND_OP(device_remove) 489 BIND_OP(device_online) 490 BIND_OP(device_offline) 491 BIND_OP(device_find_endpoint) 492 493 BIND_OP(endpoint_create) 494 BIND_OP(endpoint_destroy) 495 BIND_OP(endpoint_register) 496 BIND_OP(endpoint_unregister) 559 497 BIND_OP(endpoint_get_toggle) 560 498 BIND_OP(endpoint_set_toggle) 561 499 562 BIND_OP( create_batch)563 BIND_OP( destroy_batch)500 BIND_OP(batch_create) 501 BIND_OP(batch_destroy) 564 502 #undef BIND_OP 565 503 }; … … 569 507 assert(bus); 570 508 571 bus_init(&bus->base, sizeof(xhci_device_t));509 bus_init(&bus->base, hc->hcd, sizeof(xhci_device_t)); 572 510 573 511 bus->devices_by_slot = calloc(hc->max_slots, sizeof(xhci_device_t *)); … … 576 514 577 515 bus->hc = hc; 578 bus->base.ops = xhci_bus_ops;516 bus->base.ops = &xhci_bus_ops; 579 517 bus->default_address_speed = USB_SPEED_MAX; 580 518 return EOK; -
uspace/drv/bus/usb/xhci/bus.h
rbd05140 r6832245 58 58 void xhci_bus_fini(xhci_bus_t *); 59 59 60 int xhci_bus_enumerate_device(xhci_bus_t *, xhci_hc_t *,device_t *);61 int xhci_bus_remove_device(xhci_bus_t *, xhci_hc_t *,device_t *);60 int xhci_bus_enumerate_device(xhci_bus_t *, device_t *); 61 int xhci_bus_remove_device(xhci_bus_t *, device_t *); 62 62 63 63 #endif -
uspace/drv/bus/usb/xhci/endpoint.c
rbd05140 r6832245 45 45 #include "endpoint.h" 46 46 47 int xhci_endpoint_init(xhci_endpoint_t *xhci_ep, xhci_bus_t *xhci_bus)47 int xhci_endpoint_init(xhci_endpoint_t *xhci_ep, device_t *dev, const usb_endpoint_desc_t *desc) 48 48 { 49 49 assert(xhci_ep); 50 assert(xhci_bus); 51 52 bus_t *bus = &xhci_bus->base; 50 53 51 endpoint_t *ep = &xhci_ep->base; 54 52 55 endpoint_init(ep, bus); 53 endpoint_init(ep, dev, desc); 54 55 xhci_ep->max_streams = desc->usb3.max_streams; 56 xhci_ep->max_burst = desc->usb3.max_burst; 57 xhci_ep->mult = desc->usb3.mult; 58 59 if (xhci_ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) { 60 xhci_ep->isoch_max_size = desc->usb3.bytes_per_interval 61 ? desc->usb3.bytes_per_interval 62 : desc->max_packet_size * (desc->packets + 1); 63 /* Technically there could be superspeed plus too. */ 64 65 /* Allocate and setup isochronous-specific structures. */ 66 xhci_ep->isoch_enqueue = 0; 67 xhci_ep->isoch_dequeue = XHCI_ISOCH_BUFFER_COUNT - 1; 68 xhci_ep->isoch_started = false; 69 70 fibril_mutex_initialize(&xhci_ep->isoch_guard); 71 fibril_condvar_initialize(&xhci_ep->isoch_avail); 72 } 56 73 57 74 return EOK; -
uspace/drv/bus/usb/xhci/endpoint.h
rbd05140 r6832245 149 149 #define XHCI_DEV_ARGS(dev) ddf_fun_get_name((dev).base.fun), (dev).slot_id 150 150 151 int xhci_endpoint_init(xhci_endpoint_t *, xhci_bus_t *);151 int xhci_endpoint_init(xhci_endpoint_t *, device_t *, const usb_endpoint_desc_t *); 152 152 void xhci_endpoint_fini(xhci_endpoint_t *); 153 153 int xhci_endpoint_alloc_transfer_ds(xhci_endpoint_t *); -
uspace/drv/bus/usb/xhci/hc.c
rbd05140 r6832245 212 212 goto err_scratch; 213 213 214 if ((err = xhci_bus_init(&hc->bus, hc))) 215 goto err_cmd; 216 214 217 if ((err = xhci_rh_init(&hc->rh, hc, device))) 215 goto err_cmd; 216 217 if ((err = xhci_bus_init(&hc->bus, hc))) 218 goto err_rh; 219 220 221 return EOK; 222 223 err_rh: 224 xhci_rh_fini(&hc->rh); 218 goto err_bus; 219 220 return EOK; 221 222 err_bus: 223 xhci_bus_fini(&hc->bus); 225 224 err_cmd: 226 225 xhci_fini_commands(hc); -
uspace/drv/bus/usb/xhci/main.c
rbd05140 r6832245 82 82 goto err; 83 83 84 hc->hcd = hcd; 85 84 86 if ((err = hc_init_memory(hc, device))) 85 87 goto err; 86 88 87 89 hcd_set_implementation(hcd, hc, &xhci_ddf_hc_driver.ops, &hc->bus.base); 88 hc->hcd = hcd;89 90 90 91 return EOK; -
uspace/drv/bus/usb/xhci/rh.c
rbd05140 r6832245 71 71 rh->hc_device = device; 72 72 73 const int err = device_init(&rh->device.base);73 const int err = bus_device_init(&rh->device.base, &rh->hc->bus.base); 74 74 if (err) 75 75 return err; … … 94 94 xhci_bus_t *bus = &rh->hc->bus; 95 95 96 device_t *dev = hcd_ddf_device_create(rh->hc_device, bus->base.device_size);96 device_t *dev = hcd_ddf_device_create(rh->hc_device, &bus->base); 97 97 if (!dev) { 98 98 usb_log_error("Failed to create USB device function."); … … 109 109 dev->speed = port_speed->usb_speed; 110 110 111 if ((err = xhci_bus_enumerate_device(bus, rh->hc,dev))) {111 if ((err = xhci_bus_enumerate_device(bus, dev))) { 112 112 usb_log_error("Failed to enumerate USB device: %s", str_error(err)); 113 113 return err; … … 115 115 116 116 if (!ddf_fun_get_name(dev->fun)) { 117 device_set_default_name(dev);117 bus_device_set_default_name(dev); 118 118 } 119 119 … … 196 196 197 197 /* Remove device from XHCI bus. */ 198 if ((err = xhci_bus_remove_device(&rh->hc->bus, rh->hc,&dev->base))) {198 if ((err = xhci_bus_remove_device(&rh->hc->bus, &dev->base))) { 199 199 usb_log_warning("Failed to remove device " XHCI_DEV_FMT " from XHCI bus: %s", 200 200 XHCI_DEV_ARGS(*dev), str_error(err)); -
uspace/lib/usbhost/include/usb/host/bandwidth.h
rbd05140 r6832245 51 51 typedef struct endpoint endpoint_t; 52 52 53 extern s ize_t bandwidth_count_usb11(endpoint_t *, size_t);53 extern ssize_t bandwidth_count_usb11(endpoint_t *, size_t); 54 54 55 extern s ize_t bandwidth_count_usb20(endpoint_t *, size_t);55 extern ssize_t bandwidth_count_usb20(endpoint_t *, size_t); 56 56 57 57 #endif -
uspace/lib/usbhost/include/usb/host/bus.h
rbd05140 r6832245 77 77 usb_address_t address; 78 78 79 /* Managing bus */ 80 bus_t *bus; 81 79 82 /* This structure is meant to be extended by overriding. */ 80 83 } device_t; 81 84 82 typedef struct { 83 int (*enumerate_device)(bus_t *, hcd_t *, device_t *); 84 int (*remove_device)(bus_t *, hcd_t *, device_t *); 85 typedef struct bus_ops bus_ops_t; 85 86 86 int (*online_device)(bus_t *, hcd_t *, device_t *); /**< Optional */ 87 int (*offline_device)(bus_t *, hcd_t *, device_t *); /**< Optional */ 87 /** 88 * Operations structure serving as an interface of hc driver for the library 89 * (and the rest of the system). 90 */ 91 struct bus_ops { 92 /* Undefined operations will be delegated to parent ops */ 93 const bus_ops_t *parent; 88 94 89 /* The following operations are protected by a bus guard. */ 90 endpoint_t *(*create_endpoint)(bus_t *); 91 int (*register_endpoint)(bus_t *, device_t *, endpoint_t *, const usb_endpoint_desc_t *); 92 int (*unregister_endpoint)(bus_t *, endpoint_t *); 93 endpoint_t *(*find_endpoint)(bus_t *, device_t*, usb_target_t, usb_direction_t); 94 void (*destroy_endpoint)(endpoint_t *); /**< Optional */ 95 /* Global operations on the bus */ 96 int (*reserve_default_address)(bus_t *, usb_speed_t); 97 int (*release_default_address)(bus_t *); 98 int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t); 99 100 /* Operations on device */ 101 int (*device_enumerate)(device_t *); 102 int (*device_remove)(device_t *); 103 int (*device_online)(device_t *); /**< Optional */ 104 int (*device_offline)(device_t *); /**< Optional */ 105 endpoint_t *(*device_find_endpoint)(device_t*, usb_target_t, usb_direction_t); 106 endpoint_t *(*endpoint_create)(device_t *, const usb_endpoint_desc_t *); 107 108 /* Operations on endpoint */ 109 int (*endpoint_register)(endpoint_t *); 110 int (*endpoint_unregister)(endpoint_t *); 111 void (*endpoint_destroy)(endpoint_t *); /**< Optional */ 95 112 bool (*endpoint_get_toggle)(endpoint_t *); /**< Optional */ 96 113 void (*endpoint_set_toggle)(endpoint_t *, bool); /**< Optional */ 114 ssize_t (*endpoint_count_bw) (endpoint_t *, size_t); 115 usb_transfer_batch_t *(*batch_create)(endpoint_t *); /**< Optional */ 97 116 98 int (*reserve_default_address)(bus_t *, usb_speed_t); 99 int (*release_default_address)(bus_t *); 117 /* Operations on batch */ 118 void (*batch_destroy)(usb_transfer_batch_t *); /**< Optional */ 119 }; 100 120 101 int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t); 102 103 size_t (*count_bw) (endpoint_t *, size_t); 104 105 usb_transfer_batch_t *(*create_batch)(bus_t *, endpoint_t *); /**< Optional */ 106 void (*destroy_batch)(usb_transfer_batch_t *); /**< Optional */ 107 } bus_ops_t; 121 /** 122 * Use this macro to lookup virtual function. 123 */ 124 #define BUS_OPS_LOOKUP(start, fn) ({ bus_ops_t const * ops = (start); while (ops && ops->fn == NULL) ops = ops->parent; ops; }) 108 125 109 126 /** Endpoint management structure */ … … 112 129 fibril_mutex_t guard; 113 130 131 /* TODO: get rid of this one. */ 132 hcd_t *hcd; 133 114 134 size_t device_size; 115 135 116 136 /* Do not call directly, ops are synchronized. */ 117 bus_ops_tops;137 const bus_ops_t *ops; 118 138 119 139 /* This structure is meant to be extended by overriding. */ 120 140 } bus_t; 121 141 122 void bus_init(bus_t *, size_t);123 int device_init(device_t *);142 void bus_init(bus_t *, hcd_t *, size_t); 143 int bus_device_init(device_t *, bus_t *); 124 144 125 int device_set_default_name(device_t *);145 int bus_device_set_default_name(device_t *); 126 146 127 int bus_ enumerate_device(bus_t *, hcd_t *,device_t *);128 int bus_ remove_device(bus_t *, hcd_t *,device_t *);147 int bus_device_enumerate(device_t *); 148 int bus_device_remove(device_t *); 129 149 130 int bus_ online_device(bus_t *, hcd_t *,device_t *);131 int bus_ offline_device(bus_t *, hcd_t *,device_t *);150 int bus_device_online(device_t *); 151 int bus_device_offline(device_t *); 132 152 133 int bus_add_endpoint(bus_t *, device_t *, const usb_endpoint_desc_t *, endpoint_t **); 134 endpoint_t *bus_find_endpoint(bus_t *, device_t *, usb_target_t, usb_direction_t); 135 int bus_remove_endpoint(bus_t *, endpoint_t *); 136 137 size_t bus_count_bw(endpoint_t *, size_t); 153 int bus_endpoint_add(device_t *, const usb_endpoint_desc_t *, endpoint_t **); 154 endpoint_t *bus_find_endpoint(device_t *, usb_target_t, usb_direction_t); 155 int bus_endpoint_remove(endpoint_t *); 138 156 139 157 int bus_reserve_default_address(bus_t *, usb_speed_t); -
uspace/lib/usbhost/include/usb/host/ddf_helpers.h
rbd05140 r6832245 81 81 int hcd_setup_virtual_root_hub(hcd_t *, ddf_dev_t *); 82 82 83 device_t *hcd_ddf_device_create(ddf_dev_t *, size_t);83 device_t *hcd_ddf_device_create(ddf_dev_t *, bus_t *); 84 84 void hcd_ddf_device_destroy(device_t *); 85 int hcd_ddf_device_explore( hcd_t *,device_t *);85 int hcd_ddf_device_explore(device_t *); 86 86 int hcd_ddf_device_online(ddf_fun_t *); 87 87 int hcd_ddf_device_offline(ddf_fun_t *); -
uspace/lib/usbhost/include/usb/host/endpoint.h
rbd05140 r6832245 45 45 #include <stdbool.h> 46 46 #include <usb/usb.h> 47 #include <usb/host/bus.h> 47 48 48 49 typedef struct bus bus_t; … … 54 55 /** Part of linked list. */ 55 56 link_t link; 56 /** Managing bus*/57 bus_t *bus;57 /** USB device */ 58 device_t *device; 58 59 /** Reference count. */ 59 60 atomic_t refcnt; 60 /** USB device */61 device_t *device;62 61 /** Enpoint number */ 63 62 usb_endpoint_t endpoint; … … 84 83 } endpoint_t; 85 84 86 extern void endpoint_init(endpoint_t *, bus_t *);85 extern void endpoint_init(endpoint_t *, device_t *, const usb_endpoint_desc_t *); 87 86 88 87 extern void endpoint_add_ref(endpoint_t *); … … 103 102 void endpoint_abort(endpoint_t *); 104 103 104 /* Manage the toggle bit */ 105 105 extern int endpoint_toggle_get(endpoint_t *); 106 106 extern void endpoint_toggle_set(endpoint_t *, bool); 107 108 /* Calculate bandwidth */ 109 ssize_t endpoint_count_bw(endpoint_t *, size_t); 110 111 static inline bus_t *endpoint_get_bus(endpoint_t *ep) 112 { 113 return ep->device->bus; 114 } 107 115 108 116 /** list_get_instance wrapper. -
uspace/lib/usbhost/include/usb/host/usb2_bus.h
rbd05140 r6832245 46 46 typedef struct endpoint endpoint_t; 47 47 48 typedef size_t (*count_bw_func_t)(endpoint_t *, size_t);49 50 48 /** Endpoint management structure */ 51 49 typedef struct usb2_bus { … … 66 64 } usb2_bus_t; 67 65 68 extern int usb2_bus_init(usb2_bus_t *, size_t, count_bw_func_t); 66 extern const bus_ops_t usb2_bus_ops; 67 68 extern int usb2_bus_init(usb2_bus_t *, hcd_t *, size_t); 69 69 70 70 #endif -
uspace/lib/usbhost/src/bandwidth.c
rbd05140 r6832245 48 48 * @param max_packet_size Maximum bytes in one packet. 49 49 */ 50 s ize_t bandwidth_count_usb11(endpoint_t *ep, size_t size)50 ssize_t bandwidth_count_usb11(endpoint_t *ep, size_t size) 51 51 { 52 52 assert(ep); … … 102 102 * @param max_packet_size Maximum bytes in one packet. 103 103 */ 104 s ize_t bandwidth_count_usb20(endpoint_t *ep, size_t size)104 ssize_t bandwidth_count_usb20(endpoint_t *ep, size_t size) 105 105 { 106 106 assert(ep); -
uspace/lib/usbhost/src/bus.c
rbd05140 r6832245 46 46 * Initializes the bus structure. 47 47 */ 48 void bus_init(bus_t *bus, size_t device_size) 49 { 50 assert(bus); 48 void bus_init(bus_t *bus, hcd_t *hcd, size_t device_size) 49 { 50 assert(bus); 51 assert(hcd); 51 52 assert(device_size >= sizeof(device_t)); 52 53 memset(bus, 0, sizeof(bus_t)); 53 54 54 55 fibril_mutex_initialize(&bus->guard); 56 bus->hcd = hcd; 55 57 bus->device_size = device_size; 56 58 } 57 59 58 int device_init(device_t *dev) 59 { 60 int bus_device_init(device_t *dev, bus_t *bus) 61 { 62 assert(bus); 63 assert(bus->hcd); 64 60 65 memset(dev, 0, sizeof(*dev)); 66 67 dev->bus = bus; 61 68 62 69 link_initialize(&dev->link); … … 67 74 } 68 75 69 int device_set_default_name(device_t *dev)76 int bus_device_set_default_name(device_t *dev) 70 77 { 71 78 assert(dev); … … 79 86 } 80 87 81 int bus_enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev) 82 { 83 assert(bus); 84 assert(hcd); 85 assert(dev); 86 87 if (!bus->ops.enumerate_device) 88 return ENOTSUP; 89 90 return bus->ops.enumerate_device(bus, hcd, dev); 91 } 92 93 int bus_remove_device(bus_t *bus, hcd_t *hcd, device_t *dev) 94 { 95 assert(bus); 96 assert(dev); 97 98 if (!bus->ops.remove_device) 99 return ENOTSUP; 100 101 return bus->ops.remove_device(bus, hcd, dev); 102 } 103 104 int bus_online_device(bus_t *bus, hcd_t *hcd, device_t *dev) 105 { 106 assert(bus); 107 assert(hcd); 108 assert(dev); 109 110 if (!bus->ops.online_device) 111 return ENOTSUP; 112 113 return bus->ops.online_device(bus, hcd, dev); 114 } 115 116 int bus_offline_device(bus_t *bus, hcd_t *hcd, device_t *dev) 117 { 118 assert(bus); 119 assert(hcd); 120 assert(dev); 121 122 if (!bus->ops.offline_device) 123 return ENOTSUP; 124 125 return bus->ops.offline_device(bus, hcd, dev); 126 } 127 128 int bus_add_endpoint(bus_t *bus, device_t *device, const usb_endpoint_desc_t *desc, endpoint_t **out_ep) 129 { 130 assert(bus); 88 int bus_device_enumerate(device_t *dev) 89 { 90 assert(dev); 91 92 const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_enumerate); 93 if (!ops) 94 return ENOTSUP; 95 96 return ops->device_enumerate(dev); 97 } 98 99 int bus_device_remove(device_t *dev) 100 { 101 assert(dev); 102 103 const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_remove); 104 105 if (!ops) 106 return ENOTSUP; 107 108 return ops->device_remove(dev); 109 } 110 111 int bus_device_online(device_t *dev) 112 { 113 assert(dev); 114 115 const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_online); 116 if (!ops) 117 return ENOTSUP; 118 119 return ops->device_online(dev); 120 } 121 122 int bus_device_offline(device_t *dev) 123 { 124 assert(dev); 125 126 const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_offline); 127 if (!ops) 128 return ENOTSUP; 129 130 return ops->device_offline(dev); 131 } 132 133 int bus_endpoint_add(device_t *device, const usb_endpoint_desc_t *desc, endpoint_t **out_ep) 134 { 135 int err; 131 136 assert(device); 137 138 bus_t *bus = device->bus; 132 139 133 140 if (desc->max_packet_size == 0 || desc->packets == 0) { … … 136 143 } 137 144 138 fibril_mutex_lock(&bus->guard); 139 140 int err = ENOMEM; 141 endpoint_t *ep = bus->ops.create_endpoint(bus); 145 const bus_ops_t *create_ops = BUS_OPS_LOOKUP(bus->ops, endpoint_create); 146 const bus_ops_t *register_ops = BUS_OPS_LOOKUP(bus->ops, endpoint_register); 147 if (!create_ops || !register_ops) 148 return ENOTSUP; 149 150 endpoint_t *ep = create_ops->endpoint_create(device, desc); 142 151 if (!ep) 143 goto err;144 145 /* Busreference */152 return ENOMEM; 153 154 /* Temporary reference */ 146 155 endpoint_add_ref(ep); 147 156 148 if ((err = bus->ops.register_endpoint(bus, device, ep, desc))) 149 goto err_ep; 157 fibril_mutex_lock(&bus->guard); 158 err = register_ops->endpoint_register(ep); 159 fibril_mutex_unlock(&bus->guard); 150 160 151 161 if (out_ep) { 162 /* Exporting reference */ 152 163 endpoint_add_ref(ep); 153 164 *out_ep = ep; 154 165 } 155 166 156 fibril_mutex_unlock(&bus->guard); 157 return EOK; 158 159 err_ep: 167 /* Temporary reference */ 160 168 endpoint_del_ref(ep); 161 err:162 fibril_mutex_unlock(&bus->guard);163 169 return err; 164 170 } … … 166 172 /** Searches for an endpoint. Returns a reference. 167 173 */ 168 endpoint_t *bus_find_endpoint(bus_t *bus, device_t *device, usb_target_t endpoint, usb_direction_t dir) 169 { 170 assert(bus); 171 172 fibril_mutex_lock(&bus->guard); 173 endpoint_t *ep = bus->ops.find_endpoint(bus, device, endpoint, dir); 174 endpoint_t *bus_find_endpoint(device_t *device, usb_target_t endpoint, usb_direction_t dir) 175 { 176 assert(device); 177 178 bus_t *bus = device->bus; 179 180 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, device_find_endpoint); 181 if (!ops) 182 return NULL; 183 184 fibril_mutex_lock(&bus->guard); 185 endpoint_t *ep = ops->device_find_endpoint(device, endpoint, dir); 174 186 if (ep) { 175 187 /* Exporting reference */ … … 181 193 } 182 194 183 int bus_remove_endpoint(bus_t *bus, endpoint_t *ep) 184 { 185 assert(bus); 195 int bus_endpoint_remove(endpoint_t *ep) 196 { 186 197 assert(ep); 187 198 188 fibril_mutex_lock(&bus->guard); 189 const int r = bus->ops.unregister_endpoint(bus, ep); 199 bus_t *bus = endpoint_get_bus(ep); 200 201 const bus_ops_t *ops = BUS_OPS_LOOKUP(ep->device->bus->ops, endpoint_unregister); 202 if (!ops) 203 return ENOTSUP; 204 205 fibril_mutex_lock(&bus->guard); 206 const int r = ops->endpoint_unregister(ep); 190 207 fibril_mutex_unlock(&bus->guard); 191 208 … … 203 220 assert(bus); 204 221 205 if (!bus->ops.reserve_default_address) 206 return ENOTSUP; 207 208 fibril_mutex_lock(&bus->guard); 209 const int r = bus->ops.reserve_default_address(bus, speed); 222 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, reserve_default_address); 223 if (!ops) 224 return ENOTSUP; 225 226 fibril_mutex_lock(&bus->guard); 227 const int r = ops->reserve_default_address(bus, speed); 210 228 fibril_mutex_unlock(&bus->guard); 211 229 return r; … … 216 234 assert(bus); 217 235 218 /* If this op is not set, allow everything */219 if (! bus->ops.release_default_address)220 return ENOTSUP; 221 222 fibril_mutex_lock(&bus->guard); 223 const int r = bus->ops.release_default_address(bus);236 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, release_default_address); 237 if (!ops) 238 return ENOTSUP; 239 240 fibril_mutex_lock(&bus->guard); 241 const int r = ops->release_default_address(bus); 224 242 fibril_mutex_unlock(&bus->guard); 225 243 return r; … … 230 248 assert(bus); 231 249 232 if (!bus->ops.reset_toggle) 233 return ENOTSUP; 234 235 fibril_mutex_lock(&bus->guard); 236 const int r = bus->ops.reset_toggle(bus, target, all); 250 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, reset_toggle); 251 if (!ops) 252 return ENOTSUP; 253 254 fibril_mutex_lock(&bus->guard); 255 const int r = ops->reset_toggle(bus, target, all); 237 256 fibril_mutex_unlock(&bus->guard); 238 257 return r; 239 }240 241 size_t bus_count_bw(endpoint_t *ep, size_t size)242 {243 assert(ep);244 245 fibril_mutex_lock(&ep->guard);246 const size_t bw = ep->bus->ops.count_bw(ep, size);247 fibril_mutex_unlock(&ep->guard);248 return bw;249 258 } 250 259 -
uspace/lib/usbhost/src/ddf_helpers.c
rbd05140 r6832245 101 101 endpoint_desc->max_packet_size, endpoint_desc->usb2.polling_interval); 102 102 103 return bus_ add_endpoint(hcd->bus,dev, endpoint_desc, NULL);103 return bus_endpoint_add(dev, endpoint_desc, NULL); 104 104 } 105 105 … … 128 128 usb_str_direction(endpoint_desc->direction)); 129 129 130 endpoint_t *ep = bus_find_endpoint( hcd->bus,dev, target, endpoint_desc->direction);130 endpoint_t *ep = bus_find_endpoint(dev, target, endpoint_desc->direction); 131 131 if (!ep) 132 132 return ENOENT; 133 133 134 return bus_ remove_endpoint(hcd->bus,ep);134 return bus_endpoint_remove(ep); 135 135 } 136 136 … … 362 362 const int ret = ddf_fun_unbind(victim->fun); 363 363 if (ret == EOK) { 364 bus_ remove_device(hcd->bus, hcd,victim);364 bus_device_remove(victim); 365 365 ddf_fun_destroy(victim->fun); 366 366 } else { … … 374 374 } 375 375 376 device_t *hcd_ddf_device_create(ddf_dev_t *hc, size_t device_size)376 device_t *hcd_ddf_device_create(ddf_dev_t *hc, bus_t *bus) 377 377 { 378 378 /* Create DDF function for the new device */ … … 384 384 385 385 /* Create USB device node for the new device */ 386 device_t *dev = ddf_fun_data_alloc(fun, device_size);386 device_t *dev = ddf_fun_data_alloc(fun, bus->device_size); 387 387 if (!dev) { 388 388 ddf_fun_destroy(fun); … … 390 390 } 391 391 392 device_init(dev);392 bus_device_init(dev, bus); 393 393 dev->fun = fun; 394 394 return dev; … … 402 402 } 403 403 404 int hcd_ddf_device_explore( hcd_t *hcd,device_t *device)404 int hcd_ddf_device_explore(device_t *device) 405 405 { 406 406 int err; … … 421 421 usb_log_debug("Device(%d): Requesting full device descriptor.", 422 422 device->address); 423 ssize_t got = hcd_send_batch_sync( hcd, device, control_ep, USB_DIRECTION_IN,423 ssize_t got = hcd_send_batch_sync(device->bus->hcd, device, control_ep, USB_DIRECTION_IN, 424 424 (char *) &desc, sizeof(desc), *(uint64_t *)&get_device_desc, 425 425 "read device descriptor"); … … 458 458 usb_log_info("Device(%d): Requested to be brought online.", dev->address); 459 459 460 return bus_ online_device(hcd->bus, hcd,dev);460 return bus_device_online(dev); 461 461 } 462 462 … … 472 472 usb_log_info("Device(%d): Requested to be taken offline.", dev->address); 473 473 474 return bus_ offline_device(hcd->bus, hcd,dev);474 return bus_device_offline(dev); 475 475 } 476 476 … … 483 483 assert(hc); 484 484 485 device_t *dev = hcd_ddf_device_create(hc, hcd->bus ->device_size);485 device_t *dev = hcd_ddf_device_create(hc, hcd->bus); 486 486 if (!dev) { 487 487 usb_log_error("Failed to create USB device function."); … … 492 492 dev->port = port; 493 493 494 if ((err = bus_ enumerate_device(hcd->bus, hcd,dev))) {494 if ((err = bus_device_enumerate(dev))) { 495 495 usb_log_error("Failed to initialize USB dev memory structures."); 496 496 return err; … … 501 501 */ 502 502 if (!ddf_fun_get_name(dev->fun)) { 503 device_set_default_name(dev);503 bus_device_set_default_name(dev); 504 504 } 505 505 … … 538 538 } 539 539 540 device_t *dev = hcd_ddf_device_create(hc, hcd->bus ->device_size);540 device_t *dev = hcd_ddf_device_create(hc, hcd->bus); 541 541 if (!dev) { 542 542 usb_log_error("Failed to create function for the root hub."); … … 547 547 548 548 /* Assign an address to the device */ 549 if ((err = bus_ enumerate_device(hcd->bus, hcd,dev))) {549 if ((err = bus_device_enumerate(dev))) { 550 550 usb_log_error("Failed to enumerate roothub device: %s", str_error(err)); 551 551 goto err_usb_dev; -
uspace/lib/usbhost/src/endpoint.c
rbd05140 r6832245 47 47 /** Initialize provided endpoint structure. 48 48 */ 49 void endpoint_init(endpoint_t *ep, bus_t *bus)49 void endpoint_init(endpoint_t *ep, device_t *dev, const usb_endpoint_desc_t *desc) 50 50 { 51 51 memset(ep, 0, sizeof(endpoint_t)); 52 52 53 ep->bus = bus; 53 assert(dev); 54 ep->device = dev; 55 54 56 atomic_set(&ep->refcnt, 0); 55 57 link_initialize(&ep->link); 56 58 fibril_mutex_initialize(&ep->guard); 57 59 fibril_condvar_initialize(&ep->avail); 60 61 ep->endpoint = desc->endpoint_no; 62 ep->direction = desc->direction; 63 ep->transfer_type = desc->transfer_type; 64 ep->max_packet_size = desc->max_packet_size; 65 ep->packets = desc->packets; 66 67 ep->bandwidth = endpoint_count_bw(ep, desc->max_packet_size); 68 } 69 70 static inline const bus_ops_t *get_bus_ops(endpoint_t *ep) 71 { 72 return ep->device->bus->ops; 58 73 } 59 74 … … 63 78 } 64 79 80 static inline void endpoint_destroy(endpoint_t *ep) 81 { 82 const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_destroy); 83 if (ops) { 84 ops->endpoint_destroy(ep); 85 } else { 86 assert(ep->active_batch == NULL); 87 88 /* Assume mostly the eps will be allocated by malloc. */ 89 free(ep); 90 } 91 } 92 65 93 void endpoint_del_ref(endpoint_t *ep) 66 94 { 67 95 if (atomic_predec(&ep->refcnt) == 0) { 68 if (ep->bus->ops.destroy_endpoint) { 69 ep->bus->ops.destroy_endpoint(ep); 70 } 71 else { 72 assert(ep->active_batch == NULL); 73 74 /* Assume mostly the eps will be allocated by malloc. */ 75 free(ep); 76 } 96 endpoint_destroy(ep); 77 97 } 78 98 } … … 133 153 assert(ep); 134 154 135 return ep->bus->ops.endpoint_get_toggle 136 ? ep->bus->ops.endpoint_get_toggle(ep) 155 const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_get_toggle); 156 return ops 157 ? ops->endpoint_get_toggle(ep) 137 158 : ep->toggle; 138 159 } … … 146 167 assert(ep); 147 168 148 if (ep->bus->ops.endpoint_set_toggle) { 149 ep->bus->ops.endpoint_set_toggle(ep, toggle); 169 const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_set_toggle); 170 if (ops) { 171 ops->endpoint_set_toggle(ep, toggle); 150 172 } 151 173 else { … … 154 176 } 155 177 178 ssize_t endpoint_count_bw(endpoint_t *ep, size_t packet_size) 179 { 180 assert(ep); 181 182 const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_count_bw); 183 if (!ops) 184 return 0; 185 186 return ops->endpoint_count_bw(ep, packet_size); 187 } 188 156 189 /** 157 190 * @} -
uspace/lib/usbhost/src/hcd.c
rbd05140 r6832245 208 208 } 209 209 210 endpoint_t *ep = bus_find_endpoint( hcd->bus,device, target, direction);210 endpoint_t *ep = bus_find_endpoint(device, target, direction); 211 211 if (ep == NULL) { 212 212 usb_log_error("Endpoint(%d:%d) not registered for %s.\n", … … 216 216 217 217 // TODO cut here aka provide helper to call with instance of endpoint_t in hand 218 assert(ep->device == device); 218 219 219 220 usb_log_debug2("%s %d:%d %zu(%zu).\n", 220 221 name, target.address, target.endpoint, size, ep->max_packet_size); 221 222 222 const size_t bw = bus_count_bw(ep, size);223 const size_t bw = endpoint_count_bw(ep, size); 223 224 /* Check if we have enough bandwidth reserved */ 224 225 if (ep->bandwidth < bw) { -
uspace/lib/usbhost/src/usb2_bus.c
rbd05140 r6832245 200 200 }}; 201 201 202 static int address_device( usb2_bus_t *bus, hcd_t *hcd,device_t *dev)202 static int address_device(device_t *dev) 203 203 { 204 204 int err; 205 206 usb2_bus_t *bus = (usb2_bus_t *) dev->bus; 207 hcd_t *hcd = (hcd_t *) bus->base.hcd; 205 208 206 209 /* The default address is currently reserved for this device */ … … 220 223 221 224 endpoint_t *default_ep; 222 err = bus_ add_endpoint(&bus->base,dev, &usb2_default_control_ep, &default_ep);225 err = bus_endpoint_add(dev, &usb2_default_control_ep, &default_ep); 223 226 if (err != EOK) { 224 227 usb_log_error("Device(%d): Failed to add default target: %s.", … … 244 247 245 248 /* We need to remove ep before we change the address */ 246 if ((err = bus_ remove_endpoint(&bus->base,default_ep))) {249 if ((err = bus_endpoint_remove(default_ep))) { 247 250 usb_log_error("Device(%d): Failed to unregister default target: %s", address, str_error(err)); 248 251 goto err_address; … … 262 265 /* Register EP on the new address */ 263 266 usb_log_debug("Device(%d): Registering control EP.", address); 264 err = bus_ add_endpoint(&bus->base,dev, &control_ep, NULL);267 err = bus_endpoint_add(dev, &control_ep, NULL); 265 268 if (err != EOK) { 266 269 usb_log_error("Device(%d): Failed to register EP0: %s", … … 272 275 273 276 err_default_control_ep: 274 bus_ remove_endpoint(&bus->base,default_ep);277 bus_endpoint_remove(default_ep); 275 278 endpoint_del_ref(default_ep); 276 279 err_address: … … 281 284 /** Enumerate a new USB device 282 285 */ 283 static int usb2_bus_ enumerate_device(bus_t *bus_base, hcd_t *hcd,device_t *dev)286 static int usb2_bus_device_enumerate(device_t *dev) 284 287 { 285 288 int err; 286 usb2_bus_t *bus = bus_to_usb2_bus( bus_base);289 usb2_bus_t *bus = bus_to_usb2_bus(dev->bus); 287 290 288 291 /* The speed of the new device was reported by the hub when reserving … … 306 309 307 310 /* Assign an address to the device */ 308 if ((err = address_device( bus, hcd,dev))) {311 if ((err = address_device(dev))) { 309 312 usb_log_error("Failed to setup address of the new device: %s", str_error(err)); 310 313 return err; … … 312 315 313 316 /* Read the device descriptor, derive the match ids */ 314 if ((err = hcd_ddf_device_explore( hcd,dev))) {317 if ((err = hcd_ddf_device_explore(dev))) { 315 318 usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err)); 316 319 release_address(bus, dev->address); … … 329 332 * @note Assumes that the internal mutex is locked. 330 333 */ 331 static endpoint_t *usb2_bus_find_ep( bus_t *bus_base,device_t *device, usb_target_t target, usb_direction_t direction)332 { 333 usb2_bus_t *bus = bus_to_usb2_bus( bus_base);334 static endpoint_t *usb2_bus_find_ep(device_t *device, usb_target_t target, usb_direction_t direction) 335 { 336 usb2_bus_t *bus = bus_to_usb2_bus(device->bus); 334 337 335 338 assert(device->address == target.address); … … 345 348 } 346 349 347 static endpoint_t *usb2_bus_create_ep( bus_t *bus)350 static endpoint_t *usb2_bus_create_ep(device_t *dev, const usb_endpoint_desc_t *desc) 348 351 { 349 352 endpoint_t *ep = malloc(sizeof(endpoint_t)); … … 351 354 return NULL; 352 355 353 endpoint_init(ep, bus);356 endpoint_init(ep, dev, desc); 354 357 return ep; 355 358 } … … 370 373 * @param endpoint USB endpoint number. 371 374 */ 372 static int usb2_bus_register_ep(bus_t *bus_base, device_t *device, endpoint_t *ep, const usb_endpoint_desc_t *desc) 373 { 374 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 375 static int usb2_bus_register_ep(endpoint_t *ep) 376 { 377 usb2_bus_t *bus = bus_to_usb2_bus(ep->device->bus); 378 assert(fibril_mutex_is_locked(&bus->base.guard)); 375 379 assert(ep); 376 380 377 ep->device = device;378 379 /* Extract USB2-related information from endpoint_desc */380 ep->endpoint = desc->endpoint_no;381 ep->direction = desc->direction;382 ep->transfer_type = desc->transfer_type;383 ep->max_packet_size = desc->max_packet_size;384 ep->packets = desc->packets;385 386 ep->bandwidth = bus_base->ops.count_bw(ep, desc->max_packet_size);387 388 381 /* Check for existence */ 389 if (usb2_bus_find_ep( bus_base,ep->device, usb2_ep_to_target(ep), ep->direction))382 if (usb2_bus_find_ep(ep->device, usb2_ep_to_target(ep), ep->direction)) 390 383 return EEXIST; 391 384 … … 394 387 return ENOSPC; 395 388 389 endpoint_add_ref(ep); 396 390 list_append(&ep->link, get_list(bus, ep->device->address)); 397 391 bus->free_bw -= ep->bandwidth; … … 400 394 } 401 395 402 403 396 /** Release bandwidth reserved by the given endpoint. 404 397 */ 405 static int usb2_bus_unregister_ep( bus_t *bus_base,endpoint_t *ep)406 { 407 usb2_bus_t *bus = bus_to_usb2_bus( bus_base);398 static int usb2_bus_unregister_ep(endpoint_t *ep) 399 { 400 usb2_bus_t *bus = bus_to_usb2_bus(ep->device->bus); 408 401 assert(ep); 409 402 410 403 list_remove(&ep->link); 411 ep->device = NULL;412 404 413 405 bus->free_bw += ep->bandwidth; 406 endpoint_del_ref(ep); 414 407 415 408 return EOK; … … 452 445 } 453 446 454 staticconst bus_ops_t usb2_bus_ops = {447 const bus_ops_t usb2_bus_ops = { 455 448 .reserve_default_address = usb2_bus_register_default_address, 456 449 .release_default_address = usb2_bus_release_default_address, 457 .enumerate_device = usb2_bus_enumerate_device,458 .create_endpoint = usb2_bus_create_ep,459 .find_endpoint = usb2_bus_find_ep,460 .unregister_endpoint = usb2_bus_unregister_ep,461 .register_endpoint = usb2_bus_register_ep,462 450 .reset_toggle = usb2_bus_reset_toggle, 451 .device_enumerate = usb2_bus_device_enumerate, 452 .device_find_endpoint = usb2_bus_find_ep, 453 .endpoint_create= usb2_bus_create_ep, 454 .endpoint_register= usb2_bus_register_ep, 455 .endpoint_unregister= usb2_bus_unregister_ep, 463 456 }; 464 457 … … 470 463 * @return Error code. 471 464 */ 472 int usb2_bus_init(usb2_bus_t *bus, size_t available_bandwidth, count_bw_func_t count_bw)465 int usb2_bus_init(usb2_bus_t *bus, hcd_t *hcd, size_t available_bandwidth) 473 466 { 474 467 assert(bus); 475 468 476 bus_init(&bus->base, sizeof(device_t)); 477 478 bus->base.ops = usb2_bus_ops; 479 bus->base.ops.count_bw = count_bw; 469 bus_init(&bus->base, hcd, sizeof(device_t)); 470 bus->base.ops = &usb2_bus_ops; 480 471 481 472 bus->free_bw = available_bandwidth; -
uspace/lib/usbhost/src/usb_transfer_batch.c
rbd05140 r6832245 49 49 { 50 50 assert(ep); 51 assert(ep->bus);52 51 53 usb_transfer_batch_t *batch; 54 if (ep->bus->ops.create_batch) 55 batch = ep->bus->ops.create_batch(ep->bus, ep); 56 else 57 batch = calloc(1, sizeof(usb_transfer_batch_t)); 52 bus_t *bus = endpoint_get_bus(ep); 53 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, batch_create); 58 54 59 return batch; 55 if (!ops) { 56 usb_transfer_batch_t *batch = calloc(1, sizeof(usb_transfer_batch_t)); 57 usb_transfer_batch_init(batch, ep); 58 return batch; 59 } 60 61 return ops->batch_create(ep); 60 62 } 61 63 … … 64 66 void usb_transfer_batch_init(usb_transfer_batch_t *batch, endpoint_t *ep) 65 67 { 68 assert(ep); 69 endpoint_add_ref(ep); 66 70 batch->ep = ep; 67 71 } … … 82 86 batch->toggle_reset_mode == RESET_ALL ? "all EPs toggle" : "EP toggle"); 83 87 84 return bus_reset_toggle( batch->ep->bus, batch->target, batch->toggle_reset_mode);88 return bus_reset_toggle(endpoint_get_bus(batch->ep), batch->target, batch->toggle_reset_mode); 85 89 } 86 90 … … 93 97 assert(batch); 94 98 assert(batch->ep); 95 assert(batch->ep->bus);96 99 97 bus_t *bus = batch->ep->bus; 98 if (bus->ops.destroy_batch) { 100 bus_t *bus = endpoint_get_bus(batch->ep); 101 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, batch_destroy); 102 103 endpoint_del_ref(batch->ep); 104 105 if (ops) { 99 106 usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " destroying.\n", 100 107 batch, USB_TRANSFER_BATCH_ARGS(*batch)); 101 bus->ops.destroy_batch(batch);108 ops->batch_destroy(batch); 102 109 } 103 110 else {
Note:
See TracChangeset
for help on using the changeset viewer.