diff options
author | Yojiro Uo <yuo@cvs.openbsd.org> | 2008-06-15 18:10:04 +0000 |
---|---|---|
committer | Yojiro Uo <yuo@cvs.openbsd.org> | 2008-06-15 18:10:04 +0000 |
commit | 5d650255310e2a1cfefe66f5710185fde11763b1 (patch) | |
tree | 1cba17ccaec162a82d69ac5259e36d2ba4f35f28 /sys/dev | |
parent | 06f18aafcdbf1a8e6035c737b54d271c546aad2f (diff) |
expand the quirk framework to enable device class match
ok deraadt@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/usb/usb_quirks.c | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/sys/dev/usb/usb_quirks.c b/sys/dev/usb/usb_quirks.c index 81707121052..38f47ad55d4 100644 --- a/sys/dev/usb/usb_quirks.c +++ b/sys/dev/usb/usb_quirks.c @@ -1,4 +1,4 @@ -/* $OpenBSD: usb_quirks.c,v 1.37 2008/05/24 20:39:18 ckuethe Exp $ */ +/* $OpenBSD: usb_quirks.c,v 1.38 2008/06/15 18:10:03 yuo Exp $ */ /* $NetBSD: usb_quirks.c,v 1.45 2003/05/10 17:47:14 hamajima Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.30 2003/01/02 04:15:55 imp Exp $ */ @@ -160,27 +160,60 @@ const struct usbd_quirk_entry { { 0, 0, 0, { 0 } } }; +#define bANY 0xff +const struct usbd_dev_quirk_entry { + u_int8_t bDeviceClass; + u_int8_t bDeviceSubClass; + u_int8_t bDeviceProtocol; + struct usbd_quirks quirks; +} usb_dev_quirks[] = { + /* currently this table is empty */ + { 0, 0, 0, { 0 } } +}; + const struct usbd_quirks usbd_no_quirk = { 0 }; const struct usbd_quirks * usbd_find_quirk(usb_device_descriptor_t *d) { const struct usbd_quirk_entry *t; + const struct usbd_dev_quirk_entry *td; u_int16_t vendor = UGETW(d->idVendor); u_int16_t product = UGETW(d->idProduct); u_int16_t revision = UGETW(d->bcdDevice); + /* search device specific quirks entry */ for (t = usb_quirks; t->idVendor != 0; t++) { if (t->idVendor == vendor && t->idProduct == product && - (t->bcdDevice == ANY || t->bcdDevice == revision)) - break; + (t->bcdDevice == ANY || t->bcdDevice == revision)) { +#ifdef USB_DEBUG + if (usbdebug && t->quirks.uq_flags) + printf("usbd_find_quirk for specific device 0x%04x/0x%04x/%x: %d\n", + vendor, product, UGETW(d->bcdDevice), + t->quirks.uq_flags); +#endif + + return (&t->quirks); + } } + /* no device specific quirks found, serarch class specific entry */ + for (td = usb_dev_quirks; td->bDeviceClass != 0; td++) { + if (td->bDeviceClass == d->bDeviceClass && + (td->bDeviceSubClass == bANY || + td->bDeviceSubClass == d->bDeviceSubClass) && + (td->bDeviceProtocol == bANY || + td->bDeviceProtocol == d->bDeviceProtocol)) { #ifdef USB_DEBUG - if (usbdebug && t->quirks.uq_flags) - printf("usbd_find_quirk 0x%04x/0x%04x/%x: %d\n", - UGETW(d->idVendor), UGETW(d->idProduct), - UGETW(d->bcdDevice), t->quirks.uq_flags); + if (usbdebug && td->quirks.uq_flags) + printf("usbd_find_quirk for device class 0x%02x/0x%02x/%x: %d\n", + d->bDeviceClass, d->bDeviceSubClass, + UGETW(d->bcdDevice), + td->quirks.uq_flags); #endif - return (&t->quirks); + return (&td->quirks); + } + } + + return (&usbd_no_quirk); } |