Changeset 2be477d5 in mainline
- Timestamp:
- 2014-01-19T06:26:14Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bd41b192
- Parents:
- 4ee5272
- Location:
- uspace/drv/bus/usb/ehci
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/ehci_regs.h
r4ee5272 r2be477d5 42 42 #define EHCI_RD(reg) uint32_t_le2host(pio_read_32(&(reg))) 43 43 #define EHCI_RD8(reg) pio_read_8(&(reg)) 44 //#define EHCI_SET(reg, val) reg |= host2uint32_t_le(val)45 //#define EHCI_CLR(reg, val) reg &= host2uint32_t_le(~val)44 #define EHCI_SET(reg, val) pio_set_32(&(reg), host2uint32_t_le(val), 0) 45 #define EHCI_CLR(reg, val) pio_clear_32(&(reg), host2uint32_t_le(val), 0) 46 46 47 47 /** EHCI memory mapped capability registers structure */ … … 135 135 #define USB_PORTSC_WKDSCNNT_E_FLAG (1 << 21) 136 136 #define USB_PORTSC_WKCNNT_E_FLAG (1 << 20) 137 #define USB_PORTSC_PORT_TEST_MASK 0xf 138 #define USB_PORTSC_PORT_TEST_SHIFT 16 139 #define USB_PORTSC_NO_TEST 0x0 140 #define USB_PORTSC_TEST_J_STATE 0x1 141 #define USB_PORTSC_TEST_K_STATE 0x2 142 #define USB_PORTSC_TEST_SE0_NAK 0x3 143 #define USB_PORTSC_TEST_PACKET 0x4 144 #define USB_PORTSC_TEST_FORCE_ENABLE 0x5 145 #define USB_PORTSC_INDICATOR_MASK 0x3 146 #define USB_PORTSC_INDICATOR_SHIFT 14 147 #define USB_PORTSC_INDICATOR_OFF 0x0 148 #define USB_PORTSC_INDICATOR_AMBER 0x1 149 #define USB_PORTSC_INDICATOR_GREEN 0x2 137 #define USB_PORTSC_PORT_TEST_MASK (0xf << 16) 138 #define USB_PORTSC_NO_TEST (0x0 << 16) 139 #define USB_PORTSC_TEST_J_STATE (0x1 << 16) 140 #define USB_PORTSC_TEST_K_STATE (0x2 << 16) 141 #define USB_PORTSC_TEST_SE0_NAK (0x3 << 16) 142 #define USB_PORTSC_TEST_PACKET (0x4 << 16) 143 #define USB_PORTSC_TEST_FORCE_ENABLE (0x5 << 16) 144 #define USB_PORTSC_INDICATOR_MASK (0x3 << 14) 145 #define USB_PORTSC_INDICATOR_OFF (0x0 << 14) 146 #define USB_PORTSC_INDICATOR_AMBER (0x1 << 14) 147 #define USB_PORTSC_INDICATOR_GREEN (0x2 << 14) 150 148 #define USB_PORTSC_PORT_OWNER_FLAG (1 << 13) 151 149 #define USB_PORTSC_PORT_POWER_FLAG (1 << 12) 152 #define USB_PORTSC_LINE_STATUS_MASK 0x3 153 #define USB_PORTSC_LINE_STATUS_SHIFT 10 154 #define USB_PORTSC_LINE_STATUS_SE0 0x0 155 #define USB_PORTSC_LINE_STATUS_K 0x1 156 #define USB_PORTSC_LINE_STATUS_J 0x2 150 #define USB_PORTSC_LINE_STATUS_MASK (0x3 << 10) 151 #define USB_PORTSC_LINE_STATUS_SE0 (0x0 << 10) 152 #define USB_PORTSC_LINE_STATUS_K (0x1 << 10) 153 #define USB_PORTSC_LINE_STATUS_J (0x2 << 10) 157 154 #define USB_PORTSC_PORT_RESET_FLAG (1 << 8) 158 155 #define USB_PORTSC_SUSPEND_FLAG (1 << 7) … … 164 161 #define USB_PORTSC_CONNECT_CH_FLAG (1 << 1) 165 162 #define USB_PORTSC_CONNECT_FLAG (1 << 0) 163 164 #define USB_PORTSC_WC_MASK \ 165 (USB_PORTSC_CONNECT_CH_FLAG | USB_PORTSC_EN_CHANGE_FLAG | USB_PORTSC_OC_CHANGE_FLAG) 166 166 } ehci_regs_t; 167 167 -
uspace/drv/bus/usb/ehci/ehci_rh.c
r4ee5272 r2be477d5 116 116 ehci_rh_hub_desc_init(instance, EHCI_RD(caps->hcsparams)); 117 117 instance->unfinished_interrupt_transfer = NULL; 118 118 119 return virthub_base_init(&instance->base, name, &ops, instance, 119 120 NULL, &instance->hub_descriptor.header, HUB_STATUS_CHANGE_PIPE); … … 206 207 if (uint16_usb2host(setup_packet->length) != 4) 207 208 return ESTALL; 209 /* ECHI RH does not report global OC, and local power is always good */ 208 210 const uint32_t val = 0; 209 //TODO: implement210 211 memcpy(data, &val, sizeof(val)); 211 212 *act_size = sizeof(val); … … 231 232 * Chapter 11.16.2 specifies that only C_HUB_LOCAL_POWER and 232 233 * C_HUB_OVER_CURRENT are supported. 233 * C_HUB_LOCAL_POWER is not supported 234 * because root hubs do not support local power status feature. 235 * C_HUB_OVER_CURRENT is represented by EHCI RHS_OCIC_FLAG. 236 * (EHCI pg. 127) 234 * C_HUB_LOCAL_POWER is not supported because root hubs do not support 235 * local power status feature. 236 * EHCI RH does not report global OC condition either 237 237 */ 238 const unsigned feature = uint16_usb2host(setup_packet->value); 239 if (feature == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) { 240 //TODO: Implement 241 // EHCI_WR(hub->registers->rh_status, RHS_OCIC_FLAG); 242 } 243 return EOK; 238 return ESTALL; 244 239 } 245 240 … … 262 257 return EINVAL; 263 258 264 const uint32_t status = 0; 265 // TODO: Implement 266 //EHCI_RD(hub->registers->rh_port_status[port]); 259 const uint32_t reg = EHCI_RD(hub->registers->portsc[port]); 260 const uint32_t status = uint32_host2usb(0 | 261 (reg & USB_PORTSC_CONNECT_FLAG) ? (1 << 0) : 0 | 262 (reg & USB_PORTSC_ENABLED_FLAG) ? (1 << 1) : 0 | 263 (reg & USB_PORTSC_SUSPEND_FLAG) ? (1 << 2) : 0 | 264 (reg & USB_PORTSC_OC_ACTIVE_FLAG) ? (1 << 3) : 0 | 265 (reg & USB_PORTSC_PORT_RESET_FLAG) ? (1 << 4) : 0 | 266 (reg & USB_PORTSC_PORT_POWER_FLAG) ? (1 << 8) : 0 | 267 ((reg & USB_PORTSC_LINE_STATUS_MASK) == USB_PORTSC_LINE_STATUS_K) ? 268 (1 << 9) : 0 | 269 (reg & USB_PORTSC_PORT_OWNER_FLAG) ? (1 << 10) : 0 | 270 (reg & USB_PORTSC_PORT_TEST_MASK) ? (1 << 11) : 0 | 271 (reg & USB_PORTSC_INDICATOR_MASK) ? (1 << 12) : 0) 272 ; 273 //TODO: use hub status flags here 267 274 memcpy(data, &status, sizeof(status)); 268 275 *act_size = sizeof(status); … … 290 297 { 291 298 case USB_HUB_FEATURE_PORT_POWER: /*8*/ 292 { 293 // EHCI_WR(hub->registers->rh_port_status[port], 294 // RHPS_CLEAR_PORT_POWER); 295 // TODO: Implement 296 return EOK; 297 } 299 EHCI_CLR(hub->registers->portsc[port], 300 USB_PORTSC_PORT_POWER_FLAG); 301 return EOK; 298 302 299 303 case USB_HUB_FEATURE_PORT_ENABLE: /*1*/ 300 // EHCI_WR(hub->registers->rh_port_status[port],301 // RHPS_CLEAR_PORT_ENABLE);304 EHCI_CLR(hub->registers->portsc[port], 305 USB_PORTSC_ENABLED_FLAG); 302 306 return EOK; 303 307 304 308 case USB_HUB_FEATURE_PORT_SUSPEND: /*2*/ 305 // EHCI_WR(hub->registers->rh_port_status[port], 306 // RHPS_CLEAR_PORT_SUSPEND); 309 /* If not in suspend it's noop */ 310 if ((EHCI_RD(hub->registers->portsc[port]) & 311 USB_PORTSC_SUSPEND_FLAG) == 0) 312 return EOK; 313 /* Host driven resume */ 314 EHCI_SET(hub->registers->portsc[port], 315 USB_PORTSC_RESUME_FLAG); 316 async_usleep(20000); 317 EHCI_CLR(hub->registers->portsc[port], 318 USB_PORTSC_RESUME_FLAG); 307 319 return EOK; 308 320 309 321 case USB_HUB_FEATURE_C_PORT_CONNECTION: /*16*/ 322 EHCI_SET(hub->registers->portsc[port], 323 USB_PORTSC_CONNECT_CH_FLAG); 324 return EOK; 310 325 case USB_HUB_FEATURE_C_PORT_ENABLE: /*17*/ 326 EHCI_SET(hub->registers->portsc[port], 327 USB_PORTSC_CONNECT_CH_FLAG); 328 return EOK; 329 case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: /*19*/ 330 EHCI_SET(hub->registers->portsc[port], 331 USB_PORTSC_OC_CHANGE_FLAG); 332 return EOK; 311 333 case USB_HUB_FEATURE_C_PORT_SUSPEND: /*18*/ 312 case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: /*19*/313 334 case USB_HUB_FEATURE_C_PORT_RESET: /*20*/ 314 usb_log_debug2("Clearing port C_CONNECTION, C_ENABLE, " 315 "C_SUSPEND, C_OC or C_RESET on port %"PRIu16".\n", port); 316 /* Bit offsets correspond to the feature number */ 317 // EHCI_WR(hub->registers->rh_port_status[port], 318 // 1 << feature); 335 //TODO these are not represented in hw, think of something 319 336 return EOK; 320 337 … … 341 358 const unsigned feature = uint16_usb2host(setup_packet->value); 342 359 switch (feature) { 360 case USB_HUB_FEATURE_PORT_ENABLE: /*1*/ 361 EHCI_SET(hub->registers->portsc[port], 362 USB_PORTSC_ENABLED_FLAG); 363 return EOK; 364 case USB_HUB_FEATURE_PORT_SUSPEND: /*2*/ 365 EHCI_SET(hub->registers->portsc[port], 366 USB_PORTSC_SUSPEND_FLAG); 367 return EOK; 368 case USB_HUB_FEATURE_PORT_RESET: /*4*/ 369 EHCI_SET(hub->registers->portsc[port], 370 USB_PORTSC_PORT_RESET_FLAG); 371 async_usleep(50000); 372 EHCI_CLR(hub->registers->portsc[port], 373 USB_PORTSC_PORT_RESET_FLAG); 374 /* wait for reset to complete */ 375 while (EHCI_RD(hub->registers->portsc[port]) & 376 USB_PORTSC_PORT_RESET_FLAG); 377 /* Handle port ownership, if the port is not enabled 378 * after reset it's a full speed device */ 379 if (!(EHCI_RD(hub->registers->portsc[port]) & 380 USB_PORTSC_ENABLED_FLAG)) 381 EHCI_CLR(hub->registers->portsc[port], 382 USB_PORTSC_PORT_OWNER_FLAG); 383 384 return EOK; 343 385 case USB_HUB_FEATURE_PORT_POWER: /*8*/ 344 { 345 /* No power switching */ 346 // if (rhda & RHDA_NPS_FLAG) 347 return EOK; 348 /* Ganged power switching, one port powers all */ 349 // if (!(rhda & RHDA_PSM_FLAG)) { 350 // EHCI_WR(hub->registers->rh_status,RHS_SET_GLOBAL_POWER); 351 // return EOK; 352 // } 353 } 354 /* Fall through, for per port power */ 355 case USB_HUB_FEATURE_PORT_ENABLE: /*1*/ 356 case USB_HUB_FEATURE_PORT_SUSPEND: /*2*/ 357 case USB_HUB_FEATURE_PORT_RESET: /*4*/ 358 usb_log_debug2("Setting port POWER, ENABLE, SUSPEND or RESET " 359 "on port %"PRIu16".\n", port); 360 /* Bit offsets correspond to the feature number */ 361 // EHCI_WR(hub->registers->rh_port_status[port], 1 << feature); 386 EHCI_SET(hub->registers->portsc[port], 387 USB_PORTSC_PORT_POWER_FLAG); 362 388 return EOK; 363 389 default: … … 389 415 390 416 uint16_t mask = 0; 391 392 /* Only local power source change and over-current change can happen */ 393 // if (EHCI_RD(hub->registers->rh_status) & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) { 394 // mask |= 1; 395 // } 396 397 for (unsigned port = 1; port <= hub->port_count; ++port) { 417 for (unsigned port = 0; port < hub->port_count; ++port) { 398 418 /* Write-clean bits are those that indicate change */ 399 // if (EHCI_RD(hub->registers->rh_port_status[port - 1]) 400 // & RHPS_CHANGE_WC_MASK) { 401 // mask |= (1 << port); 402 // } 419 uint32_t status = EHCI_RD(hub->registers->portsc[port]); 420 if (status & USB_PORTSC_WC_MASK) { 421 /* Ignore new LS device */ 422 if ((status & USB_PORTSC_CONNECT_CH_FLAG) && 423 (status & USB_PORTSC_LINE_STATUS_MASK) == 424 USB_PORTSC_LINE_STATUS_K) 425 EHCI_CLR(hub->registers->portsc[port], 426 USB_PORTSC_PORT_OWNER_FLAG); 427 else 428 mask |= (2 << port); 429 } 403 430 } 404 431
Note:
See TracChangeset
for help on using the changeset viewer.