Changeset 308a5d5 in mainline
- Timestamp:
- 2011-04-24T15:38:10Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 94c0dcbd
- Parents:
- 9b78020 (diff), 564a2b3 (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. - Location:
- uspace/drv
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
r9b78020 r308a5d5 217 217 instance->registers->rh_desc_a |= RHDA_NPS_FLAG; 218 218 instance->unfinished_interrupt_transfer = NULL; 219 instance->interrupt_buffer = malloc((instance->port_count + 8)/8); 219 220 usb_log_info("OHCI root hub with %d ports.\n", instance->port_count); 220 221 return EOK; … … 471 472 size_t * buffer_size) { 472 473 int bit_count = instance->port_count + 1; 473 (*buffer_size) = (bit_count / 8) + ((bit_count % 8 == 0) ? 0 : 1);474 475 (*buffer) = malloc(*buffer_size);474 (*buffer_size) = (bit_count+7 / 8); 475 476 (*buffer) = instance->interrupt_buffer;//malloc(*buffer_size); 476 477 uint8_t * bitmap = (uint8_t*) (*buffer); 477 478 uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16)) -
uspace/drv/ohci/root_hub.h
r9b78020 r308a5d5 56 56 /** interrupt transfer waiting for an actual interrupt to occur */ 57 57 usb_transfer_batch_t * unfinished_interrupt_transfer; 58 /** pre-allocated interrupt mask 59 * 60 * This is allocated when initializing instance, so that memory 61 * allocation is not needed when processing request. 62 */ 63 uint8_t * interrupt_buffer; 58 64 } rh_t; 59 65 -
uspace/drv/uhci-hcd/hc.c
r9b78020 r308a5d5 44 44 #include "hc.h" 45 45 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 /*----------------------------------------------------------------------------*/ 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 62 52 static int hc_init_transfer_lists(hc_t *instance); 63 53 static int hc_init_mem_structures(hc_t *instance); … … 151 141 /* Enable all interrupts, but resume interrupt */ 152 142 pio_write_16(&instance->registers->usbintr, 153 UHCI_INTR_ CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);143 UHCI_INTR_ALLOW_INTERRUPTS); 154 144 } 155 145 … … 177 167 { 178 168 assert(instance); 179 #define CHECK_RET_ DEST_CMDS_RETURN(ret, message...) \169 #define CHECK_RET_RETURN(ret, message...) \ 180 170 if (ret != EOK) { \ 181 171 usb_log_error(message); \ 182 if (instance->interrupt_code.cmds != NULL) \183 free(instance->interrupt_code.cmds); \184 172 return ret; \ 185 173 } else (void) 0 186 174 187 175 /* Init interrupt code */ 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 176 instance->interrupt_code.cmds = instance->interrupt_commands; 193 177 { 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); 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; 202 206 } 203 207 204 208 /* Init transfer lists */ 205 ret = hc_init_transfer_lists(instance);206 CHECK_RET_ DEST_CMDS_RETURN(ret, "Failed to init transfer lists.\n");209 int ret = hc_init_transfer_lists(instance); 210 CHECK_RET_RETURN(ret, "Failed to init transfer lists.\n"); 207 211 usb_log_debug("Initialized transfer lists.\n"); 208 212 … … 210 214 instance->frame_list = get_page(); 211 215 ret = instance ? EOK : ENOMEM; 212 CHECK_RET_ DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n");216 CHECK_RET_RETURN(ret, "Failed to get frame list page.\n"); 213 217 usb_log_debug("Initialized frame list at %p.\n", instance->frame_list); 214 218 215 219 /* Set all frames to point to the first queue head */ 216 const uint32_t queue = 217 LINK_POINTER_QH(addr_to_phys( 218 instance->transfers_interrupt.queue_head)); 220 const uint32_t queue = LINK_POINTER_QH( 221 addr_to_phys(instance->transfers_interrupt.queue_head)); 219 222 220 223 unsigned i = 0; … … 229 232 ret = usb_endpoint_manager_init(&instance->ep_manager, 230 233 BANDWIDTH_AVAILABLE_USB11); 231 assert(ret == EOK); 232 233 return EOK; 234 #undef CHECK_RET_DEST_CMDS_RETURN 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 235 239 } 236 240 /*----------------------------------------------------------------------------*/ … … 277 281 #ifdef FSBR 278 282 transfer_list_set_next(&instance->transfers_bulk_full, 279 283 &instance->transfers_control_full); 280 284 #endif 281 285 … … 330 334 { 331 335 assert(instance); 332 status |= 1; //Uncomment to work around qemu hang333 336 /* Lower 2 bits are transaction error and transaction complete */ 334 337 if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) { … … 352 355 } 353 356 /* Resume interrupts are not supported */ 357 if (status & UHCI_STATUS_RESUME) { 358 usb_log_error("Resume interrupt!\n"); 359 } 354 360 355 361 /* Bits 4 and 5 indicate hc error */ … … 380 386 { 381 387 usb_log_debug("Started interrupt emulator.\n"); 382 hc_t *instance = (hc_t*)arg;388 hc_t *instance = arg; 383 389 assert(instance); 384 390 385 391 while (1) { 386 /* Read dand clear status register */392 /* Read and clear status register */ 387 393 uint16_t status = pio_read_16(&instance->registers->usbsts); 388 394 pio_write_16(&instance->registers->usbsts, status); 389 395 if (status != 0) 390 396 usb_log_debug2("UHCI status: %x.\n", status); 397 // Qemu fails to report stalled communication 398 // see https://bugs.launchpad.net/qemu/+bug/757654 399 // This is a simple workaround to force queue processing every time 400 // status |= 1; 391 401 hc_interrupt(instance, status); 392 402 async_usleep(UHCI_INT_EMULATOR_TIMEOUT); … … 402 412 int hc_debug_checker(void *arg) 403 413 { 404 hc_t *instance = (hc_t*)arg;414 hc_t *instance = arg; 405 415 assert(instance); 406 416 -
uspace/drv/uhci-hcd/hc.h
r9b78020 r308a5d5 69 69 #define UHCI_STATUS_ERROR_INTERRUPT (1 << 1) 70 70 #define UHCI_STATUS_INTERRUPT (1 << 0) 71 #define UHCI_STATUS_NM_INTERRUPTS \ 72 (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR) 71 73 72 74 /** Interrupt enabled registers */ … … 91 93 #define UHCI_DEBUGER_TIMEOUT 5000000 92 94 #define UHCI_ALLOWED_HW_FAIL 5 95 #define UHCI_NEEDED_IRQ_COMMANDS 5 93 96 94 97 /* Main HC driver structure */ … … 119 122 /** Code to be executed in kernel interrupt handler */ 120 123 irq_code_t interrupt_code; 124 125 /** Commands that form interrupt code */ 126 irq_cmd_t interrupt_commands[UHCI_NEEDED_IRQ_COMMANDS]; 121 127 122 128 /** Fibril periodically checking status register*/ -
uspace/drv/uhci-hcd/pci.c
r9b78020 r308a5d5 146 146 * write all WC bits in USB legacy register */ 147 147 sysarg_t address = 0xc0; 148 sysarg_t value = 0x 8f00;148 sysarg_t value = 0xaf00; 149 149 150 150 int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE), -
uspace/drv/uhci-hcd/uhci-hcd.ma
r9b78020 r308a5d5 20 20 10 pci/ven=8086&dev=2938 21 21 10 pci/ven=8086&dev=2939 22 23 10 pci/ven=8086&dev=24c2 24 10 pci/ven=8086&dev=24c4 25 10 pci/ven=8086&dev=24c7 -
uspace/drv/usbhub/usbhub.c
r9b78020 r308a5d5 105 105 } 106 106 107 //usb_pipe_start_session(hub_info->control_pipe);108 107 //set hub configuration 109 108 opResult = usb_hub_set_configuration(hub_info); … … 122 121 return opResult; 123 122 } 124 //usb_pipe_end_session(hub_info->control_pipe);125 126 123 127 124 usb_log_debug("Creating 'hub' function in DDF.\n"); … … 176 173 leave: 177 174 /* FIXME: proper interval. */ 178 async_usleep(1000 * 1000 * 10);175 async_usleep(1000 * 250); 179 176 180 177 return true; … … 218 215 // get hub descriptor 219 216 usb_log_debug("creating serialized descriptor\n"); 220 //void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);221 217 uint8_t serialized_descriptor[USB_HUB_MAX_DESCRIPTOR_SIZE]; 222 218 usb_hub_descriptor_t * descriptor; … … 253 249 sizeof (usb_hub_port_t) * (hub_info->port_count + 1)); 254 250 size_t port; 255 for (port = 0; port < hub_info->port_count + 1; port++) {251 for (port = 0; port < hub_info->port_count + 1; ++port) { 256 252 usb_hub_port_init(&hub_info->ports[port]); 257 253 } 258 254 if(is_power_switched){ 259 255 usb_log_debug("is_power_switched\n"); 260 if(has_individual_port_powering){ 261 usb_log_debug("has_individual_port_powering\n"); 262 for (port = 0; port < hub_info->port_count; port++) { 263 opResult = usb_hub_set_port_feature(hub_info->control_pipe, 264 port+1, USB_HUB_FEATURE_PORT_POWER); 265 if (opResult != EOK) { 266 usb_log_error("cannot power on port %zu: %s.\n", 267 port+1, str_error(opResult)); 268 } 256 257 for (port = 1; port <= hub_info->port_count; ++port) { 258 usb_log_debug("powering port %d\n",port); 259 opResult = usb_hub_set_port_feature(hub_info->control_pipe, 260 port, USB_HUB_FEATURE_PORT_POWER); 261 if (opResult != EOK) { 262 usb_log_error("cannot power on port %zu: %s.\n", 263 port, str_error(opResult)); 269 264 } 270 }else{ 265 } 266 if(!has_individual_port_powering){ 271 267 usb_log_debug("!has_individual_port_powering\n"); 272 268 opResult = usb_hub_set_feature(hub_info->control_pipe, … … 281 277 } 282 278 usb_log_debug2("freeing data\n"); 283 //free(serialized_descriptor);284 //free(descriptor->devices_removable);285 279 free(descriptor); 286 280 return EOK; … … 415 409 usb_hub_status_t status) { 416 410 int opResult; 417 if ( usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) {411 if (!usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) { 418 412 //restart power on hub 419 413 opResult = usb_hub_set_feature(hub_info->control_pipe, … … 425 419 } else {//power reestablished on hub- restart ports 426 420 size_t port; 427 for (port = 0; port <hub_info->port_count; ++port) {421 for (port = 1; port <= hub_info->port_count; ++port) { 428 422 opResult = usb_hub_set_port_feature( 429 423 hub_info->control_pipe, … … 434 428 } 435 429 } 430 opResult = usb_hub_clear_feature(hub_info->control_pipe, 431 USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 432 if (opResult != EOK) { 433 usb_log_error("cannnot clear hub power change flag: " 434 "%d\n", 435 opResult); 436 } 436 437 } 437 438 return opResult;
Note:
See TracChangeset
for help on using the changeset viewer.