Changes in uspace/drv/uhci-hcd/hc.c [27205841:4c28d17] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/hc.c
r27205841 r4c28d17 66 66 static int hc_interrupt_emulator(void *arg); 67 67 static int hc_debug_checker(void *arg); 68 #if 0 69 static bool usb_is_allowed( 70 bool low_speed, usb_transfer_type_t transfer, size_t size); 71 #endif 68 72 /*----------------------------------------------------------------------------*/ 69 73 /** Initialize UHCI hcd driver structure … … 85 89 int ret; 86 90 87 #define CHECK_RET_ RETURN(ret, message...) \91 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \ 88 92 if (ret != EOK) { \ 89 93 usb_log_error(message); \ 94 if (instance->ddf_instance) \ 95 ddf_fun_destroy(instance->ddf_instance); \ 90 96 return ret; \ 91 97 } else (void) 0 … … 93 99 instance->hw_interrupts = interrupts; 94 100 instance->hw_failures = 0; 101 102 /* Setup UHCI function. */ 103 instance->ddf_instance = fun; 95 104 96 105 /* allow access to hc control registers */ 97 106 regs_t *io; 98 107 ret = pio_enable(regs, reg_size, (void**)&io); 99 CHECK_RET_ RETURN(ret,108 CHECK_RET_DEST_FUN_RETURN(ret, 100 109 "Failed(%d) to gain access to registers at %p: %s.\n", 101 ret, io, str_error(ret));110 ret, str_error(ret), io); 102 111 instance->registers = io; 103 112 usb_log_debug("Device registers at %p(%u) accessible.\n", … … 105 114 106 115 ret = hc_init_mem_structures(instance); 107 CHECK_RET_RETURN(ret, 108 "Failed(%d) to initialize UHCI memory structures: %s.\n", 109 ret, str_error(ret)); 116 CHECK_RET_DEST_FUN_RETURN(ret, 117 "Failed to initialize UHCI memory structures.\n"); 110 118 111 119 hc_init_hw(instance); 112 120 if (!interrupts) { 113 instance-> interrupt_emulator =121 instance->cleaner = 114 122 fibril_create(hc_interrupt_emulator, instance); 115 fibril_add_ready(instance->interrupt_emulator); 116 } 117 (void)hc_debug_checker; 123 fibril_add_ready(instance->cleaner); 124 } else { 125 /* TODO: enable interrupts here */ 126 } 127 128 instance->debug_checker = 129 fibril_create(hc_debug_checker, instance); 130 // fibril_add_ready(instance->debug_checker); 118 131 119 132 return EOK; … … 215 228 /* Set all frames to point to the first queue head */ 216 229 const uint32_t queue = 217 LINK_POINTER_QH(addr_to_phys(218 instance->transfers_interrupt.queue_head));230 instance->transfers_interrupt.queue_head_pa 231 | LINK_POINTER_QUEUE_HEAD_FLAG; 219 232 220 233 unsigned i = 0; … … 223 236 } 224 237 225 /* Init device keeper 238 /* Init device keeper*/ 226 239 usb_device_keeper_init(&instance->manager); 227 240 usb_log_debug("Initialized device manager.\n"); … … 247 260 { 248 261 assert(instance); 249 #define SETUP_TRANSFER_LIST(type, name) \ 250 do { \ 251 int ret = transfer_list_init(&instance->transfers_##type, name); \ 262 #define CHECK_RET_CLEAR_RETURN(ret, message...) \ 252 263 if (ret != EOK) { \ 253 usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \ 254 ret, name, str_error(ret)); \ 264 usb_log_error(message); \ 255 265 transfer_list_fini(&instance->transfers_bulk_full); \ 256 266 transfer_list_fini(&instance->transfers_control_full); \ … … 258 268 transfer_list_fini(&instance->transfers_interrupt); \ 259 269 return ret; \ 260 } \ 261 } while (0) 262 263 SETUP_TRANSFER_LIST(bulk_full, "BULK FULL"); 264 SETUP_TRANSFER_LIST(control_full, "CONTROL FULL"); 265 SETUP_TRANSFER_LIST(control_slow, "CONTROL LOW"); 266 SETUP_TRANSFER_LIST(interrupt, "INTERRUPT"); 267 #undef SETUP_TRANSFER_LIST 268 /* Connect lists into one schedule */ 270 } else (void) 0 271 272 /* initialize TODO: check errors */ 273 int ret; 274 ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL"); 275 CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list."); 276 277 ret = transfer_list_init( 278 &instance->transfers_control_full, "CONTROL_FULL"); 279 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list."); 280 281 ret = transfer_list_init( 282 &instance->transfers_control_slow, "CONTROL_SLOW"); 283 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list."); 284 285 ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT"); 286 CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list."); 287 269 288 transfer_list_set_next(&instance->transfers_control_full, 270 289 &instance->transfers_bulk_full); … … 310 329 311 330 transfer_list_t *list = 312 instance->transfers[batch-> ep->speed][batch->ep->transfer_type];331 instance->transfers[batch->speed][batch->transfer_type]; 313 332 assert(list); 314 333 transfer_list_add_batch(list, batch); … … 331 350 assert(instance); 332 351 // status |= 1; //Uncomment to work around qemu hang 352 /* TODO: Resume interrupts are not supported */ 333 353 /* Lower 2 bits are transaction error and transaction complete */ 334 if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {354 if (status & 0x3) { 335 355 LIST_INITIALIZE(done); 336 356 transfer_list_remove_finished( … … 351 371 } 352 372 } 353 /* Resume interrupts are not supported */ 354 355 /* Bits 4 and 5 indicate hc error */ 356 if (status & (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)) { 373 /* bits 4 and 5 indicate hc error */ 374 if (status & 0x18) { 357 375 usb_log_error("UHCI hardware failure!.\n"); 358 376 ++instance->hw_failures; … … 384 402 385 403 while (1) { 386 /* Readd and clear status register*/404 /* read and ack interrupts */ 387 405 uint16_t status = pio_read_16(&instance->registers->usbsts); 388 pio_write_16(&instance->registers->usbsts, status);406 pio_write_16(&instance->registers->usbsts, 0x1f); 389 407 if (status != 0) 390 408 usb_log_debug2("UHCI status: %x.\n", status); 391 409 hc_interrupt(instance, status); 392 async_usleep(UHCI_ INT_EMULATOR_TIMEOUT);410 async_usleep(UHCI_CLEANER_TIMEOUT); 393 411 } 394 412 return EOK; … … 461 479 #undef QH 462 480 } 481 /*----------------------------------------------------------------------------*/ 482 /** Check transfers for USB validity 483 * 484 * @param[in] low_speed Transfer speed. 485 * @param[in] transfer Transer type 486 * @param[in] size Size of data packets 487 * @return True if transaction is allowed by USB specs, false otherwise 488 */ 489 #if 0 490 bool usb_is_allowed( 491 bool low_speed, usb_transfer_type_t transfer, size_t size) 492 { 493 /* see USB specification chapter 5.5-5.8 for magic numbers used here */ 494 switch(transfer) 495 { 496 case USB_TRANSFER_ISOCHRONOUS: 497 return (!low_speed && size < 1024); 498 case USB_TRANSFER_INTERRUPT: 499 return size <= (low_speed ? 8 : 64); 500 case USB_TRANSFER_CONTROL: /* device specifies its own max size */ 501 return (size <= (low_speed ? 8 : 64)); 502 case USB_TRANSFER_BULK: /* device specifies its own max size */ 503 return (!low_speed && size <= 64); 504 } 505 return false; 506 } 507 #endif 463 508 /** 464 509 * @}
Note:
See TracChangeset
for help on using the changeset viewer.