Changeset 91ca111 in mainline for uspace/drv/bus/usb/xhci/hc.c
- Timestamp:
- 2017-06-23T11:18:50Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 51b2693
- Parents:
- e4d7363
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/hc.c
re4d7363 r91ca111 69 69 }; 70 70 71 /** 72 * Default USB Speed ID mapping: Table 157 73 */ 74 #define PSI_TO_BPS(psie, psim) (((uint64_t) psim) << (10 * psie)) 75 #define PORT_SPEED(psie, psim) { \ 76 .rx_bps = PSI_TO_BPS(psie, psim), \ 77 .tx_bps = PSI_TO_BPS(psie, psim) \ 78 } 79 static const xhci_port_speed_t ps_default_full = PORT_SPEED(2, 12); 80 static const xhci_port_speed_t ps_default_low = PORT_SPEED(1, 1500); 81 static const xhci_port_speed_t ps_default_high = PORT_SPEED(2, 480); 82 static const xhci_port_speed_t ps_default_super = PORT_SPEED(3, 5); 83 84 /** 85 * Walk the list of extended capabilities. 86 */ 87 static int hc_parse_ec(xhci_hc_t *hc) 88 { 89 unsigned psic, major; 90 91 for (xhci_extcap_t *ec = hc->xecp; ec; ec = xhci_extcap_next(ec)) { 92 xhci_dump_extcap(ec); 93 switch (XHCI_REG_RD(ec, XHCI_EC_CAP_ID)) { 94 case XHCI_EC_USB_LEGACY: 95 assert(hc->legsup == NULL); 96 hc->legsup = (xhci_legsup_t *) ec; 97 break; 98 case XHCI_EC_SUPPORTED_PROTOCOL: 99 psic = XHCI_REG_RD(ec, XHCI_EC_SP_PSIC); 100 major = XHCI_REG_RD(ec, XHCI_EC_SP_MAJOR); 101 102 // "Implied" speed 103 if (psic == 0) { 104 /* 105 * According to section 7.2.2.1.2, only USB 2.0 106 * and USB 3.0 can have psic == 0. So we 107 * blindly assume the name == "USB " and minor 108 * == 0. 109 */ 110 if (major == 2) { 111 hc->speeds[1] = ps_default_full; 112 hc->speeds[2] = ps_default_low; 113 hc->speeds[3] = ps_default_high; 114 } else if (major == 3) { 115 hc->speeds[4] = ps_default_super; 116 } else { 117 return EINVAL; 118 } 119 120 usb_log_debug2("Implied speed of USB %u set up.", major); 121 } else { 122 for (unsigned i = 0; i < psic; i++) { 123 xhci_psi_t *psi = xhci_extcap_psi(ec, i); 124 unsigned sim = XHCI_REG_RD(psi, XHCI_PSI_PSIM); 125 unsigned psiv = XHCI_REG_RD(psi, XHCI_PSI_PSIV); 126 unsigned psie = XHCI_REG_RD(psi, XHCI_PSI_PSIE); 127 unsigned psim = XHCI_REG_RD(psi, XHCI_PSI_PSIM); 128 129 uint64_t bps = PSI_TO_BPS(psie, psim); 130 131 if (sim == XHCI_PSI_PLT_SYMM || sim == XHCI_PSI_PLT_RX) 132 hc->speeds[psiv].rx_bps = bps; 133 if (sim == XHCI_PSI_PLT_SYMM || sim == XHCI_PSI_PLT_TX) { 134 hc->speeds[psiv].tx_bps = bps; 135 usb_log_debug2("Speed %u set up for bps %" PRIu64 " / %" PRIu64 ".", psiv, hc->speeds[psiv].rx_bps, hc->speeds[psiv].tx_bps); 136 } 137 } 138 } 139 } 140 } 141 return EOK; 142 } 143 71 144 int hc_init_mmio(xhci_hc_t *hc, const hw_res_list_parsed_t *hw_res) 72 145 { … … 90 163 return err; 91 164 165 hc->base = base; 92 166 hc->cap_regs = (xhci_cap_regs_t *) base; 93 167 hc->op_regs = (xhci_op_regs_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_LENGTH)); 94 168 hc->rt_regs = (xhci_rt_regs_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_RTSOFF)); 95 169 hc->db_arry = (xhci_doorbell_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_DBOFF)); 170 171 uintptr_t xec_offset = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_XECP) * sizeof(xhci_dword_t); 172 if (xec_offset > 0) 173 hc->xecp = (xhci_extcap_t *) (base + xec_offset); 96 174 97 175 usb_log_debug2("Initialized MMIO reg areas:"); … … 105 183 hc->ac64 = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_AC64); 106 184 hc->max_slots = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_SLOTS); 185 186 if ((err = hc_parse_ec(hc))) { 187 pio_disable(hc->base, RNGSZ(hc->mmio_range)); 188 return err; 189 } 107 190 108 191 return EOK; … … 151 234 } 152 235 153 addr_range_t mmio_range = hw_res->mem_ranges.ranges[0];154 155 236 code->ranges = malloc(sizeof(irq_pio_range_t)); 156 237 if (code->ranges == NULL) … … 165 246 code->rangecount = 1; 166 247 code->ranges[0] = (irq_pio_range_t) { 167 .base = RNGABS( mmio_range),168 .size = RNGSZ( mmio_range),248 .base = RNGABS(hc->mmio_range), 249 .size = RNGSZ(hc->mmio_range), 169 250 }; 170 251 … … 172 253 memcpy(code->cmds, irq_commands, sizeof(irq_commands)); 173 254 174 void *intr0_iman = RNGABSPTR( mmio_range) + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_RTSOFF) + offsetof(xhci_rt_regs_t, ir[0]);255 void *intr0_iman = RNGABSPTR(hc->mmio_range) + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_RTSOFF) + offsetof(xhci_rt_regs_t, ir[0]); 175 256 code->cmds[0].addr = intr0_iman; 176 257 code->cmds[3].addr = intr0_iman; … … 182 263 int hc_claim(xhci_hc_t *hc, ddf_dev_t *dev) 183 264 { 184 // TODO: impl 185 return EOK; 265 /* No legacy support capability, the controller is solely for us */ 266 if (!hc->legsup) 267 return EOK; 268 269 /* 270 * TODO: Implement handoff from BIOS, section 4.22.1 271 * QEMU does not support this, so we have to test on real HW. 272 */ 273 return ENOTSUP; 186 274 } 187 275 … … 346 434 xhci_trb_ring_fini(&hc->command_ring); 347 435 xhci_event_ring_fini(&hc->event_ring); 436 pio_disable(hc->base, RNGSZ(hc->mmio_range)); 348 437 usb_log_info("HC(%p): Finalized.", hc); 349 438 }
Note:
See TracChangeset
for help on using the changeset viewer.