Changeset e50cd7f in mainline for uspace/drv/uhci-hcd/hc.c
- Timestamp:
- 2011-04-17T19:17:55Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63517c2, cfbbe1d3
- Parents:
- ef354b6 (diff), 8595577b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/hc.c
ref354b6 re50cd7f 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"); 241 228 242 ret = 243 usb_endpoint_manager_init(&instance->ep_manager, 244 BANDWIDTH_AVAILABLE_USB11); 229 ret = usb_endpoint_manager_init(&instance->ep_manager, 230 BANDWIDTH_AVAILABLE_USB11); 245 231 assert(ret == EOK); 246 232 … … 261 247 { 262 248 assert(instance); 263 #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); \ 264 252 if (ret != EOK) { \ 265 usb_log_error(message); \ 253 usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \ 254 ret, name, str_error(ret)); \ 266 255 transfer_list_fini(&instance->transfers_bulk_full); \ 267 256 transfer_list_fini(&instance->transfers_control_full); \ … … 269 258 transfer_list_fini(&instance->transfers_interrupt); \ 270 259 return ret; \ 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 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 */ 289 269 transfer_list_set_next(&instance->transfers_control_full, 290 270 &instance->transfers_bulk_full); … … 330 310 331 311 transfer_list_t *list = 332 instance->transfers[batch-> speed][batch->transfer_type];312 instance->transfers[batch->ep->speed][batch->ep->transfer_type]; 333 313 assert(list); 334 if (batch->transfer_type == USB_TRANSFER_CONTROL) {335 usb_device_keeper_use_control(336 &instance->manager, batch->target);337 }338 314 transfer_list_add_batch(list, batch); 339 315 … … 355 331 assert(instance); 356 332 // status |= 1; //Uncomment to work around qemu hang 357 /* TODO: Resume interrupts are not supported */358 333 /* Lower 2 bits are transaction error and transaction complete */ 359 if (status & 0x3) {334 if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) { 360 335 LIST_INITIALIZE(done); 361 336 transfer_list_remove_finished( … … 373 348 usb_transfer_batch_t *batch = 374 349 list_get_instance(item, usb_transfer_batch_t, link); 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) { 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)) { 402 357 usb_log_error("UHCI hardware failure!.\n"); 403 358 ++instance->hw_failures; … … 429 384 430 385 while (1) { 431 /* read and ack interrupts*/386 /* Readd and clear status register */ 432 387 uint16_t status = pio_read_16(&instance->registers->usbsts); 433 pio_write_16(&instance->registers->usbsts, 0x1f);388 pio_write_16(&instance->registers->usbsts, status); 434 389 if (status != 0) 435 390 usb_log_debug2("UHCI status: %x.\n", status); 436 391 hc_interrupt(instance, status); 437 async_usleep(UHCI_ CLEANER_TIMEOUT);392 async_usleep(UHCI_INT_EMULATOR_TIMEOUT); 438 393 } 439 394 return EOK; … … 506 461 #undef QH 507 462 } 508 /*----------------------------------------------------------------------------*/509 /** Check transfers for USB validity510 *511 * @param[in] low_speed Transfer speed.512 * @param[in] transfer Transer type513 * @param[in] size Size of data packets514 * @return True if transaction is allowed by USB specs, false otherwise515 */516 #if 0517 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 #endif535 463 /** 536 464 * @}
Note:
See TracChangeset
for help on using the changeset viewer.