Changeset 32fb6bce in mainline for uspace/drv/bus/usb/uhci
- 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/uhci
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
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 /**
Note:
See TracChangeset
for help on using the changeset viewer.
