Changes in uspace/drv/uhci-hcd/hc.c [27205841:391d55b] in mainline
- File:
-
- 1 edited
-
uspace/drv/uhci-hcd/hc.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/hc.c
r27205841 r391d55b 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"); 228 241 229 ret = usb_endpoint_manager_init(&instance->ep_manager, 230 BANDWIDTH_AVAILABLE_USB11); 242 ret = 243 usb_endpoint_manager_init(&instance->ep_manager, 244 BANDWIDTH_AVAILABLE_USB11); 231 245 assert(ret == EOK); 232 246 … … 247 261 { 248 262 assert(instance); 249 #define SETUP_TRANSFER_LIST(type, name) \ 250 do { \ 251 int ret = transfer_list_init(&instance->transfers_##type, name); \ 263 #define CHECK_RET_CLEAR_RETURN(ret, message...) \ 252 264 if (ret != EOK) { \ 253 usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \ 254 ret, name, str_error(ret)); \ 265 usb_log_error(message); \ 255 266 transfer_list_fini(&instance->transfers_bulk_full); \ 256 267 transfer_list_fini(&instance->transfers_control_full); \ … … 258 269 transfer_list_fini(&instance->transfers_interrupt); \ 259 270 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 */ 271 } else (void) 0 272 273 /* initialize TODO: check errors */ 274 int ret; 275 ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL"); 276 CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list."); 277 278 ret = transfer_list_init( 279 &instance->transfers_control_full, "CONTROL_FULL"); 280 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list."); 281 282 ret = transfer_list_init( 283 &instance->transfers_control_slow, "CONTROL_SLOW"); 284 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list."); 285 286 ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT"); 287 CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list."); 288 269 289 transfer_list_set_next(&instance->transfers_control_full, 270 290 &instance->transfers_bulk_full); … … 310 330 311 331 transfer_list_t *list = 312 instance->transfers[batch-> ep->speed][batch->ep->transfer_type];332 instance->transfers[batch->speed][batch->transfer_type]; 313 333 assert(list); 334 if (batch->transfer_type == USB_TRANSFER_CONTROL) { 335 usb_device_keeper_use_control( 336 &instance->manager, batch->target); 337 } 314 338 transfer_list_add_batch(list, batch); 315 339 … … 331 355 assert(instance); 332 356 // status |= 1; //Uncomment to work around qemu hang 357 /* TODO: Resume interrupts are not supported */ 333 358 /* Lower 2 bits are transaction error and transaction complete */ 334 if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {359 if (status & 0x3) { 335 360 LIST_INITIALIZE(done); 336 361 transfer_list_remove_finished( … … 348 373 usb_transfer_batch_t *batch = 349 374 list_get_instance(item, usb_transfer_batch_t, link); 350 usb_transfer_batch_finish(batch); 351 } 352 } 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 switch (batch->transfer_type) 376 { 377 case USB_TRANSFER_CONTROL: 378 usb_device_keeper_release_control( 379 &instance->manager, batch->target); 380 break; 381 case USB_TRANSFER_INTERRUPT: 382 case USB_TRANSFER_ISOCHRONOUS: { 383 /* 384 int ret = bandwidth_free(&instance->bandwidth, 385 batch->target.address, 386 batch->target.endpoint, 387 batch->direction); 388 if (ret != EOK) 389 usb_log_warning("Failed(%d) to free " 390 "reserved bw: %s.\n", ret, 391 str_error(ret)); 392 */ 393 } 394 default: 395 break; 396 } 397 batch->next_step(batch); 398 } 399 } 400 /* bits 4 and 5 indicate hc error */ 401 if (status & 0x18) { 357 402 usb_log_error("UHCI hardware failure!.\n"); 358 403 ++instance->hw_failures; … … 384 429 385 430 while (1) { 386 /* Readd and clear status register*/431 /* read and ack interrupts */ 387 432 uint16_t status = pio_read_16(&instance->registers->usbsts); 388 pio_write_16(&instance->registers->usbsts, status);433 pio_write_16(&instance->registers->usbsts, 0x1f); 389 434 if (status != 0) 390 435 usb_log_debug2("UHCI status: %x.\n", status); 391 436 hc_interrupt(instance, status); 392 async_usleep(UHCI_ INT_EMULATOR_TIMEOUT);437 async_usleep(UHCI_CLEANER_TIMEOUT); 393 438 } 394 439 return EOK; … … 461 506 #undef QH 462 507 } 508 /*----------------------------------------------------------------------------*/ 509 /** Check transfers for USB validity 510 * 511 * @param[in] low_speed Transfer speed. 512 * @param[in] transfer Transer type 513 * @param[in] size Size of data packets 514 * @return True if transaction is allowed by USB specs, false otherwise 515 */ 516 #if 0 517 bool usb_is_allowed( 518 bool low_speed, usb_transfer_type_t transfer, size_t size) 519 { 520 /* see USB specification chapter 5.5-5.8 for magic numbers used here */ 521 switch(transfer) 522 { 523 case USB_TRANSFER_ISOCHRONOUS: 524 return (!low_speed && size < 1024); 525 case USB_TRANSFER_INTERRUPT: 526 return size <= (low_speed ? 8 : 64); 527 case USB_TRANSFER_CONTROL: /* device specifies its own max size */ 528 return (size <= (low_speed ? 8 : 64)); 529 case USB_TRANSFER_BULK: /* device specifies its own max size */ 530 return (!low_speed && size <= 64); 531 } 532 return false; 533 } 534 #endif 463 535 /** 464 536 * @}
Note:
See TracChangeset
for help on using the changeset viewer.
