Changeset 32fb6bce in mainline for uspace/drv
- Timestamp:
- 2017-12-18T22:50:21Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7f70d1c
- Parents:
- 1ea0bbf
- git-author:
- Ondřej Hlavatý <aearsis@…> (2017-12-18 22:04:50)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2017-12-18 22:50:21)
- Location:
- uspace/drv/bus/usb
- Files:
-
- 23 edited
-
ehci/ehci_bus.c (modified) (3 diffs)
-
ehci/ehci_bus.h (modified) (1 diff)
-
ehci/hc.c (modified) (10 diffs)
-
ehci/hc.h (modified) (2 diffs)
-
ehci/main.c (modified) (3 diffs)
-
ehci/res.c (modified) (2 diffs)
-
ehci/res.h (modified) (1 diff)
-
ohci/hc.c (modified) (19 diffs)
-
ohci/hc.h (modified) (3 diffs)
-
ohci/main.c (modified) (2 diffs)
-
ohci/ohci_bus.c (modified) (2 diffs)
-
ohci/ohci_bus.h (modified) (1 diff)
-
uhci/hc.c (modified) (12 diffs)
-
uhci/hc.h (modified) (3 diffs)
-
uhci/main.c (modified) (4 diffs)
-
vhc/main.c (modified) (2 diffs)
-
vhc/transfer.c (modified) (5 diffs)
-
vhc/vhcd.h (modified) (3 diffs)
-
xhci/bus.c (modified) (5 diffs)
-
xhci/hc.c (modified) (3 diffs)
-
xhci/hc.h (modified) (4 diffs)
-
xhci/main.c (modified) (2 diffs)
-
xhci/rh.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/ehci_bus.c
r1ea0bbf r32fb6bce 162 162 .parent = &usb2_bus_ops, 163 163 164 .interrupt = ehci_hc_interrupt, 165 .status = ehci_hc_status, 164 166 .endpoint_destroy = ehci_endpoint_destroy, 165 167 .endpoint_create = ehci_endpoint_create, … … 171 173 .batch_create = ehci_create_batch, 172 174 .batch_destroy = ehci_destroy_batch, 175 .batch_schedule = ehci_hc_schedule, 173 176 }; 174 177 175 int ehci_bus_init(ehci_bus_t *bus, hc d_t *hcd, hc_t *hc)178 int ehci_bus_init(ehci_bus_t *bus, hc_t *hc) 176 179 { 177 180 assert(hc); … … 181 184 bus_t *bus_base = (bus_t *) bus; 182 185 183 usb2_bus_init(usb2_bus, hcd,BANDWIDTH_AVAILABLE_USB11);186 usb2_bus_init(usb2_bus, BANDWIDTH_AVAILABLE_USB11); 184 187 bus_base->ops = &ehci_bus_ops; 185 188 -
uspace/drv/bus/usb/ehci/ehci_bus.h
r1ea0bbf r32fb6bce 63 63 void ehci_bus_prepare_ops(void); 64 64 65 int ehci_bus_init(ehci_bus_t *, hc d_t *, hc_t *);65 int ehci_bus_init(ehci_bus_t *, hc_t *); 66 66 67 67 /** Get and convert assigned ehci_endpoint_t structure 68 68 * @param[in] ep USBD endpoint structure. 69 * @return Pointer to assigned hcdendpoint structure69 * @return Pointer to assigned ehci endpoint structure 70 70 */ 71 71 static inline ehci_endpoint_t * ehci_endpoint_get(const endpoint_t *ep) -
uspace/drv/bus/usb/ehci/hc.c
r1ea0bbf r32fb6bce 97 97 * @return Error code. 98 98 */ 99 int ehci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)99 int hc_gen_irq_code(irq_code_t *code, hc_device_t *hcd, const hw_res_list_parsed_t *hw_res) 100 100 { 101 101 assert(code); 102 102 assert(hw_res); 103 104 hc_t *instance = hcd_get_driver_data(hcd); 103 hc_t *instance = hcd_to_hc(hcd); 105 104 106 105 if (hw_res->irqs.count != 1 || hw_res->mem_ranges.count != 1) … … 149 148 * @return Error code 150 149 */ 151 int hc_ init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)152 { 153 assert(instance);150 int hc_add(hc_device_t *hcd, const hw_res_list_parsed_t *hw_res) 151 { 152 hc_t *instance = hcd_to_hc(hcd); 154 153 assert(hw_res); 155 154 if (hw_res->mem_ranges.count != 1 || … … 190 189 &instance->rh, instance->caps, instance->registers, "ehci rh"); 191 190 192 ehci_bus_init(&instance->bus, hcd, instance); 191 ehci_bus_init(&instance->bus, instance); 192 hc_device_setup(hcd, (bus_t *) &instance->bus); 193 193 return EOK; 194 194 } … … 198 198 * @param[in] instance Host controller structure to use. 199 199 */ 200 void hc_fini(hc_t *instance)200 int hc_gone(hc_device_t *instance) 201 201 { 202 202 assert(instance); 203 return EOK; 203 204 //TODO: stop the hw 204 205 #if 0 … … 263 264 } 264 265 265 int ehci_hc_status(hcd_t *hcd, uint32_t *status) 266 { 267 assert(hcd); 268 hc_t *instance = hcd_get_driver_data(hcd); 269 assert(instance); 266 int ehci_hc_status(bus_t *bus_base, uint32_t *status) 267 { 268 assert(bus_base); 270 269 assert(status); 270 271 ehci_bus_t *bus = (ehci_bus_t *) bus_base; 272 hc_t *hc = bus->hc; 273 assert(hc); 274 271 275 *status = 0; 272 if ( instance->registers) {273 *status = EHCI_RD( instance->registers->usbsts);274 EHCI_WR( instance->registers->usbsts, *status);275 } 276 usb_log_debug2("HC(%p): Read status: %x", instance, *status);276 if (hc->registers) { 277 *status = EHCI_RD(hc->registers->usbsts); 278 EHCI_WR(hc->registers->usbsts, *status); 279 } 280 usb_log_debug2("HC(%p): Read status: %x", hc, *status); 277 281 return EOK; 278 282 } … … 284 288 * @return Error code. 285 289 */ 286 int ehci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch) 287 { 288 assert(hcd); 289 hc_t *instance = hcd_get_driver_data(hcd); 290 assert(instance); 290 int ehci_hc_schedule(usb_transfer_batch_t *batch) 291 { 292 assert(batch); 293 294 ehci_bus_t *bus = (ehci_bus_t *) endpoint_get_bus(batch->ep); 295 hc_t *hc = bus->hc; 296 assert(hc); 291 297 292 298 /* Check for root hub communication */ 293 if (batch->target.address == ehci_rh_get_address(& instance->rh)) {299 if (batch->target.address == ehci_rh_get_address(&hc->rh)) { 294 300 usb_log_debug("HC(%p): Scheduling BATCH(%p) for RH(%p)", 295 instance, batch, &instance->rh);296 return ehci_rh_schedule(& instance->rh, batch);301 hc, batch, &hc->rh); 302 return ehci_rh_schedule(&hc->rh, batch); 297 303 } 298 304 … … 303 309 return err; 304 310 305 fibril_mutex_lock(& instance->guard);306 usb_log_debug2("HC(%p): Appending BATCH(%p)", instance, batch);307 list_append(&ehci_batch->link, & instance->pending_batches);308 usb_log_debug("HC(%p): Committing BATCH(%p)", instance, batch);311 fibril_mutex_lock(&hc->guard); 312 usb_log_debug2("HC(%p): Appending BATCH(%p)", hc, batch); 313 list_append(&ehci_batch->link, &hc->pending_batches); 314 usb_log_debug("HC(%p): Committing BATCH(%p)", hc, batch); 309 315 ehci_transfer_batch_commit(ehci_batch); 310 316 311 fibril_mutex_unlock(& instance->guard);317 fibril_mutex_unlock(&hc->guard); 312 318 return EOK; 313 319 } … … 318 324 * @param[in] status Value of the status register at the time of interrupt. 319 325 */ 320 void ehci_hc_interrupt(hcd_t *hcd, uint32_t status) 321 { 322 assert(hcd); 323 hc_t *instance = hcd_get_driver_data(hcd); 324 status = EHCI_RD(status); 325 assert(instance); 326 327 usb_log_debug2("HC(%p): Interrupt: %"PRIx32, instance, status); 326 void ehci_hc_interrupt(bus_t *bus_base, uint32_t status) 327 { 328 assert(bus_base); 329 330 ehci_bus_t *bus = (ehci_bus_t *) bus_base; 331 hc_t *hc = bus->hc; 332 assert(hc); 333 334 usb_log_debug2("HC(%p): Interrupt: %"PRIx32, hc, status); 328 335 if (status & USB_STS_PORT_CHANGE_FLAG) { 329 ehci_rh_interrupt(& instance->rh);336 ehci_rh_interrupt(&hc->rh); 330 337 } 331 338 332 339 if (status & USB_STS_IRQ_ASYNC_ADVANCE_FLAG) { 333 fibril_mutex_lock(& instance->guard);334 usb_log_debug2("HC(%p): Signaling doorbell", instance);335 fibril_condvar_broadcast(& instance->async_doorbell);336 fibril_mutex_unlock(& instance->guard);340 fibril_mutex_lock(&hc->guard); 341 usb_log_debug2("HC(%p): Signaling doorbell", hc); 342 fibril_condvar_broadcast(&hc->async_doorbell); 343 fibril_mutex_unlock(&hc->guard); 337 344 } 338 345 339 346 if (status & (USB_STS_IRQ_FLAG | USB_STS_ERR_IRQ_FLAG)) { 340 fibril_mutex_lock(& instance->guard);341 342 usb_log_debug2("HC(%p): Scanning %lu pending batches", instance,343 list_count(& instance->pending_batches));344 list_foreach_safe( instance->pending_batches, current, next) {347 fibril_mutex_lock(&hc->guard); 348 349 usb_log_debug2("HC(%p): Scanning %lu pending batches", hc, 350 list_count(&hc->pending_batches)); 351 list_foreach_safe(hc->pending_batches, current, next) { 345 352 ehci_transfer_batch_t *batch = 346 353 ehci_transfer_batch_from_link(current); … … 351 358 } 352 359 } 353 fibril_mutex_unlock(& instance->guard);360 fibril_mutex_unlock(&hc->guard); 354 361 } 355 362 356 363 if (status & USB_STS_HOST_ERROR_FLAG) { 357 usb_log_fatal("HCD(%p): HOST SYSTEM ERROR!", instance);364 usb_log_fatal("HCD(%p): HOST SYSTEM ERROR!", hc); 358 365 //TODO do something here 359 366 } … … 364 371 * @param[in] instance EHCI hc driver structure. 365 372 */ 366 int hc_start(hc_ t *instance, bool interrupts)367 { 368 assert(instance);373 int hc_start(hc_device_t *hcd) 374 { 375 hc_t *instance = hcd_to_hc(hcd); 369 376 usb_log_debug("HC(%p): Starting HW.", instance); 370 377 -
uspace/drv/bus/usb/ehci/hc.h
r1ea0bbf r32fb6bce 55 55 /** Main EHCI driver structure */ 56 56 typedef struct hc { 57 /* Common device header */ 58 hc_device_t base; 59 57 60 /** Memory mapped CAPS register area */ 58 61 ehci_caps_regs_t *caps; … … 85 88 } hc_t; 86 89 87 int hc_init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res); 88 int hc_start(hc_t *instance, bool interrupts); 89 void hc_fini(hc_t *instance); 90 static inline hc_t *hcd_to_hc(hc_device_t *hcd) 91 { 92 assert(hcd); 93 return (hc_t *) hcd; 94 } 90 95 91 void hc_enqueue_endpoint(hc_t * instance, const endpoint_t *ep);92 void hc_dequeue_endpoint(hc_t * instance, const endpoint_t *ep);96 void hc_enqueue_endpoint(hc_t *, const endpoint_t *); 97 void hc_dequeue_endpoint(hc_t *, const endpoint_t *); 93 98 94 int ehci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res); 99 /* Boottime operations */ 100 int hc_add(hc_device_t *, const hw_res_list_parsed_t *); 101 int hc_start(hc_device_t *); 102 int hc_gen_irq_code(irq_code_t *, hc_device_t *, const hw_res_list_parsed_t *); 103 int hc_gone(hc_device_t *); 95 104 96 void ehci_hc_interrupt(hcd_t *hcd, uint32_t status); 97 int ehci_hc_status(hcd_t *hcd, uint32_t *status); 98 int ehci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 105 /** Runtime operations */ 106 void ehci_hc_interrupt(bus_t *, uint32_t); 107 int ehci_hc_status(bus_t *, uint32_t *); 108 int ehci_hc_schedule(usb_transfer_batch_t *); 109 99 110 #endif 100 111 /** -
uspace/drv/bus/usb/ehci/main.c
r1ea0bbf r32fb6bce 35 35 */ 36 36 37 #include <ddf/driver.h>38 #include <ddf/interrupt.h>39 #include <device/hw_res.h>40 #include <errno.h>41 #include <str_error.h>42 37 #include <io/logctl.h> 43 44 #include <usb_iface.h> 45 #include <usb/debug.h> 38 #include <usb/host/hcd.h> 46 39 #include <usb/host/ddf_helpers.h> 47 40 … … 51 44 #define NAME "ehci" 52 45 53 static int ehci_driver_init(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *); 54 static int ehci_driver_claim(hcd_t *, ddf_dev_t *); 55 static int ehci_driver_start(hcd_t *, bool); 56 static void ehci_driver_fini(hcd_t *); 46 static const hc_driver_t ehci_driver = { 47 .name = NAME, 48 .hc_device_size = sizeof(hc_t), 57 49 58 static const ddf_hc_driver_t ehci_hc_driver = { 59 .name = "EHCI-PCI", 60 .init = ehci_driver_init, 61 .irq_code_gen = ehci_hc_gen_irq_code, 62 .claim = ehci_driver_claim, 63 .start = ehci_driver_start, 50 .hc_add = hc_add, 51 .irq_code_gen = hc_gen_irq_code, 52 .claim = disable_legacy, 53 .start = hc_start, 64 54 .setup_root_hub = hcd_setup_virtual_root_hub, 65 .fini = ehci_driver_fini, 66 .ops = { 67 .schedule = ehci_hc_schedule, 68 .irq_hook = ehci_hc_interrupt, 69 .status_hook = ehci_hc_status, 70 } 55 .hc_gone = hc_gone, 71 56 }; 72 73 74 static int ehci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, ddf_dev_t *device)75 {76 assert(hcd);77 assert(hcd_get_driver_data(hcd) == NULL);78 79 hc_t *instance = malloc(sizeof(hc_t));80 if (!instance)81 return ENOMEM;82 83 const int ret = hc_init(instance, hcd, res);84 if (ret == EOK) {85 hcd_set_implementation(hcd, instance, &ehci_hc_driver.ops, &instance->bus.base.base);86 } else {87 free(instance);88 }89 return ret;90 }91 92 static int ehci_driver_claim(hcd_t *hcd, ddf_dev_t *dev)93 {94 hc_t *instance = hcd_get_driver_data(hcd);95 assert(instance);96 97 return disable_legacy(instance, dev);98 }99 100 static int ehci_driver_start(hcd_t *hcd, bool irq) {101 hc_t *instance = hcd_get_driver_data(hcd);102 assert(instance);103 104 return hc_start(instance, irq);105 }106 107 static void ehci_driver_fini(hcd_t *hcd)108 {109 assert(hcd);110 hc_t *hc = hcd_get_driver_data(hcd);111 if (hc)112 hc_fini(hc);113 114 free(hc);115 hcd_set_implementation(hcd, NULL, NULL, NULL);116 }117 118 /** Initializes a new ddf driver instance of EHCI hcd.119 *120 * @param[in] device DDF instance of the device to initialize.121 * @return Error code.122 */123 static int ehci_dev_add(ddf_dev_t *device)124 {125 usb_log_debug("ehci_dev_add() called\n");126 assert(device);127 128 return hcd_ddf_add_hc(device, &ehci_hc_driver);129 130 }131 132 static int ehci_fun_online(ddf_fun_t *fun)133 {134 return hcd_ddf_device_online(fun);135 }136 137 static int ehci_fun_offline(ddf_fun_t *fun)138 {139 return hcd_ddf_device_offline(fun);140 }141 142 143 static const driver_ops_t ehci_driver_ops = {144 .dev_add = ehci_dev_add,145 .fun_online = ehci_fun_online,146 .fun_offline = ehci_fun_offline147 };148 149 static const driver_t ehci_driver = {150 .name = NAME,151 .driver_ops = &ehci_driver_ops152 };153 154 57 155 58 /** Initializes global driver structures (NONE). … … 165 68 log_init(NAME); 166 69 logctl_set_log_level(NAME, LVL_NOTE); 167 return ddf_driver_main(&ehci_driver);70 return hc_driver_main(&ehci_driver); 168 71 } 169 72 -
uspace/drv/bus/usb/ehci/res.c
r1ea0bbf r32fb6bce 45 45 #include <pci_dev_iface.h> 46 46 47 #include "hc.h" 47 48 #include "res.h" 48 49 #include "ehci_regs.h" … … 172 173 } 173 174 174 int disable_legacy(hc_ t *hc, ddf_dev_t *device)175 int disable_legacy(hc_device_t *hcd) 175 176 { 176 assert(device);177 178 async_sess_t *parent_sess = ddf_dev_parent_sess_get( device);177 hc_t *hc = hcd_to_hc(hcd); 178 179 async_sess_t *parent_sess = ddf_dev_parent_sess_get(hcd->ddf_dev); 179 180 if (parent_sess == NULL) 180 181 return ENOMEM; -
uspace/drv/bus/usb/ehci/res.h
r1ea0bbf r32fb6bce 36 36 #define DRV_EHCI_PCI_H 37 37 38 #include <ddf/driver.h> 39 #include <device/hw_res_parsed.h> 38 typedef struct hc_device hc_device_t; 40 39 41 #include "hc.h" 42 43 extern int disable_legacy(hc_t *, ddf_dev_t *); 40 extern int disable_legacy(hc_device_t *); 44 41 45 42 #endif -
uspace/drv/bus/usb/ohci/hc.c
r1ea0bbf r32fb6bce 101 101 * @return Error code. 102 102 */ 103 int ohci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)103 int hc_gen_irq_code(irq_code_t *code, hc_device_t *hcd, const hw_res_list_parsed_t *hw_res) 104 104 { 105 105 assert(code); … … 149 149 * @return Error code 150 150 */ 151 int hc_ init(hc_t *instance, const hw_res_list_parsed_t *hw_res)152 { 153 assert(instance);151 int hc_add(hc_device_t *hcd, const hw_res_list_parsed_t *hw_res) 152 { 153 hc_t *instance = hcd_to_hc(hcd); 154 154 assert(hw_res); 155 155 if (hw_res->mem_ranges.count != 1 || … … 186 186 * @param[in] instance Host controller structure to use. 187 187 */ 188 void hc_fini(hc_t *instance)188 int hc_gone(hc_device_t *instance) 189 189 { 190 190 assert(instance); 191 191 /* TODO: implement*/ 192 }; 192 return ENOTSUP; 193 } 193 194 194 195 void hc_enqueue_endpoint(hc_t *instance, const endpoint_t *ep) … … 260 261 } 261 262 262 int ohci_hc_status( hcd_t *hcd, uint32_t *status)263 { 264 assert( hcd);263 int ohci_hc_status(bus_t *bus_base, uint32_t *status) 264 { 265 assert(bus_base); 265 266 assert(status); 266 hc_t *instance = hcd_get_driver_data(hcd); 267 assert(instance); 268 269 if (instance->registers){ 270 *status = OHCI_RD(instance->registers->interrupt_status); 271 OHCI_WR(instance->registers->interrupt_status, *status); 267 268 ohci_bus_t *bus = (ohci_bus_t *) bus_base; 269 hc_t *hc = bus->hc; 270 assert(hc); 271 272 if (hc->registers){ 273 *status = OHCI_RD(hc->registers->interrupt_status); 274 OHCI_WR(hc->registers->interrupt_status, *status); 272 275 } 273 276 return EOK; … … 280 283 * @return Error code. 281 284 */ 282 int ohci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch) 283 { 284 assert(hcd); 285 hc_t *instance = hcd_get_driver_data(hcd); 286 assert(instance); 285 int ohci_hc_schedule(usb_transfer_batch_t *batch) 286 { 287 assert(batch); 288 289 ohci_bus_t *bus = (ohci_bus_t *) endpoint_get_bus(batch->ep); 290 hc_t *hc = bus->hc; 291 assert(hc); 287 292 288 293 /* Check for root hub communication */ 289 if (batch->target.address == ohci_rh_get_address(& instance->rh)) {294 if (batch->target.address == ohci_rh_get_address(&hc->rh)) { 290 295 usb_log_debug("OHCI root hub request.\n"); 291 return ohci_rh_schedule(& instance->rh, batch);296 return ohci_rh_schedule(&hc->rh, batch); 292 297 } 293 298 ohci_transfer_batch_t *ohci_batch = ohci_transfer_batch_get(batch); … … 299 304 return err; 300 305 301 fibril_mutex_lock(& instance->guard);302 list_append(&ohci_batch->link, & instance->pending_batches);306 fibril_mutex_lock(&hc->guard); 307 list_append(&ohci_batch->link, &hc->pending_batches); 303 308 ohci_transfer_batch_commit(ohci_batch); 304 309 … … 307 312 { 308 313 case USB_TRANSFER_CONTROL: 309 OHCI_SET( instance->registers->command_status, CS_CLF);314 OHCI_SET(hc->registers->command_status, CS_CLF); 310 315 break; 311 316 case USB_TRANSFER_BULK: 312 OHCI_SET( instance->registers->command_status, CS_BLF);317 OHCI_SET(hc->registers->command_status, CS_BLF); 313 318 break; 314 319 default: 315 320 break; 316 321 } 317 fibril_mutex_unlock(& instance->guard);322 fibril_mutex_unlock(&hc->guard); 318 323 return EOK; 319 324 } … … 324 329 * @param[in] status Value of the status register at the time of interrupt. 325 330 */ 326 void ohci_hc_interrupt(hcd_t *hcd, uint32_t status) 327 { 328 assert(hcd); 329 hc_t *instance = hcd_get_driver_data(hcd); 331 void ohci_hc_interrupt(bus_t *bus_base, uint32_t status) 332 { 333 assert(bus_base); 334 335 ohci_bus_t *bus = (ohci_bus_t *) bus_base; 336 hc_t *hc = bus->hc; 337 assert(hc); 338 330 339 status = OHCI_RD(status); 331 assert( instance);340 assert(hc); 332 341 if ((status & ~I_SF) == 0) /* ignore sof status */ 333 342 return; 334 usb_log_debug2("OHCI(%p) interrupt: %x.\n", instance, status);343 usb_log_debug2("OHCI(%p) interrupt: %x.\n", hc, status); 335 344 if (status & I_RHSC) 336 ohci_rh_interrupt(& instance->rh);345 ohci_rh_interrupt(&hc->rh); 337 346 338 347 if (status & I_WDH) { 339 fibril_mutex_lock(& instance->guard);340 usb_log_debug2("HCCA: %p-%#" PRIx32 " (%p).\n", instance->hcca,341 OHCI_RD( instance->registers->hcca),342 (void *) addr_to_phys( instance->hcca));348 fibril_mutex_lock(&hc->guard); 349 usb_log_debug2("HCCA: %p-%#" PRIx32 " (%p).\n", hc->hcca, 350 OHCI_RD(hc->registers->hcca), 351 (void *) addr_to_phys(hc->hcca)); 343 352 usb_log_debug2("Periodic current: %#" PRIx32 ".\n", 344 OHCI_RD( instance->registers->periodic_current));345 346 link_t *current = list_first(& instance->pending_batches);347 while (current && current != & instance->pending_batches.head) {353 OHCI_RD(hc->registers->periodic_current)); 354 355 link_t *current = list_first(&hc->pending_batches); 356 while (current && current != &hc->pending_batches.head) { 348 357 link_t *next = current->next; 349 358 ohci_transfer_batch_t *batch = … … 357 366 current = next; 358 367 } 359 fibril_mutex_unlock(& instance->guard);368 fibril_mutex_unlock(&hc->guard); 360 369 } 361 370 362 371 if (status & I_UE) { 363 372 usb_log_fatal("Error like no other!\n"); 364 hc_start( instance);373 hc_start(&hc->base); 365 374 } 366 375 … … 374 383 * @param[in] instance OHCI hc driver structure. 375 384 */ 376 void hc_gain_control(hc_t *instance)377 { 378 assert(instance);385 int hc_gain_control(hc_device_t *hcd) 386 { 387 hc_t *instance = hcd_to_hc(hcd); 379 388 380 389 usb_log_debug("Requesting OHCI control.\n"); … … 409 418 C_HCFS_SET(instance->registers->control, C_HCFS_RESET); 410 419 async_usleep(50000); 411 return ;420 return EOK; 412 421 } 413 422 … … 418 427 if (hc_status == C_HCFS_OPERATIONAL) { 419 428 usb_log_info("BIOS driver: HC operational.\n"); 420 return ;429 return EOK; 421 430 } 422 431 /* HC is suspended assert resume for 20ms */ … … 424 433 async_usleep(20000); 425 434 usb_log_info("BIOS driver: HC resumed.\n"); 426 return ;435 return EOK; 427 436 } 428 437 … … 431 440 usb_log_debug("Host controller found in reset state.\n"); 432 441 async_usleep(50000); 442 return EOK; 433 443 } 434 444 … … 437 447 * @param[in] instance OHCI hc driver structure. 438 448 */ 439 void hc_start(hc_t *instance) 440 { 449 int hc_start(hc_device_t *hcd) 450 { 451 hc_t *instance = hcd_to_hc(hcd); 441 452 ohci_rh_init(&instance->rh, instance->registers, "ohci rh"); 442 453 … … 489 500 490 501 /* Enable interrupts */ 491 if (instance-> hw_interrupts) {502 if (instance->base.irq_cap >= 0) { 492 503 OHCI_WR(instance->registers->interrupt_enable, 493 504 OHCI_USED_INTERRUPTS); … … 508 519 usb_log_debug("OHCI HC up and running (ctl_reg=0x%x).\n", 509 520 OHCI_RD(instance->registers->control)); 521 522 return EOK; 510 523 } 511 524 … … 555 568 memset(&instance->rh, 0, sizeof(instance->rh)); 556 569 /* Init queues */ 557 constint ret = hc_init_transfer_lists(instance);570 int ret = hc_init_transfer_lists(instance); 558 571 if (ret != EOK) { 559 572 return ret; … … 574 587 instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa); 575 588 589 if ((ret = ohci_bus_init(&instance->bus, instance))) { 590 usb_log_error("HC(%p): Failed to setup bus : %s", 591 instance, str_error(ret)); 592 return ret; 593 } 594 595 hc_device_setup(&instance->base, (bus_t *) &instance->bus); 596 576 597 return EOK; 577 598 } -
uspace/drv/bus/usb/ohci/hc.h
r1ea0bbf r32fb6bce 58 58 /** Main OHCI driver structure */ 59 59 typedef struct hc { 60 /** Common hcd header */ 61 hc_device_t base; 62 60 63 /** Memory mapped I/O registers area */ 61 64 ohci_regs_t *registers; … … 70 73 list_t pending_batches; 71 74 72 /** Fibril for periodic checks if interrupts can't be used */73 fid_t interrupt_emulator;74 75 75 /** Guards schedule and endpoint manipulation */ 76 76 fibril_mutex_t guard; 77 78 /** interrupts available */79 bool hw_interrupts;80 77 81 78 /** USB hub emulation structure */ … … 86 83 } hc_t; 87 84 88 extern int hc_init(hc_t *, const hw_res_list_parsed_t *); 89 extern void hc_gain_control(hc_t *instance); 90 extern void hc_start(hc_t *instance); 91 extern void hc_fini(hc_t *); 85 static inline hc_t * hcd_to_hc(hc_device_t *hcd) 86 { 87 assert(hcd); 88 return (hc_t *) hcd; 89 } 90 91 extern int hc_add(hc_device_t *, const hw_res_list_parsed_t *); 92 extern int hc_gen_irq_code(irq_code_t *, hc_device_t *, const hw_res_list_parsed_t *); 93 extern int hc_gain_control(hc_device_t *); 94 extern int hc_start(hc_device_t *); 95 extern int hc_gone(hc_device_t *); 92 96 93 97 extern void hc_enqueue_endpoint(hc_t *, const endpoint_t *); 94 98 extern void hc_dequeue_endpoint(hc_t *, const endpoint_t *); 95 99 96 int ohci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res); 97 98 extern void ohci_hc_interrupt(hcd_t *, uint32_t); 99 extern int ohci_hc_status(hcd_t *, uint32_t *); 100 extern int ohci_hc_schedule(hcd_t *, usb_transfer_batch_t *); 100 extern int ohci_hc_schedule(usb_transfer_batch_t *); 101 extern int ohci_hc_status(bus_t *, uint32_t *); 102 extern void ohci_hc_interrupt(bus_t *, uint32_t); 101 103 102 104 #endif -
uspace/drv/bus/usb/ohci/main.c
r1ea0bbf r32fb6bce 48 48 49 49 #define NAME "ohci" 50 static int ohci_driver_init(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *);51 static int ohci_driver_start(hcd_t *, bool);52 static int ohci_driver_claim(hcd_t *, ddf_dev_t *);53 static void ohci_driver_fini(hcd_t *);54 50 55 static const ddf_hc_driver_t ohci_hc_driver = { 56 .irq_code_gen = ohci_hc_gen_irq_code, 57 .init = ohci_driver_init, 58 .claim = ohci_driver_claim, 59 .start = ohci_driver_start, 51 static const hc_driver_t ohci_driver = { 52 .name = NAME, 53 .hc_device_size = sizeof(hc_t), 54 55 .hc_add = hc_add, 56 .irq_code_gen = hc_gen_irq_code, 57 .claim = hc_gain_control, 58 .start = hc_start, 60 59 .setup_root_hub = hcd_setup_virtual_root_hub, 61 .fini = ohci_driver_fini, 62 .name = "OHCI", 63 .ops = { 64 .schedule = ohci_hc_schedule, 65 .irq_hook = ohci_hc_interrupt, 66 .status_hook = ohci_hc_status, 67 }, 68 }; 69 70 71 static int ohci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, ddf_dev_t *device) 72 { 73 int err; 74 75 assert(hcd); 76 assert(hcd_get_driver_data(hcd) == NULL); 77 78 hc_t *instance = malloc(sizeof(hc_t)); 79 if (!instance) 80 return ENOMEM; 81 82 if ((err = hc_init(instance, res)) != EOK) 83 goto err; 84 85 if ((err = ohci_bus_init(&instance->bus, hcd, instance))) 86 goto err; 87 88 hcd_set_implementation(hcd, instance, &ohci_hc_driver.ops, &instance->bus.base.base); 89 90 return EOK; 91 92 err: 93 free(instance); 94 return err; 95 } 96 97 static int ohci_driver_claim(hcd_t *hcd, ddf_dev_t *dev) 98 { 99 hc_t *hc = hcd_get_driver_data(hcd); 100 assert(hc); 101 102 hc_gain_control(hc); 103 104 return EOK; 105 } 106 107 static int ohci_driver_start(hcd_t *hcd, bool interrupts) 108 { 109 hc_t *hc = hcd_get_driver_data(hcd); 110 assert(hc); 111 112 hc->hw_interrupts = interrupts; 113 hc_start(hc); 114 return EOK; 115 } 116 117 static void ohci_driver_fini(hcd_t *hcd) 118 { 119 assert(hcd); 120 hc_t *hc = hcd_get_driver_data(hcd); 121 if (hc) 122 hc_fini(hc); 123 124 hcd_set_implementation(hcd, NULL, NULL, NULL); 125 free(hc); 126 } 127 128 /** Initializes a new ddf driver instance of OHCI hcd. 129 * 130 * @param[in] device DDF instance of the device to initialize. 131 * @return Error code. 132 */ 133 static int ohci_dev_add(ddf_dev_t *device) 134 { 135 usb_log_debug("ohci_dev_add() called\n"); 136 assert(device); 137 return hcd_ddf_add_hc(device, &ohci_hc_driver); 138 } 139 140 static int ohci_fun_online(ddf_fun_t *fun) 141 { 142 return hcd_ddf_device_online(fun); 143 } 144 145 static int ohci_fun_offline(ddf_fun_t *fun) 146 { 147 return hcd_ddf_device_offline(fun); 148 } 149 150 151 static const driver_ops_t ohci_driver_ops = { 152 .dev_add = ohci_dev_add, 153 .fun_online = ohci_fun_online, 154 .fun_offline = ohci_fun_offline 155 }; 156 157 static const driver_t ohci_driver = { 158 .name = NAME, 159 .driver_ops = &ohci_driver_ops 60 .hc_gone = hc_gone, 160 61 }; 161 62 … … 171 72 { 172 73 log_init(NAME); 173 return ddf_driver_main(&ohci_driver);74 return hc_driver_main(&ohci_driver); 174 75 } 175 76 -
uspace/drv/bus/usb/ohci/ohci_bus.c
r1ea0bbf r32fb6bce 158 158 .parent = &usb2_bus_ops, 159 159 160 .interrupt = ohci_hc_interrupt, 161 .status = ohci_hc_status, 162 160 163 .endpoint_destroy = ohci_endpoint_destroy, 161 164 .endpoint_create = ohci_endpoint_create, … … 167 170 .batch_create = ohci_create_batch, 168 171 .batch_destroy = ohci_destroy_batch, 172 .batch_schedule = ohci_hc_schedule, 169 173 }; 170 174 171 175 172 int ohci_bus_init(ohci_bus_t *bus, hc d_t *hcd, hc_t *hc)176 int ohci_bus_init(ohci_bus_t *bus, hc_t *hc) 173 177 { 174 178 assert(hc); 175 179 assert(bus); 176 180 177 178 181 usb2_bus_t *usb2_bus = (usb2_bus_t *) bus; 179 182 bus_t *bus_base = (bus_t *) bus; 180 183 181 usb2_bus_init(usb2_bus, hcd,BANDWIDTH_AVAILABLE_USB11);184 usb2_bus_init(usb2_bus, BANDWIDTH_AVAILABLE_USB11); 182 185 bus_base->ops = &ohci_bus_ops; 183 186 -
uspace/drv/bus/usb/ohci/ohci_bus.h
r1ea0bbf r32fb6bce 62 62 } ohci_bus_t; 63 63 64 int ohci_bus_init(ohci_bus_t *, hc d_t *, hc_t *);64 int ohci_bus_init(ohci_bus_t *, hc_t *); 65 65 66 66 /** Get and convert assigned ohci_endpoint_t structure -
uspace/drv/bus/usb/uhci/hc.c
r1ea0bbf r32fb6bce 95 95 96 96 static void hc_init_hw(const hc_t *instance); 97 static int hc_init_mem_structures(hc_t *instance, hc d_t *);97 static int hc_init_mem_structures(hc_t *instance, hc_device_t *); 98 98 static int hc_init_transfer_lists(hc_t *instance); 99 99 … … 107 107 * @return Error code. 108 108 */ 109 int uhci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)109 int hc_gen_irq_code(irq_code_t *code, hc_device_t *hcd, const hw_res_list_parsed_t *hw_res) 110 110 { 111 111 assert(code); … … 156 156 * - resume from suspend state (not implemented) 157 157 */ 158 void uhci_hc_interrupt(hcd_t *hcd, uint32_t status) 159 { 160 assert(hcd); 161 hc_t *instance = hcd_get_driver_data(hcd); 162 assert(instance); 158 static void hc_interrupt(bus_t *bus, uint32_t status) 159 { 160 hc_t *instance = bus_to_hc(bus); 161 163 162 /* Lower 2 bits are transaction error and transaction complete */ 164 163 if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) { … … 199 198 } else { 200 199 usb_log_fatal("Too many UHCI hardware failures!.\n"); 201 hc_ fini(instance);200 hc_gone(&instance->base); 202 201 } 203 202 } … … 215 214 * interrupt fibrils. 216 215 */ 217 int hc_ init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)218 { 219 assert(instance);216 int hc_add(hc_device_t *hcd, const hw_res_list_parsed_t *hw_res) 217 { 218 hc_t *instance = hcd_to_hc(hcd); 220 219 assert(hw_res); 221 220 if (hw_res->io_ranges.count != 1 || … … 249 248 } 250 249 251 void hc_start(hc_t *instance) 252 { 250 int hc_start(hc_device_t *hcd) 251 { 252 hc_t *instance = hcd_to_hc(hcd); 253 253 hc_init_hw(instance); 254 254 (void)hc_debug_checker; 255 255 256 uhci_rh_init(&instance->rh, instance->registers->ports, "uhci");256 return uhci_rh_init(&instance->rh, instance->registers->ports, "uhci"); 257 257 } 258 258 … … 261 261 * @param[in] instance Host controller structure to use. 262 262 */ 263 void hc_fini(hc_t *instance)263 int hc_gone(hc_device_t *instance) 264 264 { 265 265 assert(instance); 266 266 //TODO Implement 267 return ENOTSUP; 267 268 } 268 269 … … 294 295 pio_write_32(®isters->flbaseadd, pa); 295 296 296 if (instance-> hw_interrupts) {297 if (instance->base.irq_cap >= 0) { 297 298 /* Enable all interrupts, but resume interrupt */ 298 299 pio_write_16(&instance->registers->usbintr, … … 320 321 } 321 322 323 static int hc_status(bus_t *, uint32_t *); 324 static int hc_schedule(usb_transfer_batch_t *); 325 322 326 static const bus_ops_t uhci_bus_ops = { 323 327 .parent = &usb2_bus_ops, 324 328 329 .interrupt = hc_interrupt, 330 .status = hc_status, 331 325 332 .endpoint_count_bw = bandwidth_count_usb11, 326 333 .batch_create = create_transfer_batch, 334 .batch_schedule = hc_schedule, 327 335 .batch_destroy = destroy_transfer_batch, 328 336 }; … … 338 346 * - frame list page (needs to be one UHCI hw accessible 4K page) 339 347 */ 340 int hc_init_mem_structures(hc_t *instance, hc d_t *hcd)348 int hc_init_mem_structures(hc_t *instance, hc_device_t *hcd) 341 349 { 342 350 int err; 343 351 assert(instance); 344 352 345 if ((err = usb2_bus_init(&instance->bus, hcd,BANDWIDTH_AVAILABLE_USB11)))353 if ((err = usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11))) 346 354 return err; 347 355 348 356 bus_t *bus = (bus_t *) &instance->bus; 349 357 bus->ops = &uhci_bus_ops; 358 359 hc_device_setup(&instance->base, bus); 350 360 351 361 /* Init USB frame list page */ … … 438 448 } 439 449 440 int uhci_hc_status(hcd_t *hcd, uint32_t *status)441 { 442 assert(hcd);450 static int hc_status(bus_t *bus, uint32_t *status) 451 { 452 hc_t *instance = bus_to_hc(bus); 443 453 assert(status); 444 hc_t *instance = hcd_get_driver_data(hcd);445 assert(instance);446 454 447 455 *status = 0; … … 462 470 * Checks for bandwidth availability and appends the batch to the proper queue. 463 471 */ 464 int uhci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch) 465 { 466 assert(hcd); 467 hc_t *instance = hcd_get_driver_data(hcd); 468 assert(instance); 472 static int hc_schedule(usb_transfer_batch_t *batch) 473 { 474 hc_t *instance = bus_to_hc(endpoint_get_bus(batch->ep)); 469 475 assert(batch); 470 476 -
uspace/drv/bus/usb/uhci/hc.h
r1ea0bbf r32fb6bce 100 100 /** Main UHCI driver structure */ 101 101 typedef struct hc { 102 /* Common hc_device header */ 103 hc_device_t base; 104 102 105 uhci_rh_t rh; 103 106 usb2_bus_t bus; … … 119 122 /** Pointer table to the above lists, helps during scheduling */ 120 123 transfer_list_t *transfers[2][4]; 121 /** Indicator of hw interrupts availability */122 bool hw_interrupts;123 124 124 125 /** Number of hw failures detected. */ … … 126 127 } hc_t; 127 128 128 extern int hc_init(hc_t *, hcd_t *, const hw_res_list_parsed_t *); 129 extern void hc_start(hc_t *); 130 extern void hc_fini(hc_t *); 129 static inline hc_t *hcd_to_hc(hc_device_t *hcd) 130 { 131 assert(hcd); 132 return (hc_t *) hcd; 133 } 131 134 132 extern int uhci_hc_gen_irq_code(irq_code_t *, hcd_t *,const hw_res_list_parsed_t *); 135 static inline hc_t *bus_to_hc(bus_t *bus) 136 { 137 assert(bus); 138 return member_to_inst(bus, hc_t, bus); 139 } 133 140 134 extern void uhci_hc_interrupt(hcd_t *, uint32_t); 135 extern int uhci_hc_status(hcd_t *, uint32_t *); 136 extern int uhci_hc_schedule(hcd_t *, usb_transfer_batch_t *); 141 extern int hc_add(hc_device_t *, const hw_res_list_parsed_t *); 142 extern int hc_gen_irq_code(irq_code_t *, hc_device_t *, const hw_res_list_parsed_t *); 143 extern int hc_start(hc_device_t *); 144 extern int hc_gone(hc_device_t *); 137 145 138 146 #endif -
uspace/drv/bus/usb/uhci/main.c
r1ea0bbf r32fb6bce 49 49 #define NAME "uhci" 50 50 51 static int uhci_driver_init(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *); 52 static int uhci_driver_start(hcd_t *, bool); 53 static void uhci_driver_fini(hcd_t *); 54 static int disable_legacy(hcd_t *, ddf_dev_t *); 51 static int disable_legacy(hc_device_t *); 55 52 56 static const ddf_hc_driver_t uhci_hc_driver = { 57 .claim = disable_legacy, 58 .irq_code_gen = uhci_hc_gen_irq_code, 59 .init = uhci_driver_init, 60 .start = uhci_driver_start, 53 static const hc_driver_t uhci_driver = { 54 .name = NAME, 55 .hc_device_size = sizeof(hc_t), 56 .claim = disable_legacy, 57 .irq_code_gen = hc_gen_irq_code, 58 .hc_add = hc_add, 59 .start = hc_start, 61 60 .setup_root_hub = hcd_setup_virtual_root_hub, 62 .fini = uhci_driver_fini, 63 .name = "UHCI", 64 .ops = { 65 .schedule = uhci_hc_schedule, 66 .irq_hook = uhci_hc_interrupt, 67 .status_hook = uhci_hc_status, 68 }, 61 .hc_gone = hc_gone, 69 62 }; 70 71 static int uhci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, ddf_dev_t *device)72 {73 int err;74 75 assert(hcd);76 assert(hcd_get_driver_data(hcd) == NULL);77 78 hc_t *instance = malloc(sizeof(hc_t));79 if (!instance)80 return ENOMEM;81 82 if ((err = hc_init(instance, hcd, res)) != EOK)83 goto err;84 85 hcd_set_implementation(hcd, instance, &uhci_hc_driver.ops, &instance->bus.base);86 87 return EOK;88 89 err:90 free(instance);91 return err;92 }93 94 static int uhci_driver_start(hcd_t *hcd, bool interrupts)95 {96 assert(hcd);97 hc_t *hc = hcd_get_driver_data(hcd);98 99 hc->hw_interrupts = interrupts;100 hc_start(hc);101 return EOK;102 }103 104 static void uhci_driver_fini(hcd_t *hcd)105 {106 assert(hcd);107 hc_t *hc = hcd_get_driver_data(hcd);108 if (hc)109 hc_fini(hc);110 111 hcd_set_implementation(hcd, NULL, NULL, NULL);112 free(hc);113 }114 63 115 64 /** Call the PCI driver with a request to clear legacy support register … … 118 67 * @return Error code. 119 68 */ 120 static int disable_legacy(hc d_t *hcd, ddf_dev_t *device)69 static int disable_legacy(hc_device_t *hcd) 121 70 { 122 assert( device);71 assert(hcd); 123 72 124 async_sess_t *parent_sess = ddf_dev_parent_sess_get( device);73 async_sess_t *parent_sess = ddf_dev_parent_sess_get(hcd->ddf_dev); 125 74 if (parent_sess == NULL) 126 75 return ENOMEM; … … 130 79 return pci_config_space_write_16(parent_sess, 0xc0, 0xaf00); 131 80 } 132 133 /** Initialize a new ddf driver instance for uhci hc and hub.134 *135 * @param[in] device DDF instance of the device to initialize.136 * @return Error code.137 */138 static int uhci_dev_add(ddf_dev_t *device)139 {140 usb_log_debug2("uhci_dev_add() called\n");141 assert(device);142 return hcd_ddf_add_hc(device, &uhci_hc_driver);143 }144 145 static int uhci_fun_online(ddf_fun_t *fun)146 {147 return hcd_ddf_device_online(fun);148 }149 150 static int uhci_fun_offline(ddf_fun_t *fun)151 {152 return hcd_ddf_device_offline(fun);153 }154 155 static const driver_ops_t uhci_driver_ops = {156 .dev_add = uhci_dev_add,157 .fun_online = uhci_fun_online,158 .fun_offline = uhci_fun_offline159 };160 161 static const driver_t uhci_driver = {162 .name = NAME,163 .driver_ops = &uhci_driver_ops164 };165 166 81 167 82 /** Initialize global driver structures (NONE). … … 178 93 log_init(NAME); 179 94 logctl_set_log_level(NAME, LVL_DEBUG2); 180 return ddf_driver_main(&uhci_driver);95 return hc_driver_main(&uhci_driver); 181 96 } 182 97 /** -
uspace/drv/bus/usb/vhc/main.c
r1ea0bbf r32fb6bce 69 69 return ret; 70 70 } 71 vhc_init(vhc, dev_to_hcd(dev));72 71 return EOK; 73 72 } 74 73 75 hcd_ops_t vhc_hc_ops = {76 .schedule = vhc_schedule,77 };78 79 74 static int vhc_dev_add(ddf_dev_t *dev) 80 75 { 76 /* Initialize generic structures */ 77 int ret = hcd_ddf_setup_hc(dev, sizeof(vhc_data_t)); 78 if (ret != EOK) { 79 usb_log_error("Failed to init HCD structures: %s.\n", 80 str_error(ret)); 81 return ret; 82 } 83 vhc_data_t *vhc = ddf_dev_data_get(dev); 84 vhc_init(vhc); 85 86 hc_device_setup(&vhc->base, (bus_t *) &vhc->bus); 87 81 88 /* Initialize virtual structure */ 82 89 ddf_fun_t *ctl_fun = NULL; 83 intret = vhc_control_node(dev, &ctl_fun);90 ret = vhc_control_node(dev, &ctl_fun); 84 91 if (ret != EOK) { 85 92 usb_log_error("Failed to setup control node.\n"); 86 93 return ret; 87 94 } 88 vhc_data_t *data = ddf_fun_data_get(ctl_fun);89 90 /* Initialize generic structures */91 ret = hcd_ddf_setup_hc(dev);92 if (ret != EOK) {93 usb_log_error("Failed to init HCD structures: %s.\n",94 str_error(ret));95 ddf_fun_destroy(ctl_fun);96 return ret;97 }98 99 hcd_set_implementation(dev_to_hcd(dev), data, &vhc_hc_ops, &data->bus.base);100 95 101 96 /* Add virtual hub device */ 102 ret = vhc_virtdev_plug_hub( data, &data->hub, NULL, 0);97 ret = vhc_virtdev_plug_hub(vhc, &vhc->hub, NULL, 0); 103 98 if (ret != EOK) { 104 99 usb_log_error("Failed to plug root hub: %s.\n", str_error(ret)); … … 111 106 * needs to be ready at this time. 112 107 */ 113 ret = hcd_setup_virtual_root_hub( dev_to_hcd(dev), dev);108 ret = hcd_setup_virtual_root_hub(&vhc->base); 114 109 if (ret != EOK) { 115 110 usb_log_error("Failed to init VHC root hub: %s\n", -
uspace/drv/bus/usb/vhc/transfer.c
r1ea0bbf r32fb6bce 40 40 static bool is_set_address_transfer(vhc_transfer_t *transfer) 41 41 { 42 if (transfer->batch ->target.endpoint != 0) {43 return false; 44 } 45 if (transfer->batch ->ep->transfer_type != USB_TRANSFER_CONTROL) {46 return false; 47 } 48 if (transfer->batch ->dir != USB_DIRECTION_OUT) {42 if (transfer->batch.target.endpoint != 0) { 43 return false; 44 } 45 if (transfer->batch.ep->transfer_type != USB_TRANSFER_CONTROL) { 46 return false; 47 } 48 if (transfer->batch.dir != USB_DIRECTION_OUT) { 49 49 return false; 50 50 } 51 51 const usb_device_request_setup_packet_t *setup 52 = &transfer->batch ->setup.packet;52 = &transfer->batch.setup.packet; 53 53 if (setup->request_type != 0) { 54 54 return false; … … 150 150 assert(outcome != ENAK); 151 151 assert(transfer); 152 assert(transfer->batch); 153 transfer->batch->error = outcome; 154 transfer->batch->transfered_size = data_transfer_size; 155 usb_transfer_batch_finish(transfer->batch); 152 transfer->batch.error = outcome; 153 transfer->batch.transfered_size = data_transfer_size; 154 usb_transfer_batch_finish(&transfer->batch); 156 155 free(transfer); 156 } 157 158 static usb_transfer_batch_t *batch_create(endpoint_t *ep) 159 { 160 vhc_transfer_t *transfer = calloc(1, sizeof(vhc_transfer_t)); 161 usb_transfer_batch_init(&transfer->batch, ep); 162 link_initialize(&transfer->link); 163 return &transfer->batch; 157 164 } 158 165 159 166 static const bus_ops_t vhc_bus_ops = { 160 167 .parent = &usb2_bus_ops, 168 161 169 .endpoint_count_bw = bandwidth_count_usb11, 170 .batch_create = batch_create, 171 .batch_schedule = vhc_schedule, 162 172 }; 163 173 164 int vhc_init(vhc_data_t *instance , hcd_t *hcd)174 int vhc_init(vhc_data_t *instance) 165 175 { 166 176 assert(instance); 167 177 list_initialize(&instance->devices); 168 178 fibril_mutex_initialize(&instance->guard); 169 usb2_bus_init(&instance->bus, hcd,BANDWIDTH_AVAILABLE_USB11);179 usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11); 170 180 instance->bus.base.ops = &vhc_bus_ops; 171 instance->magic = 0xDEADBEEF;172 181 return virthub_init(&instance->hub, "root hub"); 173 182 } 174 183 175 int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch) 176 { 177 assert(hcd); 184 int vhc_schedule(usb_transfer_batch_t *batch) 185 { 178 186 assert(batch); 179 vhc_data_t *vhc = hcd_get_driver_data(hcd); 187 vhc_transfer_t *transfer = (vhc_transfer_t *) batch; 188 vhc_data_t *vhc = bus_to_vhc(endpoint_get_bus(batch->ep)); 180 189 assert(vhc); 181 182 vhc_transfer_t *transfer = malloc(sizeof(vhc_transfer_t));183 if (!transfer)184 return ENOMEM;185 link_initialize(&transfer->link);186 transfer->batch = batch;187 190 188 191 fibril_mutex_lock(&vhc->guard); … … 192 195 list_foreach(vhc->devices, link, vhc_virtdev_t, dev) { 193 196 fibril_mutex_lock(&dev->guard); 194 if (dev->address == transfer->batch ->target.address) {197 if (dev->address == transfer->batch.target.address) { 195 198 if (!targets) { 196 199 list_append(&transfer->link, &dev->transfer_queue); … … 227 230 size_t data_transfer_size = 0; 228 231 if (dev->dev_sess) { 229 rc = process_transfer_remote( transfer->batch,232 rc = process_transfer_remote(&transfer->batch, 230 233 dev->dev_sess, &data_transfer_size); 231 234 } else if (dev->dev_local != NULL) { 232 rc = process_transfer_local( transfer->batch,235 rc = process_transfer_local(&transfer->batch, 233 236 dev->dev_local, &data_transfer_size); 234 237 } else { … … 244 247 if (is_set_address_transfer(transfer)) { 245 248 usb_device_request_setup_packet_t *setup = 246 (void*) transfer->batch ->setup.buffer;249 (void*) transfer->batch.setup.buffer; 247 250 dev->address = setup->value; 248 251 usb_log_debug2("Address changed to %d\n", -
uspace/drv/bus/usb/vhc/vhcd.h
r1ea0bbf r32fb6bce 39 39 #include <usbvirt/device.h> 40 40 #include <async.h> 41 #include <macros.h> 41 42 42 43 #include <usb/host/hcd.h> 43 44 #include <usb/host/usb2_bus.h> 45 #include <usb/host/usb_transfer_batch.h> 44 46 45 47 #define NAME "vhc" … … 56 58 57 59 typedef struct { 58 uint32_t magic; 60 hc_device_t base; 61 62 usb2_bus_t bus; 63 ddf_fun_t *virtual_fun; 59 64 list_t devices; 60 65 fibril_mutex_t guard; 61 66 usbvirt_device_t hub; 62 usb2_bus_t bus;63 67 } vhc_data_t; 64 68 65 69 typedef struct { 70 usb_transfer_batch_t batch; 66 71 link_t link; 67 usb_transfer_batch_t *batch;68 72 } vhc_transfer_t; 73 74 static inline vhc_data_t *hcd_to_vhc(hc_device_t *hcd) 75 { 76 assert(hcd); 77 return (vhc_data_t *) hcd; 78 } 79 80 static inline vhc_data_t *bus_to_vhc(bus_t *bus) 81 { 82 assert(bus); 83 return member_to_inst(bus, vhc_data_t, bus); 84 } 69 85 70 86 void on_client_close(ddf_fun_t *fun); … … 77 93 void vhc_virtdev_unplug(vhc_data_t *, uintptr_t); 78 94 79 int vhc_init(vhc_data_t * instance, hcd_t *);80 int vhc_schedule( hcd_t *hcd, usb_transfer_batch_t *batch);95 int vhc_init(vhc_data_t *); 96 int vhc_schedule(usb_transfer_batch_t *); 81 97 int vhc_transfer_queue_processor(void *arg); 82 98 -
uspace/drv/bus/usb/xhci/bus.c
r1ea0bbf r32fb6bce 111 111 112 112 uint16_t max_packet_size; 113 if ((err = hcd_get_ep0_max_packet_size(&max_packet_size, hc->hcd, &dev->base)))113 if ((err = hcd_get_ep0_max_packet_size(&max_packet_size, (bus_t *) &hc->bus, &dev->base))) 114 114 return err; 115 115 … … 168 168 169 169 /* Read the device descriptor, derive the match ids */ 170 if ((err = hcd_d df_device_explore(dev))) {170 if ((err = hcd_device_explore(dev))) { 171 171 usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err)); 172 172 goto err_address; … … 233 233 /* Destroy DDF device. */ 234 234 /* XXX: Not a good idea, this method should not destroy devices. */ 235 hcd_ddf_ device_destroy(dev);235 hcd_ddf_fun_destroy(dev); 236 236 237 237 return EOK; … … 501 501 BIND_OP(batch_destroy) 502 502 #undef BIND_OP 503 504 .interrupt = hc_interrupt, 505 .status = hc_status, 506 .batch_schedule = hc_schedule, 503 507 }; 504 508 … … 507 511 assert(bus); 508 512 509 bus_init(&bus->base, hc->hcd,sizeof(xhci_device_t));513 bus_init(&bus->base, sizeof(xhci_device_t)); 510 514 511 515 bus->devices_by_slot = calloc(hc->max_slots, sizeof(xhci_device_t *)); -
uspace/drv/bus/usb/xhci/hc.c
r1ea0bbf r32fb6bce 432 432 * Used only when polling. Shall supplement the irq_commands. 433 433 */ 434 int hc_status(xhci_hc_t *hc, uint32_t *status) 435 { 434 int hc_status(bus_t *bus, uint32_t *status) 435 { 436 xhci_hc_t *hc = bus_to_hc(bus); 436 437 int ip = XHCI_REG_RD(hc->rt_regs->ir, XHCI_INTR_IP); 437 438 if (ip) { … … 449 450 } 450 451 451 int hc_schedule( xhci_hc_t *hc,usb_transfer_batch_t *batch)452 int hc_schedule(usb_transfer_batch_t *batch) 452 453 { 453 454 assert(batch); 454 assert(batch->ep);455 xhci_hc_t *hc = bus_to_hc(endpoint_get_bus(batch->ep)); 455 456 456 457 if (!batch->target.address) { … … 532 533 } 533 534 534 void hc_interrupt(xhci_hc_t *hc, uint32_t status) 535 { 535 void hc_interrupt(bus_t *bus, uint32_t status) 536 { 537 xhci_hc_t *hc = bus_to_hc(bus); 536 538 status = xhci2host(32, status); 537 539 -
uspace/drv/bus/usb/xhci/hc.h
r1ea0bbf r32fb6bce 51 51 52 52 typedef struct xhci_hc { 53 /** Common HC device header */ 54 hc_device_t base; 55 53 56 /* MMIO range */ 54 57 addr_range_t mmio_range; … … 86 89 xhci_port_speed_t speeds [16]; 87 90 uint8_t speed_to_psiv [USB_SPEED_MAX]; 91 } xhci_hc_t; 88 92 89 /* TODO: Hack. Figure out a better way. */ 90 hcd_t *hcd; 91 } xhci_hc_t; 93 static inline xhci_hc_t *bus_to_hc(bus_t *bus) 94 { 95 assert(bus); 96 return member_to_inst(bus, xhci_hc_t, bus); 97 } 92 98 93 99 typedef struct xhci_endpoint xhci_endpoint_t; … … 99 105 int hc_irq_code_gen(irq_code_t *, xhci_hc_t *, const hw_res_list_parsed_t *); 100 106 int hc_start(xhci_hc_t *, bool); 101 int hc_schedule(xhci_hc_t *hc, usb_transfer_batch_t *batch);102 int hc_status(xhci_hc_t *, uint32_t *);103 void hc_interrupt(xhci_hc_t *, uint32_t);104 107 void hc_fini(xhci_hc_t *); 105 108 int hc_ring_doorbell(xhci_hc_t *, unsigned, unsigned); … … 113 116 int hc_update_endpoint(xhci_hc_t *, uint32_t, uint8_t, xhci_ep_ctx_t *); 114 117 118 int hc_schedule(usb_transfer_batch_t *batch); 119 int hc_status(bus_t *, uint32_t *); 120 void hc_interrupt(bus_t *, uint32_t); 121 115 122 #endif 116 123 -
uspace/drv/bus/usb/xhci/main.c
r1ea0bbf r32fb6bce 47 47 #define NAME "xhci" 48 48 49 static int hc_driver_init(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *); 50 static int hcd_irq_code_gen(irq_code_t *, hcd_t *, const hw_res_list_parsed_t *); 51 static int hcd_claim(hcd_t *, ddf_dev_t *); 52 static int hcd_start(hcd_t *, bool); 53 static int hcd_status(hcd_t *, uint32_t *); 54 static void hcd_interrupt(hcd_t *, uint32_t); 55 static int hcd_schedule(hcd_t *, usb_transfer_batch_t *); 56 static void hc_driver_fini(hcd_t *); 49 static inline xhci_hc_t *hcd_to_hc(hc_device_t *hcd) 50 { 51 assert(hcd); 52 return (xhci_hc_t *) hcd; 53 } 57 54 58 static const ddf_hc_driver_t xhci_ddf_hc_driver = { 59 .name = "XHCI-PCI", 60 .init = hc_driver_init, 55 static int hcd_hc_add(hc_device_t *hcd, const hw_res_list_parsed_t *hw_res) 56 { 57 int err; 58 xhci_hc_t *hc = hcd_to_hc(hcd); 59 hc_device_setup(hcd, (bus_t *) &hc->bus); 60 61 if ((err = hc_init_mmio(hc, hw_res))) 62 return err; 63 64 if ((err = hc_init_memory(hc, hcd->ddf_dev))) 65 return err; 66 67 return EOK; 68 } 69 70 static int hcd_irq_code_gen(irq_code_t *code, hc_device_t *hcd, const hw_res_list_parsed_t *hw_res) 71 { 72 xhci_hc_t *hc = hcd_to_hc(hcd); 73 return hc_irq_code_gen(code, hc, hw_res); 74 } 75 76 static int hcd_claim(hc_device_t *hcd) 77 { 78 xhci_hc_t *hc = hcd_to_hc(hcd); 79 return hc_claim(hc, hcd->ddf_dev); 80 } 81 82 static int hcd_start(hc_device_t *hcd) 83 { 84 xhci_hc_t *hc = hcd_to_hc(hcd); 85 return hc_start(hc, hcd->irq_cap >= 0); 86 } 87 88 static int hcd_hc_gone(hc_device_t *hcd) 89 { 90 xhci_hc_t *hc = hcd_to_hc(hcd); 91 hc_fini(hc); 92 return EOK; 93 } 94 95 static const hc_driver_t xhci_driver = { 96 .name = NAME, 97 .hc_device_size = sizeof(xhci_hc_t), 98 99 .hc_add = hcd_hc_add, 61 100 .irq_code_gen = hcd_irq_code_gen, 62 101 .claim = hcd_claim, 63 102 .start = hcd_start, 64 .setup_root_hub = NULL, 65 .fini = hc_driver_fini, 66 .ops = { 67 .schedule = hcd_schedule, 68 .irq_hook = hcd_interrupt, 69 .status_hook = hcd_status, 70 } 103 .hc_gone = hcd_hc_gone, 71 104 }; 72 73 static int hc_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *hw_res, ddf_dev_t *device)74 {75 int err;76 77 xhci_hc_t *hc = malloc(sizeof(xhci_hc_t));78 if (!hc)79 return ENOMEM;80 81 if ((err = hc_init_mmio(hc, hw_res)))82 goto err;83 84 hc->hcd = hcd;85 86 if ((err = hc_init_memory(hc, device)))87 goto err;88 89 hcd_set_implementation(hcd, hc, &xhci_ddf_hc_driver.ops, &hc->bus.base);90 91 return EOK;92 err:93 free(hc);94 return err;95 }96 97 static int hcd_irq_code_gen(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)98 {99 xhci_hc_t *hc = hcd_get_driver_data(hcd);100 assert(hc);101 102 return hc_irq_code_gen(code, hc, hw_res);103 }104 105 static int hcd_claim(hcd_t *hcd, ddf_dev_t *dev)106 {107 xhci_hc_t *hc = hcd_get_driver_data(hcd);108 assert(hc);109 110 return hc_claim(hc, dev);111 }112 113 static int hcd_start(hcd_t *hcd, bool irq)114 {115 xhci_hc_t *hc = hcd_get_driver_data(hcd);116 assert(hc);117 118 return hc_start(hc, irq);119 }120 121 static int hcd_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)122 {123 xhci_hc_t *hc = hcd_get_driver_data(hcd);124 assert(hc);125 126 return hc_schedule(hc, batch);127 }128 129 static int hcd_status(hcd_t *hcd, uint32_t *status)130 {131 xhci_hc_t *hc = hcd_get_driver_data(hcd);132 assert(hc);133 assert(status);134 135 return hc_status(hc, status);136 }137 138 static void hcd_interrupt(hcd_t *hcd, uint32_t status)139 {140 xhci_hc_t *hc = hcd_get_driver_data(hcd);141 assert(hc);142 143 hc_interrupt(hc, status);144 }145 146 static void hc_driver_fini(hcd_t *hcd)147 {148 xhci_hc_t *hc = hcd_get_driver_data(hcd);149 assert(hc);150 151 hc_fini(hc);152 153 free(hc);154 }155 156 /** Initializes a new ddf driver instance of XHCI hcd.157 *158 * @param[in] device DDF instance of the device to initialize.159 * @return Error code.160 */161 static int xhci_dev_add(ddf_dev_t *device)162 {163 usb_log_info("Adding device %s", ddf_dev_get_name(device));164 return hcd_ddf_add_hc(device, &xhci_ddf_hc_driver);165 }166 167 static int xhci_fun_online(ddf_fun_t *fun)168 {169 return hcd_ddf_device_online(fun);170 }171 172 static int xhci_fun_offline(ddf_fun_t *fun)173 {174 return hcd_ddf_device_offline(fun);175 }176 177 178 static const driver_ops_t xhci_driver_ops = {179 .dev_add = xhci_dev_add,180 .fun_online = xhci_fun_online,181 .fun_offline = xhci_fun_offline182 };183 184 static const driver_t xhci_driver = {185 .name = NAME,186 .driver_ops = &xhci_driver_ops187 };188 189 105 190 106 /** Initializes global driver structures (NONE). … … 200 116 log_init(NAME); 201 117 logctl_set_log_level(NAME, LVL_DEBUG2); 202 return ddf_driver_main(&xhci_driver);118 return hc_driver_main(&xhci_driver); 203 119 } 204 120 -
uspace/drv/bus/usb/xhci/rh.c
r1ea0bbf r32fb6bce 94 94 xhci_bus_t *bus = &rh->hc->bus; 95 95 96 device_t *dev = hcd_ddf_ device_create(rh->hc_device, &bus->base);96 device_t *dev = hcd_ddf_fun_create(&rh->hc->base); 97 97 if (!dev) { 98 98 usb_log_error("Failed to create USB device function."); … … 132 132 133 133 err_usb_dev: 134 hcd_ddf_ device_destroy(dev);134 hcd_ddf_fun_destroy(dev); 135 135 return err; 136 136 }
Note:
See TracChangeset
for help on using the changeset viewer.
