Changeset 78ab6d4 in mainline
- Timestamp:
- 2011-07-10T22:45:08Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4d62aa0
- Parents:
- 1f6eb7d
- Location:
- uspace/drv/bus/usb/ohci
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/hc.c
r1f6eb7d r78ab6d4 147 147 148 148 fibril_mutex_initialize(&instance->guard); 149 149 150 hc_gain_control(instance); 150 151 rh_init(&instance->rh, instance->registers);152 151 153 152 if (!interrupts) { … … 157 156 } 158 157 159 return EOK; 160 } 161 /*----------------------------------------------------------------------------*/ 158 rh_init(&instance->rh, instance->registers); 159 160 return EOK; 161 } 162 /*----------------------------------------------------------------------------*/ 163 /** Get number of commands used in IRQ code. 164 * @return Number of commands. 165 */ 162 166 size_t hc_irq_cmd_count(void) 163 167 { … … 165 169 } 166 170 /*----------------------------------------------------------------------------*/ 171 /** Generate IRQ code commands. 172 * @param[out] cmds Place to store the commands. 173 * @param[in] cmd_size Size of the place (bytes). 174 * @param[in] regs Physical address of device's registers. 175 * @param[in] reg_size Size of the register area (bytes). 176 * 177 * @return Error code. 178 */ 167 179 int hc_get_irq_commands( 168 180 irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size) … … 172 184 return EOVERFLOW; 173 185 174 /* Create register mapping to use in IRQ handler 175 * this mapping should be present in kernel only.186 /* Create register mapping to use in IRQ handler. 187 * This mapping should be present in kernel only. 176 188 * Remove it from here when kernel knows how to create mappings 177 189 * and accepts physical addresses in IRQ code. … … 181 193 182 194 /* Some bogus access to force create mapping. DO NOT remove, 183 * unless whole virtual addresses in irq is replaced */ 195 * unless whole virtual addresses in irq is replaced 196 * NOTE: Compiler won't remove this as ohci_regs_t members 197 * are declared volatile. */ 184 198 registers->revision; 185 199 … … 195 209 } 196 210 /*----------------------------------------------------------------------------*/ 197 /** Create and register endpoint structures 211 /** Create and register endpoint structures. 198 212 * 199 213 * @param[in] instance OHCI driver structure. … … 444 458 /** Turn off any (BIOS)driver that might be in control of the device. 445 459 * 460 * This function implements routines described in chapter 5.1.1.3 of the OHCI 461 * specification (page 40, pdf page 54). 462 * 446 463 * @param[in] instance OHCI hc driver structure. 447 464 */ … … 449 466 { 450 467 assert(instance); 468 451 469 usb_log_debug("Requesting OHCI control.\n"); 452 /* Turn off legacy emulation */ 453 volatile uint32_t *ohci_emulation_reg = 454 (uint32_t*)((char*)instance->registers + 0x100); 455 usb_log_debug("OHCI legacy register %p: %x.\n", 456 ohci_emulation_reg, *ohci_emulation_reg); 457 /* Do not change A20 state */ 458 *ohci_emulation_reg &= 0x100; 459 usb_log_debug("OHCI legacy register %p: %x.\n", 460 ohci_emulation_reg, *ohci_emulation_reg); 470 if (instance->registers->revision & R_LEGACY_FLAG) { 471 /* Turn off legacy emulation, it should be enough to zero 472 * the lowest bit, but it caused problems. Thus clear all 473 * except GateA20 (causes restart on some hw). 474 * See page 145 of the specs for details. 475 */ 476 volatile uint32_t *ohci_emulation_reg = 477 (uint32_t*)((char*)instance->registers + LEGACY_REGS_OFFSET); 478 usb_log_debug("OHCI legacy register %p: %x.\n", 479 ohci_emulation_reg, *ohci_emulation_reg); 480 /* Zero everything but A20State */ 481 *ohci_emulation_reg &= 0x100; 482 usb_log_debug( 483 "OHCI legacy register (should be 0 or 0x100) %p: %x.\n", 484 ohci_emulation_reg, *ohci_emulation_reg); 485 } 461 486 462 487 /* Interrupt routing enabled => smm driver is active */ … … 464 489 usb_log_debug("SMM driver: request ownership change.\n"); 465 490 instance->registers->command_status |= CS_OCR; 491 /* Hope that SMM actually knows its stuff or we can hang here */ 466 492 while (instance->registers->control & C_IR) { 467 493 async_usleep(1000); 468 494 } 469 495 usb_log_info("SMM driver: Ownership taken.\n"); 470 instance->registers->control &= (C_HCFS_RESET << C_HCFS_SHIFT);496 C_HCFS_SET(instance->registers->control, C_HCFS_RESET); 471 497 async_usleep(50000); 472 498 return; 473 499 } 474 500 475 const unsigned hc_status = 476 (instance->registers->control >> C_HCFS_SHIFT) & C_HCFS_MASK; 501 const unsigned hc_status = C_HCFS_GET(instance->registers->control); 477 502 /* Interrupt routing disabled && status != USB_RESET => BIOS active */ 478 503 if (hc_status != C_HCFS_RESET) { … … 482 507 return; 483 508 } 484 /* HC is suspended assert resume for 20ms */485 instance->registers->control &= (C_HCFS_RESUME << C_HCFS_SHIFT);509 /* HC is suspended assert resume for 20ms, */ 510 C_HCFS_SET(instance->registers->control, C_HCFS_RESUME); 486 511 async_usleep(20000); 487 512 usb_log_info("BIOS driver: HC resumed.\n"); … … 561 586 instance->registers->periodic_start, frame_length); 562 587 563 instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT);588 C_HCFS_SET(instance->registers->control, C_HCFS_OPERATIONAL); 564 589 usb_log_debug("OHCI HC up and running (ctl_reg=0x%x).\n", 565 590 instance->registers->control); -
uspace/drv/bus/usb/ohci/ohci_regs.h
r1f6eb7d r78ab6d4 36 36 #include <stdint.h> 37 37 38 #define LEGACY_REGS_OFFSET 0x100 39 38 40 /** OHCI memory mapped registers structure */ 39 41 typedef struct ohci_regs { 40 42 const volatile uint32_t revision; 43 #define R_REVISION_MASK (0x3f) 44 #define R_REVISION_SHIFT (0) 45 #define R_LEGACY_FLAG (0x80) 46 41 47 volatile uint32_t control; 42 48 #define C_CSBR_MASK (0x3) /* Control-bulk service ratio */ … … 58 64 #define C_HCFS_SUSPEND (0x3) 59 65 #define C_HCFS_SHIFT (6) 66 67 #define C_HCFS_GET(reg) \ 68 ((reg >> C_HCFS_SHIFT) & C_HCFS_MASK) 69 #define C_HCFS_SET(reg, hcfs_state) \ 70 do { \ 71 reg = (reg & ~(C_HCFS_MASK << C_HCFS_SHIFT)) \ 72 | ((hcfs_state & C_HCFS_MASK) << C_HCFS_SHIFT); \ 73 } while (0) 74 60 75 61 76 #define C_IR (1 << 8) /* Interrupt routing, make sure it's 0 */
Note:
See TracChangeset
for help on using the changeset viewer.