Changeset b375bb8 in mainline
- Timestamp:
- 2011-03-01T22:58:58Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0e2fdcf
- Parents:
- 9ef0d6d
- Location:
- uspace/drv/uhci-hcd
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/main.c
r9ef0d6d rb375bb8 50 50 51 51 static int uhci_add_device(ddf_dev_t *device); 52 53 52 /*----------------------------------------------------------------------------*/ 54 53 static driver_ops_t uhci_driver_ops = { … … 99 98 "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret)); 100 99 101 // ret = pci_enable_interrupts(device); 102 // CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret); 100 #if 0 101 ret = pci_enable_interrupts(device); 102 if (ret != EOK) { 103 usb_log_warning( 104 "Failed(%d) to enable interrupts, fall back to polling.\n", 105 ret); 106 } 107 #endif 103 108 104 109 hcd = malloc(sizeof(uhci_t)); 105 110 ret = (hcd != NULL) ? EOK : ENOMEM; 106 CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to allocate memory for uhci hcd.\n",107 ret);111 CHECK_RET_FREE_HC_RETURN(ret, 112 "Failed(%d) to allocate memory for uhci hcd.\n", ret); 108 113 109 114 ret = uhci_init(hcd, device, (void*)io_reg_base, io_reg_size); … … 131 136 } 132 137 138 /* It does no harm if we register this on polling */ 133 139 ret = register_interrupt_handler(device, irq, irq_handler, 134 140 &hcd->interrupt_code); 135 CHECK_RET_FINI_FREE_RETURN(ret, "Failed(%d) to register interrupt handler.\n",136 ret);141 CHECK_RET_FINI_FREE_RETURN(ret, 142 "Failed(%d) to register interrupt handler.\n", ret); 137 143 138 144 ret = setup_root_hub(&rh, device); 139 CHECK_RET_FINI_FREE_RETURN(ret, "Failed(%d) to setup UHCI root hub.\n",140 ret);145 CHECK_RET_FINI_FREE_RETURN(ret, 146 "Failed(%d) to setup UHCI root hub.\n", ret); 141 147 rh->driver_data = hcd->ddf_instance; 142 148 143 149 ret = ddf_fun_bind(rh); 144 CHECK_RET_FINI_FREE_RETURN(ret, "Failed(%d) to register UHCI root hub.\n",145 ret);150 CHECK_RET_FINI_FREE_RETURN(ret, 151 "Failed(%d) to register UHCI root hub.\n", ret); 146 152 147 153 return EOK; -
uspace/drv/uhci-hcd/pci.c
r9ef0d6d rb375bb8 139 139 } 140 140 141 sysarg_t address = 0xc0; 141 /* See UHCI design guide for these values, 142 * write all WC bits in USB legacy register */ 143 sysarg_t address = 0xc0; 142 144 sysarg_t value = 0x8f00; 143 145 -
uspace/drv/uhci-hcd/uhci.c
r9ef0d6d rb375bb8 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 /* 118 * Create UHCI function. 119 */ 117 /* Create UHCI function. */ 120 118 instance->ddf_instance = ddf_fun_create(dev, fun_exposed, "uhci"); 121 119 ret = (instance->ddf_instance == NULL) ? ENOMEM : EOK; 122 CHECK_RET_DEST_FUN_RETURN(ret, "Failed to create UHCI device function.\n"); 120 CHECK_RET_DEST_FUN_RETURN(ret, 121 "Failed to create UHCI device function.\n"); 123 122 124 123 instance->ddf_instance->ops = &uhci_ops; … … 126 125 127 126 ret = ddf_fun_bind(instance->ddf_instance); 128 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to bind UHCI device function: %s.\n", 127 CHECK_RET_DEST_FUN_RETURN(ret, 128 "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, "Failed(%d) to gain access to registers at %p: %s.\n", 134 CHECK_RET_DEST_FUN_RETURN(ret, 135 "Failed(%d) to gain access to registers at %p: %s.\n", 135 136 ret, str_error(ret), io); 136 137 instance->registers = io; 137 usb_log_debug("Device registers at %p(%u) accessible.\n", io, reg_size); 138 usb_log_debug("Device registers at %p(%u) accessible.\n", 139 io, reg_size); 138 140 139 141 ret = uhci_init_mem_structures(instance); 140 CHECK_RET_DEST_FUN_RETURN(ret, "Failed to initialize UHCI memory structures.\n"); 142 CHECK_RET_DEST_FUN_RETURN(ret, 143 "Failed to initialize UHCI memory structures.\n"); 141 144 142 145 uhci_init_hw(instance); 143 144 instance->cleaner =fibril_create(uhci_interrupt_emulator, instance);146 instance->cleaner = 147 fibril_create(uhci_interrupt_emulator, instance); 145 148 fibril_add_ready(instance->cleaner); 146 149 … … 155 158 void uhci_init_hw(uhci_t *instance) 156 159 { 160 assert(instance); 161 157 162 /* reset everything, who knows what touched it before us */ 158 163 pio_write_16(&instance->registers->usbcmd, UHCI_CMD_GLOBAL_RESET); … … 171 176 /* enable all interrupts, but resume interrupt */ 172 177 pio_write_16(&instance->registers->usbintr, 173 178 UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 174 179 175 180 /* Start the hc with large(64B) packet FSBR */ … … 200 205 interrupt_commands[1].addr = (void*)&instance->registers->usbsts; 201 206 instance->interrupt_code.cmdcount = 202 207 sizeof(uhci_cmds) / sizeof(irq_cmd_t); 203 208 } 204 209 … … 249 254 ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL"); 250 255 CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list."); 256 251 257 ret = transfer_list_init(&instance->transfers_control_full, "CONTROL_FULL"); 252 258 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list."); 259 253 260 ret = transfer_list_init(&instance->transfers_control_slow, "CONTROL_SLOW"); 254 261 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list."); 262 255 263 ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT"); 256 264 CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list."); … … 292 300 low_speed, batch->transfer_type, batch->max_packet_size)) { 293 301 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n", 294 302 low_speed ? "LOW" : "FULL" , batch->transfer_type, 295 303 batch->max_packet_size); 296 304 return ENOTSUP; … … 309 317 { 310 318 assert(instance); 311 // if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)312 // return;313 // usb_log_debug2("UHCI interrupt: %X.\n", status);314 319 transfer_list_remove_finished(&instance->transfers_interrupt); 315 320 transfer_list_remove_finished(&instance->transfers_control_slow); … … 340 345 uhci_t *instance = (uhci_t*)arg; 341 346 assert(instance); 347 348 #define QH(queue) \ 349 instance->transfers_##queue.queue_head 350 342 351 while (1) { 343 352 const uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 344 353 const uint16_t sts = pio_read_16(&instance->registers->usbsts); 345 const uint16_t intr = pio_read_16(&instance->registers->usbintr); 354 const uint16_t intr = 355 pio_read_16(&instance->registers->usbintr); 356 346 357 if (((cmd & UHCI_CMD_RUN_STOP) != 1) || (sts != 0)) { 347 358 usb_log_debug2("Command: %X Status: %X Intr: %x\n", … … 353 364 if (frame_list != addr_to_phys(instance->frame_list)) { 354 365 usb_log_debug("Framelist address: %p vs. %p.\n", 355 frame_list, addr_to_phys(instance->frame_list)); 356 } 366 frame_list, addr_to_phys(instance->frame_list)); 367 } 368 357 369 int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff; 358 370 usb_log_debug2("Framelist item: %d \n", frnum ); 359 371 360 queue_head_t* qh = instance->transfers_interrupt.queue_head;361 362 if ( (instance->frame_list[frnum] & (~0xf)) != (uintptr_t)addr_to_phys(qh)) {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) { 363 375 usb_log_debug("Interrupt QH: %p vs. %p.\n", 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 */ 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 } 391 399 async_usleep(UHCI_DEBUGER_TIMEOUT); 392 400 } 393 401 return 0; 402 #undef QH 394 403 } 395 404 /*----------------------------------------------------------------------------*/ 396 405 bool allowed_usb_packet( 397 406 bool low_speed, usb_transfer_type_t transfer, size_t size) 398 407 { 399 408 /* see USB specification chapter 5.5-5.8 for magic numbers used here */ 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); 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); 409 419 } 410 420 return false;
Note:
See TracChangeset
for help on using the changeset viewer.