Date: Fri, 18 Apr 2008 00:00:04 GMT From: Maurice Castro <maurice@castro.aus.net> To: freebsd-usb@FreeBSD.org Subject: Re: usb/122819: Patch to provide dynamic additions to the usb quirks table Message-ID: <200804180000.m3I004WD000489@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR usb/122819; it has been noted by GNATS. From: Maurice Castro <maurice@castro.aus.net> To: bug-followup@FreeBSD.org, maurice@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@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--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200804180000.m3I004WD000489>