tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[patch] xhci patch 20151003
Hello,
Here is an xhci patch for nick-nhusb branch.
nhusb-uhub_c.diff
+ Import port speed detection code from OpenBSD.
Check port power bit instead of speed bits. It's a cool idea.
+ Fix bus revision of xhci.
Thanks,
--
t-hash
--- sys/dev/usb/uhub.c.orig 2015-09-23 23:15:16.000000000 +0900
+++ sys/dev/usb/uhub.c 2015-09-28 06:38:39.000000000 +0900
@@ -1,5 +1,6 @@
/* $NetBSD: uhub.c,v 1.126.2.14 2015/09/23 13:49:59 skrll Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */
+/* $OpenBSD: uhub.c,v 1.86 2015/06/29 18:27:40 mpi Exp $ */
/*
* Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@@ -546,10 +547,6 @@ uhub_explore(struct usbd_device *dev)
}
status = UGETW(up->up_status.wPortStatus);
change = UGETW(up->up_status.wPortChange);
- if (USB_IS_SS(dev->ud_speed)) {
- status |= UPS_OTHER_SPEED;
- USETW(up->up_status.wPortStatus, status);
- }
DPRINTF("uhub %d port %d: s/c=%x/%x",
device_unit(sc->sc_dev), port, status, change);
@@ -661,23 +658,6 @@ uhub_explore(struct usbd_device *dev)
DPRINTF("unit %d dev->speed=%u dev->depth=%u",
device_unit(sc->sc_dev), dev->ud_speed, dev->ud_depth, 0);
- /*
- * To check whether port has power,
- * check UPS_PORT_POWER bit if port speed is HS/FS/LS and
- * check UPS_PORT_POWER_SS bit if port speed is SS.
- */
- if (status & UPS_OTHER_SPEED) {
- if (!(status & UPS_PORT_POWER_SS))
- aprint_normal_dev(sc->sc_dev,
- "strange, connected port %d has no power\n",
- port);
- } else {
- if (!(status & UPS_PORT_POWER))
- aprint_normal_dev(sc->sc_dev,
- "strange, connected port %d has no power\n",
- port);
- }
-
/* Wait for maximum device power up time. */
usbd_delay_ms(dev, USB_PORT_POWERUP_DELAY);
@@ -696,10 +676,6 @@ uhub_explore(struct usbd_device *dev)
}
status = UGETW(up->up_status.wPortStatus);
change = UGETW(up->up_status.wPortChange);
- if (USB_IS_SS(dev->ud_speed)) {
- status |= UPS_OTHER_SPEED;
- USETW(up->up_status.wPortStatus, status);
- }
DPRINTF("hub %d port %d after reset: s/c=%x/%x",
device_unit(sc->sc_dev), port, status, change);
@@ -724,19 +700,60 @@ uhub_explore(struct usbd_device *dev)
usbd_clear_port_feature(dev, port,
UHF_C_BH_PORT_RESET);
- /* Figure out device speed */
- if (status & UPS_OTHER_SPEED) {
- speed = USB_SPEED_SUPER;
- } else if (status & UPS_HIGH_SPEED)
+ /*
+ * Figure out device speed from power bit of port status.
+ * USB 2.0 ch 11.24.2.7.1
+ * USB 3.1 ch 10.16.2.6.1
+ */
+ int sts = status;
+ if ((sts & UPS_PORT_POWER) == 0)
+ sts &= ~UPS_PORT_POWER_SS;
+
+ if (sts & UPS_HIGH_SPEED)
speed = USB_SPEED_HIGH;
- else if (status & UPS_LOW_SPEED)
+ else if (sts & UPS_LOW_SPEED)
speed = USB_SPEED_LOW;
- else
- speed = USB_SPEED_FULL;
+ else {
+ /*
+ * If there is no power bit set, it is certainly
+ * a Super Speed device, so use the speed of its
+ * parent hub.
+ */
+ if (sts & UPS_PORT_POWER)
+ speed = USB_SPEED_FULL;
+ else
+ speed = dev->ud_speed;
+ }
+
+ /*
+ * Reduce the speed, otherwise we won't setup the proper
+ * transfer methods.
+ */
+ if (speed > dev->ud_speed)
+ speed = dev->ud_speed;
DPRINTF("uhub %d speed %u", device_unit(sc->sc_dev), speed, 0,
0);
+ /*
+ * To check whether port has power,
+ * check UPS_PORT_POWER_SS bit if port speed is SS, and
+ * check UPS_PORT_POWER bit if port speed is HS/FS/LS.
+ */
+ if (USB_IS_SS(speed)) {
+ /* SS hub port */
+ if (!(status & UPS_PORT_POWER_SS))
+ aprint_normal_dev(sc->sc_dev,
+ "strange, connected port %d has no power\n",
+ port);
+ } else {
+ /* HS/FS/LS hub port */
+ if (!(status & UPS_PORT_POWER))
+ aprint_normal_dev(sc->sc_dev,
+ "strange, connected port %d has no power\n",
+ port);
+ }
+
/* Get device info and set its address. */
err = usbd_new_device(sc->sc_dev, dev->ud_bus,
dev->ud_depth + 1, speed, port, up);
--- sys/dev/usb/xhci.c.orig 2015-09-23 23:15:19.000000000 +0900
+++ sys/dev/usb/xhci.c 2015-09-26 08:56:50.000000000 +0900
@@ -662,7 +662,7 @@ xhci_init(struct xhci_softc *sc)
XHCIHIST_FUNC(); XHCIHIST_CALLED();
/* XXX Low/Full/High speeds for now */
- sc->sc_bus.ub_revision = USBREV_2_0;
+ sc->sc_bus.ub_revision = USBREV_3_0;
sc->sc_bus.ub_usedma = true;
cap = xhci_read_4(sc, XHCI_CAPLENGTH);
Home |
Main Index |
Thread Index |
Old Index