Changes in uspace/drv/uhci-hcd/uhci.c [b375bb8:4abc304] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/uhci.c
rb375bb8 r4abc304 90 90 .interfaces[USBHC_DEV_IFACE] = &uhci_iface, 91 91 }; 92 /*----------------------------------------------------------------------------*/ 92 93 93 static int uhci_init_transfer_lists(uhci_t *instance); 94 94 static int uhci_init_mem_structures(uhci_t *instance); … … 115 115 } else (void) 0 116 116 117 /* Create UHCI function. */ 117 /* 118 * Create UHCI function. 119 */ 118 120 instance->ddf_instance = ddf_fun_create(dev, fun_exposed, "uhci"); 119 121 ret = (instance->ddf_instance == NULL) ? ENOMEM : EOK; 120 CHECK_RET_DEST_FUN_RETURN(ret, 121 "Failed to create UHCI device function.\n"); 122 CHECK_RET_DEST_FUN_RETURN(ret, "Failed to create UHCI device function.\n"); 122 123 123 124 instance->ddf_instance->ops = &uhci_ops; … … 125 126 126 127 ret = ddf_fun_bind(instance->ddf_instance); 127 CHECK_RET_DEST_FUN_RETURN(ret, 128 "Failed(%d) to bind UHCI device function: %s.\n", 128 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to bind UHCI device function: %s.\n", 129 129 ret, str_error(ret)); 130 130 … … 132 132 regs_t *io; 133 133 ret = pio_enable(regs, reg_size, (void**)&io); 134 CHECK_RET_DEST_FUN_RETURN(ret, 135 "Failed(%d) to gain access to registers at %p: %s.\n", 134 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to gain access to registers at %p: %s.\n", 136 135 ret, str_error(ret), io); 137 136 instance->registers = io; 138 usb_log_debug("Device registers at %p(%u) accessible.\n", 139 io, reg_size); 137 usb_log_debug("Device registers at %p(%u) accessible.\n", io, reg_size); 140 138 141 139 ret = uhci_init_mem_structures(instance); 142 CHECK_RET_DEST_FUN_RETURN(ret, 143 "Failed to initialize UHCI memory structures.\n"); 140 CHECK_RET_DEST_FUN_RETURN(ret, "Failed to initialize UHCI memory structures.\n"); 144 141 145 142 uhci_init_hw(instance); 146 instance->cleaner = 147 143 144 instance->cleaner = fibril_create(uhci_interrupt_emulator, instance); 148 145 fibril_add_ready(instance->cleaner); 149 146 … … 158 155 void uhci_init_hw(uhci_t *instance) 159 156 { 160 assert(instance);161 162 157 /* reset everything, who knows what touched it before us */ 163 158 pio_write_16(&instance->registers->usbcmd, UHCI_CMD_GLOBAL_RESET); … … 176 171 /* enable all interrupts, but resume interrupt */ 177 172 pio_write_16(&instance->registers->usbintr, 178 173 UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 179 174 180 175 /* Start the hc with large(64B) packet FSBR */ … … 205 200 interrupt_commands[1].addr = (void*)&instance->registers->usbsts; 206 201 instance->interrupt_code.cmdcount = 207 202 sizeof(uhci_cmds) / sizeof(irq_cmd_t); 208 203 } 209 204 … … 254 249 ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL"); 255 250 CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list."); 256 257 251 ret = transfer_list_init(&instance->transfers_control_full, "CONTROL_FULL"); 258 252 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list."); 259 260 253 ret = transfer_list_init(&instance->transfers_control_slow, "CONTROL_SLOW"); 261 254 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list."); 262 263 255 ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT"); 264 256 CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list."); … … 300 292 low_speed, batch->transfer_type, batch->max_packet_size)) { 301 293 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n", 302 294 low_speed ? "LOW" : "FULL" , batch->transfer_type, 303 295 batch->max_packet_size); 304 296 return ENOTSUP; … … 317 309 { 318 310 assert(instance); 311 // if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0) 312 // return; 313 // usb_log_debug2("UHCI interrupt: %X.\n", status); 319 314 transfer_list_remove_finished(&instance->transfers_interrupt); 320 315 transfer_list_remove_finished(&instance->transfers_control_slow); … … 345 340 uhci_t *instance = (uhci_t*)arg; 346 341 assert(instance); 347 348 #define QH(queue) \349 instance->transfers_##queue.queue_head350 351 342 while (1) { 352 343 const uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 353 344 const uint16_t sts = pio_read_16(&instance->registers->usbsts); 354 const uint16_t intr = 355 pio_read_16(&instance->registers->usbintr); 356 345 const uint16_t intr = pio_read_16(&instance->registers->usbintr); 357 346 if (((cmd & UHCI_CMD_RUN_STOP) != 1) || (sts != 0)) { 358 347 usb_log_debug2("Command: %X Status: %X Intr: %x\n", … … 364 353 if (frame_list != addr_to_phys(instance->frame_list)) { 365 354 usb_log_debug("Framelist address: %p vs. %p.\n", 366 frame_list, addr_to_phys(instance->frame_list)); 367 } 368 355 frame_list, addr_to_phys(instance->frame_list)); 356 } 369 357 int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff; 370 358 usb_log_debug2("Framelist item: %d \n", frnum ); 371 359 372 uintptr_t expected_pa = instance->frame_list[frnum] & (~0xf);373 uintptr_t real_pa = addr_to_phys(QH(interrupt)); 374 if ( expected_pa != real_pa) {360 queue_head_t* qh = instance->transfers_interrupt.queue_head; 361 362 if ((instance->frame_list[frnum] & (~0xf)) != (uintptr_t)addr_to_phys(qh)) { 375 363 usb_log_debug("Interrupt QH: %p vs. %p.\n", 376 expected_pa, real_pa); 377 } 378 379 expected_pa = QH(interrupt)->next_queue & (~0xf); 380 real_pa = addr_to_phys(QH(control_slow)); 381 if (expected_pa != real_pa) { 382 usb_log_debug("Control Slow QH: %p vs. %p.\n", 383 expected_pa, real_pa); 384 } 385 386 expected_pa = QH(control_slow)->next_queue & (~0xf); 387 real_pa = addr_to_phys(QH(control_full)); 388 if (expected_pa != real_pa) { 389 usb_log_debug("Control Full QH: %p vs. %p.\n", 390 expected_pa, real_pa); 391 } 392 393 expected_pa = QH(control_full)->next_queue & (~0xf); 394 real_pa = addr_to_phys(QH(bulk_full)); 395 if (expected_pa != real_pa ) { 396 usb_log_debug("Bulk QH: %p vs. %p.\n", 397 expected_pa, real_pa); 398 } 364 instance->frame_list[frnum] & (~0xf), addr_to_phys(qh)); 365 } 366 367 if ((qh->next_queue & (~0xf)) 368 != (uintptr_t)addr_to_phys(instance->transfers_control_slow.queue_head)) { 369 usb_log_debug("Control Slow QH: %p vs. %p.\n", qh->next_queue & (~0xf), 370 addr_to_phys(instance->transfers_control_slow.queue_head)); 371 } 372 qh = instance->transfers_control_slow.queue_head; 373 374 if ((qh->next_queue & (~0xf)) 375 != (uintptr_t)addr_to_phys(instance->transfers_control_full.queue_head)) { 376 usb_log_debug("Control Full QH: %p vs. %p.\n", qh->next_queue & (~0xf), 377 addr_to_phys(instance->transfers_control_full.queue_head));\ 378 } 379 qh = instance->transfers_control_full.queue_head; 380 381 if ((qh->next_queue & (~0xf)) 382 != (uintptr_t)addr_to_phys(instance->transfers_bulk_full.queue_head)) { 383 usb_log_debug("Bulk QH: %p vs. %p.\n", qh->next_queue & (~0xf), 384 addr_to_phys(instance->transfers_bulk_full.queue_head)); 385 } 386 /* 387 uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 388 cmd |= UHCI_CMD_RUN_STOP; 389 pio_write_16(&instance->registers->usbcmd, cmd); 390 */ 399 391 async_usleep(UHCI_DEBUGER_TIMEOUT); 400 392 } 401 393 return 0; 402 #undef QH403 394 } 404 395 /*----------------------------------------------------------------------------*/ 405 396 bool allowed_usb_packet( 406 397 bool low_speed, usb_transfer_type_t transfer, size_t size) 407 398 { 408 399 /* see USB specification chapter 5.5-5.8 for magic numbers used here */ 409 switch(transfer) 410 { 411 case USB_TRANSFER_ISOCHRONOUS: 412 return (!low_speed && size < 1024); 413 case USB_TRANSFER_INTERRUPT: 414 return size <= (low_speed ? 8 : 64); 415 case USB_TRANSFER_CONTROL: /* device specifies its own max size */ 416 return (size <= (low_speed ? 8 : 64)); 417 case USB_TRANSFER_BULK: /* device specifies its own max size */ 418 return (!low_speed && size <= 64); 400 switch(transfer) { 401 case USB_TRANSFER_ISOCHRONOUS: 402 return (!low_speed && size < 1024); 403 case USB_TRANSFER_INTERRUPT: 404 return size <= (low_speed ? 8 : 64); 405 case USB_TRANSFER_CONTROL: /* device specifies its own max size */ 406 return (size <= (low_speed ? 8 : 64)); 407 case USB_TRANSFER_BULK: /* device specifies its own max size */ 408 return (!low_speed && size <= 64); 419 409 } 420 410 return false;
Note:
See TracChangeset
for help on using the changeset viewer.