From owner-freebsd-usb@FreeBSD.ORG Thu Apr 17 03:10:04 2008 Return-Path: Delivered-To: freebsd-usb@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2ED87106564A for ; Thu, 17 Apr 2008 03:10:04 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 109B58FC18 for ; Thu, 17 Apr 2008 03:10:04 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m3H3A39h048397 for ; Thu, 17 Apr 2008 03:10:03 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m3H3A3gP048390; Thu, 17 Apr 2008 03:10:03 GMT (envelope-from gnats) Date: Thu, 17 Apr 2008 03:10:03 GMT Message-Id: <200804170310.m3H3A3gP048390@freefall.freebsd.org> To: freebsd-usb@FreeBSD.org From: Maurice Castro Cc: Subject: Re: usb/122819: Patch to provide dynamic additions to the usb quirks table X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Maurice Castro List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 Apr 2008 03:10:04 -0000 The following reply was made to PR usb/122819; it has been noted by GNATS. From: Maurice Castro 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: Thu, 17 Apr 2008 12:23:36 +1000 --Apple-Mail-2-311066617 Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Hi Hans, in addition to the corrections below I have added an extra utility to the system this utility calls the ioctl to load the dynamic quirks table. Patch is attached. As noted below I have not incorporated the bsearch for the reasons stated. Maurice Castro From: Hans Petter Selasky Date: Wed, 16 Apr 2008 18:54:02 +0200 > Hi, > > Maybe you can prefix the string version of the quirks by the USB > module name ? > > For example: > > MS_REVZ -> UMS_REVZ > AU_NO_FRAC -> UAUDIO_NO_FRAC > Done > Then it is easier to know where the quirk belongs. > > Add a short description of what the quirk does in the "usb" manpage. > Done > There might be a race condition reading and writing the quirks. > Probably a > mutex is appropriate. > Done > You can improve the quirk string to numerical conversion code by > using binary > search. > Wrote code to use bsearch and then backed it out. Value of binary searching on lists less than 20 items is minimal and required additional memory copy operation and release, due to non-destructive parsing technique used on environment variables. > Else your patch looks fine to me. --Apple-Mail-2-311066617 Content-Disposition: attachment; filename=usb.diff Content-Type: application/octet-stream; x-unix-mode=0644; name="usb.diff" Content-Transfer-Encoding: 7bit diff -ru /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-17 08:39:01.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 USWAP_UNICODE +has some Unicode strings swapped. +.It UMS_REVZ +mouse has Z-axis reversed +.It UNO_STRINGS +string descriptors are broken. +.It UBAD_ADC +bad audio spec version number. +.It UBUS_POWERED +device is bus powered, despite claim +.It UBAD_AUDIO +device claims audio class, but isn't +.It USPUR_BUT_UP +spurious mouse button up events +.It UAU_NO_XU +audio device has broken extension unit +.It UPOWER_CLAIM +hub lies about power status +.It UAU_NO_FRAC +don't adjust for fractional samples +.It UAU_INP_ASYNC +input is async despite claim of adaptive +.It UBROKEN_BIDIR +printer has broken bidir mode +.It UOPEN_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 UMS_LEADING_BYTE +mouse sends an unknown leading byte. +.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 -ru /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 -ru /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 -ru /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-17 12:02:12.000000000 +1000 @@ -42,8 +42,13 @@ #include #include +#include +#include +#include +#include #include +#include #include "usbdevs.h" #include @@ -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 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 +#include +#include +#include +#include + +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-2-311066617 Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit --Apple-Mail-2-311066617--