Lines 560-565
static usb_error_t
Link Here
|
560 |
uhub_read_port_status(struct uhub_softc *sc, uint8_t portno) |
560 |
uhub_read_port_status(struct uhub_softc *sc, uint8_t portno) |
561 |
{ |
561 |
{ |
562 |
struct usb_port_status ps; |
562 |
struct usb_port_status ps; |
|
|
563 |
uint16_t delta; |
563 |
usb_error_t err; |
564 |
usb_error_t err; |
564 |
|
565 |
|
565 |
if (sc->sc_usb_port_errors >= UHUB_USB_PORT_ERRORS_MAX) { |
566 |
if (sc->sc_usb_port_errors >= UHUB_USB_PORT_ERRORS_MAX) { |
Lines 569-581
uhub_read_port_status(struct uhub_softc *sc, uint8_t portno)
Link Here
|
569 |
return (USB_ERR_TIMEOUT); |
570 |
return (USB_ERR_TIMEOUT); |
570 |
} |
571 |
} |
571 |
|
572 |
|
572 |
err = usbd_req_get_port_status( |
573 |
err = usbd_req_get_port_status(sc->sc_udev, NULL, &ps, portno); |
573 |
sc->sc_udev, NULL, &ps, portno); |
|
|
574 |
|
575 |
if (err == 0) { |
574 |
if (err == 0) { |
|
|
575 |
if (sc->sc_usb_port_errors == 0) { |
576 |
delta = sc->sc_st.port_status ^ |
577 |
UGETW(ps.wPortStatus); |
578 |
delta &= (UPS_CURRENT_CONNECT_STATUS | |
579 |
UPS_PORT_ENABLED); |
580 |
} else { |
581 |
delta = 0; |
582 |
sc->sc_usb_port_errors = 0; |
583 |
} |
584 |
|
576 |
sc->sc_st.port_status = UGETW(ps.wPortStatus); |
585 |
sc->sc_st.port_status = UGETW(ps.wPortStatus); |
577 |
sc->sc_st.port_change = UGETW(ps.wPortChange); |
586 |
sc->sc_st.port_change = UGETW(ps.wPortChange); |
578 |
sc->sc_usb_port_errors = 0; |
587 |
|
|
|
588 |
/* Assert identical change and status bits: */ |
589 |
CTASSERT(UPS_C_PORT_ENABLED == UPS_PORT_ENABLED); |
590 |
CTASSERT(UPS_C_CONNECT_STATUS == UPS_CURRENT_CONNECT_STATUS); |
591 |
|
592 |
/* |
593 |
* Make sure change and enable port events don't get |
594 |
* lost by tracking some port status bits in |
595 |
* software. Apparently this can happen during startup |
596 |
* on some USB HUBs. |
597 |
*/ |
598 |
if (delta & ~sc->sc_st.port_change) { |
599 |
DPRINTFN(4, "port %d, missing status change, 0x%04x!\n", portno, delta); |
600 |
sc->sc_st.port_change |= delta; |
601 |
} |
579 |
} else { |
602 |
} else { |
580 |
sc->sc_st.port_status = 0; |
603 |
sc->sc_st.port_status = 0; |
581 |
sc->sc_st.port_change = 0; |
604 |
sc->sc_st.port_change = 0; |