In usbd_set_config_index(), remove the code which tries to draw conclusions

from the attempted power state instead of the real one. The configuration
descriptor is a constant thing and doesn't reflect the actual state, so
this doesn't make any sense. The actual state can be read by a device
status read, so use this as the first and only instance and remove
the device specific quirks which were based on wrong assumptions.
(It is possible that one of the 3 devices with quirk entries still
needs some special treatment, but this would need better research. For
now I'd prefer to avoid a quirk database which isn't maintained anyway.)
Btw, don't be confused by messages about self powered hubs which don't
have external power connected. This is legal, see the specs.
This commit is contained in:
drochner 2007-01-19 22:42:05 +00:00
parent 14c2cf6c8d
commit a813a29041
3 changed files with 20 additions and 50 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb_quirks.c,v 1.54 2006/09/23 13:07:06 jmcneill Exp $ */
/* $NetBSD: usb_quirks.c,v 1.55 2007/01/19 22:42:05 drochner Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.30 2003/01/02 04:15:55 imp Exp $ */
/*
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: usb_quirks.c,v 1.54 2006/09/23 13:07:06 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: usb_quirks.c,v 1.55 2007/01/19 22:42:05 drochner Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -77,8 +77,6 @@ Static const struct usbd_quirk_entry {
0x000, { UQ_BAD_AUDIO }},
{ USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, 0x110, { UQ_SPUR_BUT_UP }},
{ USB_VENDOR_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB, 0x001, { UQ_SPUR_BUT_UP }},
{ USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100, 0x102, { UQ_BUS_POWERED }},
{ USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232, 0x102, { UQ_BUS_POWERED }},
{ USB_VENDOR_METRICOM, USB_PRODUCT_METRICOM_RICOCHET_GS,
0x100, { UQ_ASSUME_CM_OVER_DATA }},
{ USB_VENDOR_SANYO, USB_PRODUCT_SANYO_SCP4900,
@ -89,7 +87,6 @@ Static const struct usbd_quirk_entry {
0x100, { UQ_ASSUME_CM_OVER_DATA }},
{ USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_MC75,
0x000, { UQ_ASSUME_CM_OVER_DATA }},
{ USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, 0x110, { UQ_POWER_CLAIM }},
{ USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, 0x009, { UQ_AU_NO_FRAC }},
{ USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE,
0x100, { UQ_AU_INP_ASYNC }},

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb_quirks.h,v 1.20 2001/04/15 09:38:01 augustss Exp $ */
/* $NetBSD: usb_quirks.h,v 1.21 2007/01/19 22:42:05 drochner Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_quirks.h,v 1.9 1999/11/12 23:31:03 n_hibma Exp $ */
/*
@ -45,11 +45,9 @@ struct usbd_quirks {
#define UQ_MS_REVZ 0x0004 /* mouse has Z-axis reversed */
#define UQ_NO_STRINGS 0x0008 /* string descriptors are broken. */
#define UQ_BAD_ADC 0x0010 /* bad audio spec version number. */
#define UQ_BUS_POWERED 0x0020 /* device is bus powered, despite claim */
#define UQ_BAD_AUDIO 0x0040 /* device claims audio class, but isn't */
#define UQ_SPUR_BUT_UP 0x0080 /* spurious mouse button up events */
#define UQ_AU_NO_XU 0x0100 /* audio device has broken extension unit */
#define UQ_POWER_CLAIM 0x0200 /* hub lies about power status */
#define UQ_AU_NO_FRAC 0x0400 /* don't adjust for fractional samples */
#define UQ_AU_INP_ASYNC 0x0800 /* input is async despite claim of adaptive */
#define UQ_ASSUME_CM_OVER_DATA 0x1000 /* modem device breaks on cm over data */

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb_subr.c,v 1.140 2006/12/05 08:17:03 pavel Exp $ */
/* $NetBSD: usb_subr.c,v 1.141 2007/01/19 22:42:05 drochner Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
/*
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.140 2006/12/05 08:17:03 pavel Exp $");
__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.141 2007/01/19 22:42:05 drochner Exp $");
#include "opt_compat_netbsd.h"
#include "opt_usbverbose.h"
@ -628,55 +628,30 @@ usbd_set_config_index(usbd_device_handle dev, int index, int msg)
/* Figure out if the device is self or bus powered. */
selfpowered = 0;
if (!(dev->quirks->uq_flags & UQ_BUS_POWERED) &&
(cdp->bmAttributes & UC_SELF_POWERED)) {
/* May be self powered. */
if (cdp->bmAttributes & UC_BUS_POWERED) {
/* Must ask device. */
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;
}
err = usbd_get_device_status(dev, &ds);
if (!err && (UGETW(ds.wStatus) & UDS_SELF_POWERED))
selfpowered = 1;
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. */
if ((cdp->bmAttributes & UC_SELF_POWERED) && !selfpowered) {
if (msg)
printf("%s: device addr %d (config %d): "
"can't set self powered configuration\n",
USBDEVNAME(dev->bus->bdev), dev->address,
cdp->bConfigurationValue);
err = USBD_NO_POWER;
goto bad;
}
#ifdef USB_DEBUG
if (dev->powersrc == NULL) {
DPRINTF(("usbd_set_config_index: No power source?\n"));
return (USBD_IOERROR);
err = USBD_IOERROR;
goto bad;
}
#endif
power = cdp->bMaxPower * 2;