usb/122819: Patch to provide dynamic additions to the usb
quirks table
Maurice Castro
maurice at castro.aus.net
Fri Apr 18 00:00:07 UTC 2008
The following reply was made to PR usb/122819; it has been noted by GNATS.
From: Maurice Castro <maurice at castro.aus.net>
To: bug-followup at FreeBSD.org, maurice at castro.aus.net
Cc:
Subject: Re: usb/122819: Patch to provide dynamic additions to the usb quirks table
Date: Fri, 18 Apr 2008 09:55:05 +1000
--Apple-Mail-4-388555214
Content-Type: text/plain;
charset=US-ASCII;
format=flowed;
delsp=yes
Content-Transfer-Encoding: 7bit
From: hselasky at c2i.net
> You need to do a little bit more work regarding the token naming.
> There is no USB module called "UAU". Instead of "UAU_NO_FRAC" I
> think you should have changed it to "UAUDIO_NO_FRAC". The same
> applies for most of the other quirk tokens aswell. "UHID_IGNORE" is
> fine.
Hi Hans,
changes made as requested. Summary of quirk, module quirk appears in
and naming below. Please note that 2 of the quirks appear to be
unused. Updated patch attached.
Maurice Castro
* UQ_SWAP_UNICODE
/usr/src/sys/dev/usb/usbdi.c: int swap = dev->quirks->uq_flags &
UQ_SWAP_UNICODE;
USWAP_UNICODE -> USBDI_SWAP_UNICODE
* UQ_NO_STRINGS
/usr/src/sys/dev/usb/usbdi.c: if (dev->quirks->uq_flags &
UQ_NO_STRINGS)
UNO_STRINGS -> USBDI_NO_STRINGS
* UQ_BAD_ADC
/usr/src/sys/dev/sound/usb/uaudio.c: if (!(usbd_get_quirks(sc-
>sc_udev)->uq_flags & UQ_BAD_ADC) &&
UBAD_ADC -> UAUDIO_BAD_ADC
* UQ_BUS_POWERED
/usr/src/sys/dev/usb/usb_subr.c: if (!(dev->quirks->uq_flags &
UQ_BUS_POWERED) &&
UBUS_POWERED -> USB_BUS_POWERED
* UQ_BAD_AUDIO
/usr/src/sys/dev/sound/usb/uaudio.c: (usbd_get_quirks(uaa-
>device)->uq_flags & UQ_BAD_AUDIO))
UBAD_AUDIO -> UAUDIO_BAD_AUDIO
* UQ_SPUR_BUT_UP
/usr/src/sys/dev/usb/ums.c: if (usbd_get_quirks(uaa->device)-
>uq_flags & UQ_SPUR_BUT_UP) {
USPUR_BUT_UP -> UMS_SPUR_BUT_UP
* UQ_AU_NO_XU
/usr/src/sys/dev/sound/usb/uaudio.c: if (usbd_get_quirks(sc-
>sc_udev)->uq_flags & UQ_AU_NO_XU)
UAU_NO_XU -> UAUDIO_NO_XU
* UQ_POWER_CLAIM
/usr/src/sys/dev/usb/usb_subr.c: if (dev-
>quirks->uq_flags & UQ_POWER_CLAIM) {
UPOWER_CLAIM -> USB_POWER_CLAIM
* UQ_AU_NO_FRAC
/usr/src/sys/dev/sound/usb/uaudio.c: if (usbd_get_quirks(sc-
>sc_udev)->uq_flags & UQ_AU_NO_FRAC)
UAU_NO_FRAC -> UAUDIO_AU_NO_FRAC
* UQ_AU_INP_ASYNC
/usr/src/sys/dev/sound/usb/uaudio.c: if ((usbd_get_quirks(sc-
>sc_udev)->uq_flags & UQ_AU_INP_ASYNC) &&
UAU_INP_ASYNC -> UAUDIO_INP_ASYNC
* UQ_BROKEN_BIDIR
/usr/src/sys/dev/usb/ulpt.c: if (usbd_get_quirks(dev)->uq_flags &
UQ_BROKEN_BIDIR) {
UBROKEN_BIDIR -> ULPT_BROKEN_BIDIR
* UQ_OPEN_CLEARSTALL
/usr/src/sys/dev/usb/usb_subr.c: if (dev->quirks->uq_flags &
UQ_OPEN_CLEARSTALL) {
* UQ_HID_IGNORE
/usr/src/sys/dev/usb/uhid.c: if (usbd_get_quirks(uaa->device)-
>uq_flags & UQ_HID_IGNORE)
UHID_IGNORE -> UHID_IGNORE
* UQ_KBD_IGNORE
/usr/src/sys/dev/usb/ukbd.c: if (usbd_get_quirks(uaa->device)-
>uq_flags & UQ_KBD_IGNORE)
UKBD_IGNORE -> UKBD_IGNORE
* UQ_MS_BAD_CLASS
/usr/src/sys/dev/usb/ums.c: if (usbd_get_quirks(uaa->device)-
>uq_flags & UQ_MS_BAD_CLASS) {
UMS_BAD_CLASS -> UMS_BAD_CLASS
* UQ_MS_REVZ
UMS_REVZ -> MS_REVZ
* UQ_MS_LEADING_BYTE
UMS_LEADING_BYTE -> MS_LEADING_BYTE
--Apple-Mail-4-388555214
Content-Disposition: attachment;
filename=usb.diff
Content-Type: application/octet-stream;
x-unix-mode=0644;
name="usb.diff"
Content-Transfer-Encoding: 7bit
diff -ur /usr/src/share/man/man4/usb.4 /scratch/src/share/man/man4/usb.4
--- /usr/src/share/man/man4/usb.4 2008-04-11 22:43:31.000000000 +1000
+++ /scratch/src/share/man/man4/usb.4 2008-04-18 09:38:37.000000000 +1000
@@ -288,6 +288,66 @@
.Em DANGEROUS
and should be used with great care since it
can destroy the bus integrity.
+.It Dv USB_SETDYNQUIRKS
+This command will cause the dynamic quirks table to be rebuilt from the
+contents of the kernel environment. Environment strings of the form
+.Pp
+.Ic usb.quirk.N="VENDOR PRODUCT REVISION FLAGS"
+.Pp
+where
+.Ic N
+is a number between 0 and 9 and quirks must be numbered contiguously;
+.Ic VENDOR PRODUCT
+and
+.Ic REVISION
+are constants that identify the device (the value 0xffff for
+.Ic REVISION
+denotes all revisions); and
+.Ic FLAGS
+is any combination of
+.Bl -tag -width "UOPEN_CLEARSTALL" -compact -offset indent
+.It USBDI_SWAP_UNICODE
+has some Unicode strings swapped.
+.It USBDI_NO_STRINGS
+string descriptors are broken.
+.It UAUDIO_BAD_ADC
+bad audio spec version number.
+.It USB_BUS_POWERED
+device is bus powered, despite claim
+.It UAUDIO_BAD_AUDIO
+device claims audio class, but isn't
+.It UMS_SPUR_BUT_UP
+spurious mouse button up events
+.It UAUDIO_NO_XU
+audio device has broken extension unit
+.It USB_POWER_CLAIM
+hub lies about power status
+.It UAUDIO_NO_FRAC
+don't adjust for fractional samples
+.It UAUDIO_INP_ASYNC
+input is async despite claim of adaptive
+.It ULPT_BROKEN_BIDIR
+printer has broken bidir mode
+.It USB_OPEN_CLEARSTALL
+device needs clear endpoint stall
+.It UHID_IGNORE
+device should be ignored by hid class
+.It UKBD_IGNORE
+device should be ignored by both kbd and hid class
+.It UMS_BAD_CLASS
+doesn't identify properly
+.It MS_LEADING_BYTE
+mouse sends an unknown leading byte.
+.It MS_REVZ
+mouse has Z-axis reversed
+.El
+separated by "|" characters. These lines set the quirks for each device
+identified.
+.Pp
+The dynamic quirks table is designed to supplement the quirks table built
+in to the kernel. It is of particular use to developers working with devices
+that inappropriately share vendor, product and revision information and hence
+cannot be correctly added in to the kernel's quirks table.
.El
.Pp
The include file
diff -ur /usr/src/sys/dev/usb/usb.c /scratch/src/sys/dev/usb/usb.c
--- /usr/src/sys/dev/usb/usb.c 2008-04-11 22:43:56.000000000 +1000
+++ /scratch/src/sys/dev/usb/usb.c 2008-04-16 23:23:55.000000000 +1000
@@ -668,6 +668,10 @@
*(struct usb_device_stats *)data = sc->sc_bus->stats;
break;
+ case USB_SETDYNQUIRKS:
+ usbd_populate_dynamic_quirks();
+ break;
+
default:
return (EINVAL);
}
diff -ur /usr/src/sys/dev/usb/usb.h /scratch/src/sys/dev/usb/usb.h
--- /usr/src/sys/dev/usb/usb.h 2008-04-11 22:43:56.000000000 +1000
+++ /scratch/src/sys/dev/usb/usb.h 2008-04-16 23:22:34.000000000 +1000
@@ -673,6 +673,7 @@
#define USB_DISCOVER _IO ('U', 3)
#define USB_DEVICEINFO _IOWR('U', 4, struct usb_device_info)
#define USB_DEVICESTATS _IOR ('U', 5, struct usb_device_stats)
+#define USB_SETDYNQUIRKS _IO ('U', 6)
/* Generic HID device */
#define USB_GET_REPORT_DESC _IOR ('U', 21, struct usb_ctl_report_desc)
diff -ur /usr/src/sys/dev/usb/usb_quirks.c /scratch/src/sys/dev/usb/usb_quirks.c
--- /usr/src/sys/dev/usb/usb_quirks.c 2008-04-11 22:43:56.000000000 +1000
+++ /scratch/src/sys/dev/usb/usb_quirks.c 2008-04-18 09:33:58.000000000 +1000
@@ -42,8 +42,13 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/ctype.h>
#include <dev/usb/usb.h>
+#include <sys/kenv.h>
#include "usbdevs.h"
#include <dev/usb/usb_quirks.h>
@@ -54,12 +59,14 @@
#define ANY 0xffff
-static const struct usbd_quirk_entry {
+struct usbd_quirk_entry {
u_int16_t idVendor;
u_int16_t idProduct;
u_int16_t bcdDevice;
struct usbd_quirks quirks;
-} usb_quirks[] = {
+};
+
+static struct usbd_quirk_entry usb_quirks[] = {
{ USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4,
0x094, { UQ_SWAP_UNICODE}},
{ USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, { UQ_BAD_ADC }},
@@ -117,15 +124,24 @@
const struct usbd_quirks usbd_no_quirk = { 0 };
-const struct usbd_quirks *
-usbd_find_quirk(usb_device_descriptor_t *d)
+#define MAX_DYNAMIC_USB_QUIRKS 10
+#define ENVNAMEROOT "usb.quirk."
+#define SEPCHAR "|"
+
+static struct usbd_quirk_entry dynamic_usb_quirks[MAX_DYNAMIC_USB_QUIRKS];
+
+static struct usbd_quirks *
+usbd_search_quirk(struct usbd_quirk_entry *quirks, usb_device_descriptor_t *d);
+
+static struct usbd_quirks *
+usbd_search_quirk(struct usbd_quirk_entry *quirks, usb_device_descriptor_t *d)
{
- const struct usbd_quirk_entry *t;
+ struct usbd_quirk_entry *t;
u_int16_t vendor = UGETW(d->idVendor);
u_int16_t product = UGETW(d->idProduct);
u_int16_t revision = UGETW(d->bcdDevice);
- for (t = usb_quirks; t->idVendor != 0; t++) {
+ for (t = quirks; t->idVendor != 0; t++) {
if (t->idVendor == vendor &&
t->idProduct == product &&
(t->bcdDevice == ANY || t->bcdDevice == revision))
@@ -139,3 +155,150 @@
#endif
return (&t->quirks);
}
+
+struct mtx dyn_mtx;
+
+const struct usbd_quirks *
+usbd_find_quirk(usb_device_descriptor_t *d)
+{
+ struct usbd_quirks *quirks;
+ /* although it should NEVER happen that this routine is called */
+ /* before the populate routine has been called, we check that */
+ /* the initialisation of the mutex has occured */
+ if (mtx_initialized(&dyn_mtx))
+ {
+ /* check the dynamic quirks list first for local entries */
+ mtx_lock(&dyn_mtx);
+ quirks = usbd_search_quirk((struct usbd_quirk_entry *) dynamic_usb_quirks, d);
+ mtx_unlock(&dyn_mtx);
+ if (quirks->uq_flags != 0)
+ return quirks;
+ }
+ /* check the compiled in quirks list if dynamic entry not set */
+ return(usbd_search_quirk((struct usbd_quirk_entry *) usb_quirks, d));
+}
+
+void usbd_populate_dynamic_quirks()
+{
+ /* the size of envkey must exceed the length of ENVNAMEROOT */
+ /* and the maximum number of digits in MAX_DYNAMIC_USB_QUIRKS plus 1 */
+ /* as the environment size is limitted to 512 entries and a maximum */
+ /* of 128 usb devices are supported 3 digits is appropriate for
+ all valid values of MAX_DYNAMIC_USB_QUIRKS */
+ const int envkeysz = strlen(ENVNAMEROOT)+3+1;
+ char envkey[envkeysz];
+ int i;
+ char *env;
+ char *pt;
+ char *e;
+ int n;
+ /* this routine should be first called well before any USB */
+ /* busses or devices are detected */
+ if (!mtx_initialized(&dyn_mtx))
+ mtx_init(&dyn_mtx, "usb_dynquirks", NULL, MTX_DEF);
+ mtx_lock(&dyn_mtx);
+ for (i=0; i<MAX_DYNAMIC_USB_QUIRKS; i++)
+ {
+ dynamic_usb_quirks[i].quirks.uq_flags = 0;
+ dynamic_usb_quirks[i].idVendor = 0;
+ dynamic_usb_quirks[i].idProduct = 0;
+ dynamic_usb_quirks[i].bcdDevice = 0;
+ snprintf(envkey,envkeysz,"%s%d",ENVNAMEROOT,i);
+ if (testenv(envkey))
+ {
+#ifdef USB_DEBUG
+ printf("usbd config %s\n", envkey);
+#endif
+ env = getenv(envkey);
+ dynamic_usb_quirks[i].idVendor = strtoul(env, &pt, 0);
+ dynamic_usb_quirks[i].idProduct = strtoul(pt, &pt, 0);
+ dynamic_usb_quirks[i].bcdDevice = strtoul(pt, &pt, 0);
+ /* skip anything which isn't a flag */
+ while (*pt && !isalpha(*pt)) pt++;
+ /* read in flags */
+ while (*pt)
+ {
+ e = strstr(pt,SEPCHAR);
+ if (!e)
+ {
+ n = strlen(pt);
+ }
+ else
+ {
+ n = e - pt;
+ }
+ if (!strncmp("USBDI_SWAP_UNICODE", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_SWAP_UNICODE;
+ if (!strncmp("MS_REVZ", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_MS_REVZ;
+ if (!strncmp("USBDI_NO_STRINGS", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_NO_STRINGS;
+ if (!strncmp("UAUDIO_BAD_ADC", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_BAD_ADC;
+ if (!strncmp("USB_BUS_POWERED", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_BUS_POWERED;
+ if (!strncmp("UAUDIO_BAD_AUDIO", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_BAD_AUDIO;
+ if (!strncmp("UMS_SPUR_BUT_UP", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_SPUR_BUT_UP;
+ if (!strncmp("UAUDIO_NO_XU", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_AU_NO_XU;
+ if (!strncmp("USB_POWER_CLAIM", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_POWER_CLAIM;
+ if (!strncmp("UAUDIO_NO_FRAC", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_AU_NO_FRAC;
+ if (!strncmp("UAUDIO_INP_ASYNC", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_AU_INP_ASYNC;
+ if (!strncmp("ULPT_BROKEN_BIDIR", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_BROKEN_BIDIR;
+ if (!strncmp("USB_OPEN_CLEARSTALL", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_OPEN_CLEARSTALL;
+ if (!strncmp("UHID_IGNORE", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_HID_IGNORE;
+ if (!strncmp("UKBD_IGNORE", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_KBD_IGNORE;
+ if (!strncmp("UMS_BAD_CLASS", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_MS_BAD_CLASS;
+ if (!strncmp("MS_LEADING_BYTE", pt, n))
+ dynamic_usb_quirks[i].quirks.uq_flags |= UQ_MS_LEADING_BYTE;
+ pt += n;
+ pt += strspn(pt, SEPCHAR);
+ }
+#ifdef USB_DEBUG
+ printf("usbd quirk %d %x %x %x %x\n",
+ dynamic_usb_quirks[i].quirks.uq_flags,
+ dynamic_usb_quirks[i].idVendor,
+ dynamic_usb_quirks[i].idProduct,
+ dynamic_usb_quirks[i].bcdDevice,
+ dynamic_usb_quirks[i].quirks.uq_flags
+ );
+#endif
+ freeenv(env);
+ }
+ else
+ {
+ break;
+ }
+ }
+ for (; i<MAX_DYNAMIC_USB_QUIRKS; i++)
+ {
+#ifdef USB_DEBUG
+ printf("usbd clear dynamic quirk %d\n", i);
+#endif
+ dynamic_usb_quirks[i].quirks.uq_flags = 0;
+ dynamic_usb_quirks[i].idVendor = 0;
+ dynamic_usb_quirks[i].idProduct = 0;
+ dynamic_usb_quirks[i].bcdDevice = 0;
+ snprintf(envkey,envkeysz,"%s%d",ENVNAMEROOT,i);
+ if (testenv(envkey))
+ {
+#ifdef USB_DEBUG
+ printf("usbd key %s invalid as earlier entry missing\n", envkey);
+#endif
+ }
+ }
+ mtx_unlock(&dyn_mtx);
+}
+
+SYSINIT(usbd_populate_dynamic_quirks, SI_SUB_KLD, SI_ORDER_MIDDLE,
+ usbd_populate_dynamic_quirks, NULL);
diff -ur /usr/src/sys/dev/usb/usb_quirks.h /scratch/src/sys/dev/usb/usb_quirks.h
--- /usr/src/sys/dev/usb/usb_quirks.h 2008-04-11 22:43:56.000000000 +1000
+++ /scratch/src/sys/dev/usb/usb_quirks.h 2008-04-16 11:09:35.000000000 +1000
@@ -62,3 +62,5 @@
extern const struct usbd_quirks usbd_no_quirk;
const struct usbd_quirks *usbd_find_quirk(usb_device_descriptor_t *);
+
+void usbd_populate_dynamic_quirks(void);
diff -rNu /usr/src/usr.bin/usbquirksload/Makefile /scratch/src/usr.bin/usbquirksload/Makefile
--- /usr/src/usr.bin/usbquirksload/Makefile 1970-01-01 10:00:00.000000000 +1000
+++ /scratch/src/usr.bin/usbquirksload/Makefile 2008-04-17 10:28:40.000000000 +1000
@@ -0,0 +1,7 @@
+# $NetBSD: Makefile,v 1.4 1999/05/11 21:02:25 augustss Exp $
+# $FreeBSD: src/usr.bin/usbhidctl/Makefile,v 1.4 2002/04/15 09:33:34 ru Exp $
+
+PROG= usbquirksload
+SRCS= usbquirksload.c
+
+.include <bsd.prog.mk>
diff -rNu /usr/src/usr.bin/usbquirksload/usbquirksload.1 /scratch/src/usr.bin/usbquirksload/usbquirksload.1
--- /usr/src/usr.bin/usbquirksload/usbquirksload.1 1970-01-01 10:00:00.000000000 +1000
+++ /scratch/src/usr.bin/usbquirksload/usbquirksload.1 2008-04-17 10:44:32.000000000 +1000
@@ -0,0 +1,50 @@
+.\" $FreeBSD$
+.\"
+.\" Copyright (c) 2008 The FreeBSD Project.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to the FreeBSD Project
+.\" by Maurice Castro.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd April 17, 2008
+.Dt USBQUIRKSLOAD 1
+.Os
+.Sh NAME
+.Nm usbquirksload
+.Nd Load usb dynamic quirks table from environment data
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+The
+.Nm
+utility loads the kernel's dynamic quirks table from strings contained in
+the kernel environment.
+.Sh SEE ALSO
+.Xr usb 4
+.Xr kenv 1
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Fx 7.0 .
diff -rNu /usr/src/usr.bin/usbquirksload/usbquirksload.c /scratch/src/usr.bin/usbquirksload/usbquirksload.c
--- /usr/src/usr.bin/usbquirksload/usbquirksload.c 1970-01-01 10:00:00.000000000 +1000
+++ /scratch/src/usr.bin/usbquirksload/usbquirksload.c 2008-04-17 10:40:13.000000000 +1000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2008 The FreeBSD Project.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to the FreeBSD Project
+ * by Maurice Castro.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dev/usb/usb.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+int main(int argc, char *argv[])
+{
+ int d, r;
+ d = open("/dev/usb0", O_RDONLY);
+ if (d == -1)
+ {
+ perror(argv[0]);
+ exit(1);
+ }
+ r = ioctl(d, USB_SETDYNQUIRKS, 0);
+ if (r == -1)
+ {
+ perror(argv[0]);
+ exit(2);
+ }
+ close(d);
+ exit(0);
+}
--Apple-Mail-4-388555214
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
Content-Transfer-Encoding: 7bit
--Apple-Mail-4-388555214--
More information about the freebsd-usb
mailing list