Changeset 2be477d5 in mainline for uspace/drv/bus/usb/ehci/ehci_rh.c
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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.