Changes in uspace/drv/uhci-hcd/hc.c [4c28d17:27205841] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/hc.c
r4c28d17 r27205841 66 66 static int hc_interrupt_emulator(void *arg); 67 67 static int hc_debug_checker(void *arg); 68 #if 069 static bool usb_is_allowed(70 bool low_speed, usb_transfer_type_t transfer, size_t size);71 #endif72 68 /*----------------------------------------------------------------------------*/ 73 69 /** Initialize UHCI hcd driver structure … … 89 85 int ret; 90 86 91 #define CHECK_RET_ DEST_FUN_RETURN(ret, message...) \87 #define CHECK_RET_RETURN(ret, message...) \ 92 88 if (ret != EOK) { \ 93 89 usb_log_error(message); \ 94 if (instance->ddf_instance) \95 ddf_fun_destroy(instance->ddf_instance); \96 90 return ret; \ 97 91 } else (void) 0 … … 99 93 instance->hw_interrupts = interrupts; 100 94 instance->hw_failures = 0; 101 102 /* Setup UHCI function. */103 instance->ddf_instance = fun;104 95 105 96 /* allow access to hc control registers */ 106 97 regs_t *io; 107 98 ret = pio_enable(regs, reg_size, (void**)&io); 108 CHECK_RET_ DEST_FUN_RETURN(ret,99 CHECK_RET_RETURN(ret, 109 100 "Failed(%d) to gain access to registers at %p: %s.\n", 110 ret, str_error(ret), io);101 ret, io, str_error(ret)); 111 102 instance->registers = io; 112 103 usb_log_debug("Device registers at %p(%u) accessible.\n", … … 114 105 115 106 ret = hc_init_mem_structures(instance); 116 CHECK_RET_DEST_FUN_RETURN(ret, 117 "Failed to initialize UHCI memory structures.\n"); 107 CHECK_RET_RETURN(ret, 108 "Failed(%d) to initialize UHCI memory structures: %s.\n", 109 ret, str_error(ret)); 118 110 119 111 hc_init_hw(instance); 120 112 if (!interrupts) { 121 instance-> cleaner =113 instance->interrupt_emulator = 122 114 fibril_create(hc_interrupt_emulator, instance); 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); 115 fibril_add_ready(instance->interrupt_emulator); 116 } 117 (void)hc_debug_checker; 131 118 132 119 return EOK; … … 228 215 /* Set all frames to point to the first queue head */ 229 216 const uint32_t queue = 230 instance->transfers_interrupt.queue_head_pa231 | LINK_POINTER_QUEUE_HEAD_FLAG;217 LINK_POINTER_QH(addr_to_phys( 218 instance->transfers_interrupt.queue_head)); 232 219 233 220 unsigned i = 0; … … 236 223 } 237 224 238 /* Init device keeper */225 /* Init device keeper */ 239 226 usb_device_keeper_init(&instance->manager); 240 227 usb_log_debug("Initialized device manager.\n"); … … 260 247 { 261 248 assert(instance); 262 #define CHECK_RET_CLEAR_RETURN(ret, message...) \ 249 #define SETUP_TRANSFER_LIST(type, name) \ 250 do { \ 251 int ret = transfer_list_init(&instance->transfers_##type, name); \ 263 252 if (ret != EOK) { \ 264 usb_log_error(message); \ 253 usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \ 254 ret, name, str_error(ret)); \ 265 255 transfer_list_fini(&instance->transfers_bulk_full); \ 266 256 transfer_list_fini(&instance->transfers_control_full); \ … … 268 258 transfer_list_fini(&instance->transfers_interrupt); \ 269 259 return ret; \ 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 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 */ 288 269 transfer_list_set_next(&instance->transfers_control_full, 289 270 &instance->transfers_bulk_full); … … 329 310 330 311 transfer_list_t *list = 331 instance->transfers[batch-> speed][batch->transfer_type];312 instance->transfers[batch->ep->speed][batch->ep->transfer_type]; 332 313 assert(list); 333 314 transfer_list_add_batch(list, batch); … … 350 331 assert(instance); 351 332 // status |= 1; //Uncomment to work around qemu hang 352 /* TODO: Resume interrupts are not supported */353 333 /* Lower 2 bits are transaction error and transaction complete */ 354 if (status & 0x3) {334 if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) { 355 335 LIST_INITIALIZE(done); 356 336 transfer_list_remove_finished( … … 371 351 } 372 352 } 373 /* bits 4 and 5 indicate hc error */ 374 if (status & 0x18) { 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)) { 375 357 usb_log_error("UHCI hardware failure!.\n"); 376 358 ++instance->hw_failures; … … 402 384 403 385 while (1) { 404 /* read and ack interrupts*/386 /* Readd and clear status register */ 405 387 uint16_t status = pio_read_16(&instance->registers->usbsts); 406 pio_write_16(&instance->registers->usbsts, 0x1f);388 pio_write_16(&instance->registers->usbsts, status); 407 389 if (status != 0) 408 390 usb_log_debug2("UHCI status: %x.\n", status); 409 391 hc_interrupt(instance, status); 410 async_usleep(UHCI_ CLEANER_TIMEOUT);392 async_usleep(UHCI_INT_EMULATOR_TIMEOUT); 411 393 } 412 394 return EOK; … … 479 461 #undef QH 480 462 } 481 /*----------------------------------------------------------------------------*/482 /** Check transfers for USB validity483 *484 * @param[in] low_speed Transfer speed.485 * @param[in] transfer Transer type486 * @param[in] size Size of data packets487 * @return True if transaction is allowed by USB specs, false otherwise488 */489 #if 0490 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 #endif508 463 /** 509 464 * @}
Note:
See TracChangeset
for help on using the changeset viewer.