-/* $OpenBSD: uhub.c,v 1.84 2015/06/15 16:46:21 mpi Exp $ */
+/* $OpenBSD: uhub.c,v 1.85 2015/06/22 10:29:18 mpi Exp $ */
/* $NetBSD: uhub.c,v 1.64 2003/02/08 03:32:51 ichiro Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */
continue;
}
/* Get port status again, it might have changed during reset */
- err = usbd_get_port_status(dev, port, &up->status);
- if (err) {
- DPRINTF("%s: get port %d status failed, error=%s\n",
- sc->sc_dev.dv_xname, port, usbd_errstr(err));
+ if (usbd_get_port_status(dev, port, &up->status))
continue;
- }
+
status = UGETW(up->status.wPortStatus);
change = UGETW(up->status.wPortChange);
+ DPRINTF("%s: port %d status=0x%04x change=0x%04x\n",
+ sc->sc_dev.dv_xname, port, status, change);
+
if (!(status & UPS_CURRENT_CONNECT_STATUS)) {
/* Nothing connected, just ignore it. */
DPRINTF("%s: port %d, device disappeared after reset\n",
if ((status & UPS_PORT_POWER) == 0)
status &= ~UPS_PORT_POWER_SS;
- if (status & UPS_SUPER_SPEED)
- speed = USB_SPEED_SUPER;
- else if (status & UPS_HIGH_SPEED)
+ if (status & UPS_HIGH_SPEED)
speed = USB_SPEED_HIGH;
else if (status & UPS_LOW_SPEED)
speed = USB_SPEED_LOW;
-/* $OpenBSD: usb.h,v 1.50 2015/02/14 06:18:58 uebayasi Exp $ */
+/* $OpenBSD: usb.h,v 1.51 2015/06/22 10:29:18 mpi Exp $ */
/* $NetBSD: usb.h,v 1.69 2002/09/22 23:20:50 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb.h,v 1.14 1999/11/17 22:33:46 n_hibma Exp $ */
#define UPS_PORT_LS_HOT_RESET 0x0120
#define UPS_PORT_LS_COMP_MOD 0x0140
#define UPS_PORT_LS_LOOPBACK 0x0160
+#define UPS_PORT_LS_GET(x) (((x) >> 5) & 0xf)
+#define UPS_PORT_LS_SET(x) (((x) & 0xf) << 5)
#define UPS_PORT_POWER 0x0100
#define UPS_PORT_POWER_SS 0x0200 /* USB 3.0 only */
#define UPS_FULL_SPEED 0x0000
#define UPS_LOW_SPEED 0x0200
#define UPS_HIGH_SPEED 0x0400
-#define UPS_SUPER_SPEED 0x0800
#define UPS_PORT_TEST 0x0800
#define UPS_PORT_INDICATOR 0x1000
-/* $OpenBSD: xhci.c,v 1.60 2015/05/27 11:13:34 mikeb Exp $ */
+/* $OpenBSD: xhci.c,v 1.61 2015/06/22 10:29:18 mpi Exp $ */
/*
* Copyright (c) 2014-2015 Martin Pieuchot
}
v = XOREAD4(sc, XHCI_PORTSC(index));
DPRINTFN(8,("xhci_root_ctrl_start: port status=0x%04x\n", v));
+ i = UPS_PORT_LS_SET(XHCI_PS_GET_PLS(v));
switch (XHCI_PS_SPEED(v)) {
case XHCI_SPEED_FULL:
- i = UPS_FULL_SPEED;
+ i |= UPS_FULL_SPEED;
break;
case XHCI_SPEED_LOW:
- i = UPS_LOW_SPEED;
+ i |= UPS_LOW_SPEED;
break;
case XHCI_SPEED_HIGH:
- i = UPS_HIGH_SPEED;
+ i |= UPS_HIGH_SPEED;
break;
case XHCI_SPEED_SUPER:
default:
- i = UPS_SUPER_SPEED;
break;
}
if (v & XHCI_PS_CCS) i |= UPS_CURRENT_CONNECT_STATUS;
if (v & XHCI_PS_PED) i |= UPS_PORT_ENABLED;
if (v & XHCI_PS_OCA) i |= UPS_OVERCURRENT_INDICATOR;
if (v & XHCI_PS_PR) i |= UPS_RESET;
- if (v & XHCI_PS_PP) i |= UPS_PORT_POWER;
+ if (v & XHCI_PS_PP) {
+ if (XHCI_PS_SPEED(v) >= XHCI_SPEED_FULL &&
+ XHCI_PS_SPEED(v) <= XHCI_SPEED_HIGH)
+ i |= UPS_PORT_POWER;
+ else
+ i |= UPS_PORT_POWER_SS;
+ }
USETW(ps.wPortStatus, i);
i = 0;
if (v & XHCI_PS_CSC) i |= UPS_C_CONNECT_STATUS;
if (v & XHCI_PS_PEC) i |= UPS_C_PORT_ENABLED;
if (v & XHCI_PS_OCC) i |= UPS_C_OVERCURRENT_INDICATOR;
if (v & XHCI_PS_PRC) i |= UPS_C_PORT_RESET;
+ if (v & XHCI_PS_PLC) i |= UPS_C_PORT_LINK_STATE;
+ if (v & XHCI_PS_CEC) i |= UPS_C_PORT_CONFIG_ERROR;
USETW(ps.wPortChange, i);
l = min(len, sizeof ps);
memcpy(buf, &ps, l);