Changes in uspace/drv/bus/usb/uhci/hc.c [7de1988c:772a172] in mainline
- File:
-
- 1 edited
-
uspace/drv/bus/usb/uhci/hc.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/uhci/hc.c
r7de1988c r772a172 85 85 static int hc_init_mem_structures(hc_t *instance); 86 86 static int hc_init_transfer_lists(hc_t *instance); 87 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);88 87 89 88 static int hc_interrupt_emulator(void *arg); 90 89 static int hc_debug_checker(void *arg); 91 90 92 enum {93 /** Number of PIO ranges used in IRQ code */94 hc_irq_pio_range_count =95 sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t),96 97 /* Number of commands used in IRQ code */98 hc_irq_cmd_count =99 sizeof(uhci_irq_commands) / sizeof(irq_cmd_t)100 };101 91 102 92 /** Generate IRQ code. 103 * @param[out] ranges PIO ranges buffer. 104 * @param[in] ranges_size Size of the ranges buffer (bytes). 105 * @param[out] cmds Commands buffer. 106 * @param[in] cmds_size Size of the commands buffer (bytes). 93 * @param[out] code IRQ code structure. 107 94 * @param[in] regs Device's register range. 108 95 * 109 96 * @return Error code. 110 97 */ 111 int 112 hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[], 113 size_t cmds_size, addr_range_t *regs) 114 { 115 if ((ranges_size < sizeof(uhci_irq_pio_ranges)) || 116 (cmds_size < sizeof(uhci_irq_commands)) || 117 (RNGSZ(*regs) < sizeof(uhci_regs_t))) 98 int hc_gen_irq_code(irq_code_t *code, addr_range_t *regs) 99 { 100 assert(code); 101 102 if (RNGSZ(*regs) < sizeof(uhci_regs_t)) 118 103 return EOVERFLOW; 119 104 120 memcpy(ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges)); 121 ranges[0].base = RNGABS(*regs); 122 123 memcpy(cmds, uhci_irq_commands, sizeof(uhci_irq_commands)); 105 code->ranges = malloc(sizeof(uhci_irq_pio_ranges)); 106 if (code->ranges == NULL) 107 return ENOMEM; 108 109 code->cmds = malloc(sizeof(uhci_irq_commands)); 110 if (code->cmds == NULL) { 111 free(code->ranges); 112 return ENOMEM; 113 } 114 115 code->rangecount = ARRAY_SIZE(uhci_irq_pio_ranges); 116 code->cmdcount = ARRAY_SIZE(uhci_irq_commands); 117 118 memcpy(code->ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges)); 119 code->ranges[0].base = RNGABS(*regs); 120 121 memcpy(code->cmds, uhci_irq_commands, sizeof(uhci_irq_commands)); 124 122 uhci_regs_t *registers = (uhci_regs_t *) RNGABSPTR(*regs); 125 cmds[0].addr = ®isters->usbsts; 126 cmds[3].addr = ®isters->usbsts; 127 128 return EOK; 129 } 130 131 /** Register interrupt handler. 132 * 133 * @param[in] device Host controller DDF device 134 * @param[in] regs Register range 135 * @param[in] irq Interrupt number 136 * @paran[in] handler Interrupt handler 137 * 138 * @return EOK on success or negative error code 139 */ 140 int hc_register_irq_handler(ddf_dev_t *device, addr_range_t *regs, int irq, 141 interrupt_handler_t handler) 142 { 143 int rc; 144 irq_pio_range_t irq_ranges[hc_irq_pio_range_count]; 145 irq_cmd_t irq_cmds[hc_irq_cmd_count]; 146 rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds, 147 sizeof(irq_cmds), regs); 148 if (rc != EOK) { 149 usb_log_error("Failed to generate IRQ commands: %s.\n", 150 str_error(rc)); 151 return rc; 152 } 153 154 irq_code_t irq_code = { 155 .rangecount = hc_irq_pio_range_count, 156 .ranges = irq_ranges, 157 .cmdcount = hc_irq_cmd_count, 158 .cmds = irq_cmds 159 }; 160 161 /* Register handler to avoid interrupt lockup */ 162 rc = register_interrupt_handler(device, irq, handler, &irq_code); 163 if (rc != EOK) { 164 usb_log_error("Failed to register interrupt handler: %s.\n", 165 str_error(rc)); 166 return rc; 167 } 123 code->cmds[0].addr = (void*)®isters->usbsts; 124 code->cmds[3].addr = (void*)®isters->usbsts; 168 125 169 126 return EOK; … … 240 197 int hc_init(hc_t *instance, addr_range_t *regs, bool interrupts) 241 198 { 199 assert(instance); 200 assert(regs); 242 201 assert(regs->size >= sizeof(uhci_regs_t)); 243 int rc;244 202 245 203 instance->hw_interrupts = interrupts; … … 248 206 /* allow access to hc control registers */ 249 207 uhci_regs_t *io; 250 rc= pio_enable_range(regs, (void **) &io);251 if (r c!= EOK) {208 int ret = pio_enable_range(regs, (void **) &io); 209 if (ret != EOK) { 252 210 usb_log_error("Failed to gain access to registers at %p: %s.\n", 253 io, str_error(rc)); 254 return rc; 255 } 256 211 io, str_error(ret)); 212 return ret; 213 } 257 214 instance->registers = io; 215 258 216 usb_log_debug( 259 217 "Device registers at %p (%zuB) accessible.\n", io, regs->size); 260 218 261 rc = hc_init_mem_structures(instance); 262 if (rc != EOK) { 263 usb_log_error("Failed to initialize UHCI memory structures: %s.\n", 264 str_error(rc)); 265 return rc; 266 } 267 268 hcd_init(&instance->generic, USB_SPEED_FULL, 269 BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11); 270 271 instance->generic.private_data = instance; 272 instance->generic.schedule = hc_schedule; 273 instance->generic.ep_add_hook = NULL; 219 ret = hc_init_mem_structures(instance); 220 if (ret != EOK) { 221 usb_log_error("Failed to init UHCI memory structures: %s.\n", 222 str_error(ret)); 223 // TODO: we should disable pio here 224 return ret; 225 } 274 226 275 227 hc_init_hw(instance); … … 280 232 } 281 233 (void)hc_debug_checker; 234 235 uhci_rh_init(&instance->rh, instance->registers->ports, "uhci"); 282 236 283 237 return EOK; … … 440 394 { 441 395 assert(hcd); 442 hc_t *instance = hcd-> private_data;396 hc_t *instance = hcd->driver.data; 443 397 assert(instance); 444 398 assert(batch); 399 400 if (batch->ep->address == uhci_rh_get_address(&instance->rh)) 401 return uhci_rh_schedule(&instance->rh, batch); 402 445 403 uhci_transfer_batch_t *uhci_batch = uhci_transfer_batch_get(batch); 446 404 if (!uhci_batch) {
Note:
See TracChangeset
for help on using the changeset viewer.
