Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/nick-nhusb]: src/sys/dev/usb From t-hash
details: https://anonhg.NetBSD.org/src/rev/112cd1b67056
branches: nick-nhusb
changeset: 334256:112cd1b67056
user: skrll <skrll%NetBSD.org@localhost>
date: Sat Oct 03 16:32:25 2015 +0000
description:
>From t-hash
+ Import port speed detection code from OpenBSD.
Check port power bit instead of speed bits. It's a cool idea.
diffstat:
sys/dev/usb/uhub.c | 85 ++++++++++++++++++++++++++++++++---------------------
1 files changed, 51 insertions(+), 34 deletions(-)
diffs (134 lines):
diff -r c333358214e2 -r 112cd1b67056 sys/dev/usb/uhub.c
--- a/sys/dev/usb/uhub.c Tue Sep 29 11:38:28 2015 +0000
+++ b/sys/dev/usb/uhub.c Sat Oct 03 16:32:25 2015 +0000
@@ -1,5 +1,6 @@
-/* $NetBSD: uhub.c,v 1.126.2.15 2015/09/29 11:38:29 skrll Exp $ */
+/* $NetBSD: uhub.c,v 1.126.2.16 2015/10/03 16:32:25 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.
@@ -36,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.126.2.15 2015/09/29 11:38:29 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.126.2.16 2015/10/03 16:32:25 skrll Exp $");
#include <sys/param.h>
@@ -546,10 +547,6 @@
}
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 @@
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 @@
}
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 @@
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);
Home |
Main Index |
Thread Index |
Old Index