Changes in uspace/drv/uhci-hcd/hc.c [8986412:4125b7d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/hc.c
r8986412 r4125b7d 44 44 #include "hc.h" 45 45 46 #define UHCI_INTR_ALLOW_INTERRUPTS \ 47 (UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET) 48 #define UHCI_STATUS_USED_INTERRUPTS \ 49 (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT) 50 51 46 static irq_cmd_t uhci_cmds[] = { 47 { 48 .cmd = CMD_PIO_READ_16, 49 .addr = NULL, /* patched for every instance */ 50 .dstarg = 1 51 }, 52 { 53 .cmd = CMD_PIO_WRITE_16, 54 .addr = NULL, /* pathed for every instance */ 55 .value = 0x1f 56 }, 57 { 58 .cmd = CMD_ACCEPT 59 } 60 }; 61 /*----------------------------------------------------------------------------*/ 52 62 static int hc_init_transfer_lists(hc_t *instance); 53 63 static int hc_init_mem_structures(hc_t *instance); … … 141 151 /* Enable all interrupts, but resume interrupt */ 142 152 pio_write_16(&instance->registers->usbintr, 143 UHCI_INTR_ ALLOW_INTERRUPTS);153 UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 144 154 } 145 155 … … 167 177 { 168 178 assert(instance); 169 #define CHECK_RET_ RETURN(ret, message...) \179 #define CHECK_RET_DEST_CMDS_RETURN(ret, message...) \ 170 180 if (ret != EOK) { \ 171 181 usb_log_error(message); \ 182 if (instance->interrupt_code.cmds != NULL) \ 183 free(instance->interrupt_code.cmds); \ 172 184 return ret; \ 173 185 } else (void) 0 174 186 175 187 /* Init interrupt code */ 176 instance->interrupt_code.cmds = instance->interrupt_commands; 188 instance->interrupt_code.cmds = malloc(sizeof(uhci_cmds)); 189 int ret = (instance->interrupt_code.cmds == NULL) ? ENOMEM : EOK; 190 CHECK_RET_DEST_CMDS_RETURN(ret, 191 "Failed to allocate interrupt cmds space.\n"); 192 177 193 { 178 /* Read status register */ 179 instance->interrupt_commands[0].cmd = CMD_PIO_READ_16; 180 instance->interrupt_commands[0].dstarg = 1; 181 instance->interrupt_commands[0].addr = 182 &instance->registers->usbsts; 183 184 /* Test whether we are the interrupt cause */ 185 instance->interrupt_commands[1].cmd = CMD_BTEST; 186 instance->interrupt_commands[1].value = 187 UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_INTERRUPTS; 188 instance->interrupt_commands[1].srcarg = 1; 189 instance->interrupt_commands[1].dstarg = 2; 190 191 /* Predicate cleaning and accepting */ 192 instance->interrupt_commands[2].cmd = CMD_PREDICATE; 193 instance->interrupt_commands[2].value = 2; 194 instance->interrupt_commands[2].srcarg = 2; 195 196 /* Write clean status register */ 197 instance->interrupt_commands[3].cmd = CMD_PIO_WRITE_A_16; 198 instance->interrupt_commands[3].srcarg = 1; 199 instance->interrupt_commands[3].addr = 200 &instance->registers->usbsts; 201 202 /* Accept interrupt */ 203 instance->interrupt_commands[4].cmd = CMD_ACCEPT; 204 205 instance->interrupt_code.cmdcount = UHCI_NEEDED_IRQ_COMMANDS; 194 irq_cmd_t *interrupt_commands = instance->interrupt_code.cmds; 195 memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds)); 196 interrupt_commands[0].addr = 197 (void*)&instance->registers->usbsts; 198 interrupt_commands[1].addr = 199 (void*)&instance->registers->usbsts; 200 instance->interrupt_code.cmdcount = 201 sizeof(uhci_cmds) / sizeof(irq_cmd_t); 206 202 } 207 203 208 204 /* Init transfer lists */ 209 intret = hc_init_transfer_lists(instance);210 CHECK_RET_ RETURN(ret, "Failed to init transfer lists.\n");205 ret = hc_init_transfer_lists(instance); 206 CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to init transfer lists.\n"); 211 207 usb_log_debug("Initialized transfer lists.\n"); 212 208 … … 214 210 instance->frame_list = get_page(); 215 211 ret = instance ? EOK : ENOMEM; 216 CHECK_RET_ RETURN(ret, "Failed to get frame list page.\n");212 CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n"); 217 213 usb_log_debug("Initialized frame list at %p.\n", instance->frame_list); 218 214 219 215 /* Set all frames to point to the first queue head */ 220 const uint32_t queue = LINK_POINTER_QH( 221 addr_to_phys(instance->transfers_interrupt.queue_head)); 216 const uint32_t queue = 217 LINK_POINTER_QH(addr_to_phys( 218 instance->transfers_interrupt.queue_head)); 222 219 223 220 unsigned i = 0; … … 232 229 ret = usb_endpoint_manager_init(&instance->ep_manager, 233 230 BANDWIDTH_AVAILABLE_USB11); 234 CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n", 235 str_error(ret)); 236 237 return EOK; 238 #undef CHECK_RET_RETURN 231 assert(ret == EOK); 232 233 return EOK; 234 #undef CHECK_RET_DEST_CMDS_RETURN 239 235 } 240 236 /*----------------------------------------------------------------------------*/ … … 281 277 #ifdef FSBR 282 278 transfer_list_set_next(&instance->transfers_bulk_full, 283 279 &instance->transfers_control_full); 284 280 #endif 285 281 … … 334 330 { 335 331 assert(instance); 332 // status |= 1; //Uncomment to work around qemu hang 336 333 /* Lower 2 bits are transaction error and transaction complete */ 337 334 if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) { … … 355 352 } 356 353 /* Resume interrupts are not supported */ 357 if (status & UHCI_STATUS_RESUME) {358 usb_log_error("Resume interrupt!\n");359 }360 354 361 355 /* Bits 4 and 5 indicate hc error */ … … 386 380 { 387 381 usb_log_debug("Started interrupt emulator.\n"); 388 hc_t *instance = arg;382 hc_t *instance = (hc_t*)arg; 389 383 assert(instance); 390 384 391 385 while (1) { 392 /* Read and clear status register */386 /* Readd and clear status register */ 393 387 uint16_t status = pio_read_16(&instance->registers->usbsts); 394 388 pio_write_16(&instance->registers->usbsts, status); 395 389 if (status != 0) 396 390 usb_log_debug2("UHCI status: %x.\n", status); 397 // Qemu fails to report stalled communication398 // see https://bugs.launchpad.net/qemu/+bug/757654399 // This is a simple workaround to force queue processing every time400 // status |= 1;401 391 hc_interrupt(instance, status); 402 392 async_usleep(UHCI_INT_EMULATOR_TIMEOUT); … … 412 402 int hc_debug_checker(void *arg) 413 403 { 414 hc_t *instance = arg;404 hc_t *instance = (hc_t*)arg; 415 405 assert(instance); 416 406
Note:
See TracChangeset
for help on using the changeset viewer.