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