summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authoraugustss <augustss@NetBSD.org>2000-10-24 15:01:26 +0000
committeraugustss <augustss@NetBSD.org>2000-10-24 15:01:26 +0000
commita675063a0d0a3928822b86201536fcc60a7d22d6 (patch)
tree397c2f0766adfdcab0fc1a1bca1ac58236f0820d /sys/dev/usb
parent372ae0a636a8ce429a76f8037578f6eb26a05275 (diff)
Add a hack to try and figure out if the TI UTUSB41 hub is bus powered
despite claiming to be self powered (it's important to know so that the power budget can be met).
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/usb_subr.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index cf9e6f65580..e0c59511d8b 100644
--- a/sys/dev/usb/usb_subr.c
+++ b/sys/dev/usb/usb_subr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: usb_subr.c,v 1.80 2000/10/12 23:11:04 augustss Exp $ */
+/* $NetBSD: usb_subr.c,v 1.81 2000/10/24 15:01:26 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
/*
@@ -576,18 +576,43 @@ usbd_set_config_index(usbd_device_handle dev, int index, int msg)
/* May be self powered. */
if (cdp->bmAttributes & UC_BUS_POWERED) {
/* Must ask device. */
- err = usbd_get_device_status(dev, &ds);
- if (!err && (UGETW(ds.wStatus) & UDS_SELF_POWERED))
- selfpowered = 1;
- DPRINTF(("usbd_set_config_index: status=0x%04x, "
- "error=%s\n",
- UGETW(ds.wStatus), usbd_errstr(err)));
+ if (dev->quirks->uq_flags & UQ_POWER_CLAIM) {
+ /*
+ * Hub claims to be self powered, but isn't.
+ * It seems that the power status can be
+ * determined by the hub characteristics.
+ */
+ usb_hub_descriptor_t hd;
+ usb_device_request_t req;
+ req.bmRequestType = UT_READ_CLASS_DEVICE;
+ req.bRequest = UR_GET_DESCRIPTOR;
+ USETW(req.wValue, 0);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE);
+ err = usbd_do_request(dev, &req, &hd);
+ if (!err &&
+ (UGETW(hd.wHubCharacteristics) &
+ UHD_PWR_INDIVIDUAL))
+ selfpowered = 1;
+ DPRINTF(("usbd_set_config_index: charac=0x%04x"
+ ", error=%s\n",
+ UGETW(hd.wHubCharacteristics),
+ usbd_errstr(err)));
+ } else {
+ err = usbd_get_device_status(dev, &ds);
+ if (!err &&
+ (UGETW(ds.wStatus) & UDS_SELF_POWERED))
+ selfpowered = 1;
+ DPRINTF(("usbd_set_config_index: status=0x%04x"
+ ", error=%s\n",
+ UGETW(ds.wStatus), usbd_errstr(err)));
+ }
} else
selfpowered = 1;
}
- DPRINTF(("usbd_set_config_index: (addr %d) attr=0x%02x, "
- "selfpowered=%d, power=%d\n",
- dev->address, cdp->bmAttributes,
+ DPRINTF(("usbd_set_config_index: (addr %d) cno=%d attr=0x%02x, "
+ "selfpowered=%d, power=%d\n",
+ cdp->bConfigurationValue, dev->address, cdp->bmAttributes,
selfpowered, cdp->bMaxPower * 2));
/* Check if we have enough power. */
@@ -599,6 +624,7 @@ usbd_set_config_index(usbd_device_handle dev, int index, int msg)
#endif
power = cdp->bMaxPower * 2;
if (power > dev->powersrc->power) {
+ DPRINTF(("power exceeded %d %d\n", power,dev->powersrc->power));
/* XXX print nicer message. */
if (msg)
printf("%s: device addr %d (config %d) exceeds power "