Changes in uspace/drv/bus/usb/uhci/hc.c [7de1988c:e0d8b740] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/uhci/hc.c
r7de1988c re0d8b740 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 }; 91 92 /** Get number of PIO ranges used in IRQ code. 93 * @return Number of ranges. 94 */ 95 size_t hc_irq_pio_range_count(void) 96 { 97 return sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t); 98 } 99 100 /** Get number of commands used in IRQ code. 101 * @return Number of commands. 102 */ 103 size_t hc_irq_cmd_count(void) 104 { 105 return sizeof(uhci_irq_commands) / sizeof(irq_cmd_t); 106 } 101 107 102 108 /** Generate IRQ code. … … 105 111 * @param[out] cmds Commands buffer. 106 112 * @param[in] cmds_size Size of the commands buffer (bytes). 107 * @param[in] regs Device's register range. 113 * @param[in] regs Physical address of device's registers. 114 * @param[in] reg_size Size of the register area (bytes). 108 115 * 109 116 * @return Error code. … … 111 118 int 112 119 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)120 size_t cmds_size, uintptr_t regs, size_t reg_size) 114 121 { 115 122 if ((ranges_size < sizeof(uhci_irq_pio_ranges)) || 116 123 (cmds_size < sizeof(uhci_irq_commands)) || 117 ( RNGSZ(*regs)< sizeof(uhci_regs_t)))124 (reg_size < sizeof(uhci_regs_t))) 118 125 return EOVERFLOW; 119 126 120 127 memcpy(ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges)); 121 ranges[0].base = RNGABS(*regs);128 ranges[0].base = regs; 122 129 123 130 memcpy(cmds, uhci_irq_commands, sizeof(uhci_irq_commands)); 124 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 } 131 uhci_regs_t *registers = (uhci_regs_t *) regs; 132 cmds[0].addr = (void*)®isters->usbsts; 133 cmds[3].addr = (void*)®isters->usbsts; 168 134 169 135 return EOK; … … 230 196 * 231 197 * @param[in] instance Memory place to initialize. 232 * @param[in] regs Range of device's I/O control registers. 198 * @param[in] regs Address of I/O control registers. 199 * @param[in] reg_size Size of I/O control registers. 233 200 * @param[in] interrupts True if hw interrupts should be used. 234 201 * @return Error code. … … 238 205 * interrupt fibrils. 239 206 */ 240 int hc_init(hc_t *instance, addr_range_t *regs, bool interrupts) 241 { 242 assert(regs->size >= sizeof(uhci_regs_t)); 243 int rc; 207 int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interrupts) 208 { 209 assert(reg_size >= sizeof(uhci_regs_t)); 244 210 245 211 instance->hw_interrupts = interrupts; … … 248 214 /* allow access to hc control registers */ 249 215 uhci_regs_t *io; 250 rc = pio_enable_range(regs, (void **)&io);251 if (r c!= EOK) {216 int ret = pio_enable(regs, reg_size, (void **)&io); 217 if (ret != EOK) { 252 218 usb_log_error("Failed to gain access to registers at %p: %s.\n", 253 io, str_error(rc)); 254 return rc; 255 } 256 219 io, str_error(ret)); 220 return ret; 221 } 257 222 instance->registers = io; 223 258 224 usb_log_debug( 259 "Device registers at %p (%zuB) accessible.\n", io, regs->size); 260 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; 225 "Device registers at %p (%zuB) accessible.\n", io, reg_size); 226 227 ret = hc_init_mem_structures(instance); 228 if (ret != EOK) { 229 usb_log_error("Failed to init UHCI memory structures: %s.\n", 230 str_error(ret)); 231 // TODO: we should disable pio here 232 return ret; 233 } 274 234 275 235 hc_init_hw(instance); … … 280 240 } 281 241 (void)hc_debug_checker; 242 243 uhci_rh_init(&instance->rh, instance->registers->ports, "uhci"); 282 244 283 245 return EOK; … … 443 405 assert(instance); 444 406 assert(batch); 407 408 if (batch->ep->address == uhci_rh_get_address(&instance->rh)) 409 return uhci_rh_schedule(&instance->rh, batch); 410 445 411 uhci_transfer_batch_t *uhci_batch = uhci_transfer_batch_get(batch); 446 412 if (!uhci_batch) {
Note:
See TracChangeset
for help on using the changeset viewer.