From: Roman Kagan <rkagan@mail.ru>
To: linux-hotplug@vger.kernel.org
Subject: [PATCH] scripts/mod/file2alias.c: handle numeric ranges for USB bcdDevice
Date: Sat, 26 Feb 2005 16:55:21 +0000 [thread overview]
Message-ID: <20050226165517.GA2404@katya> (raw)
Hi,
The attached patch fixes the longstanding problem with USB bcdDevice
numeric ranges incorrectly converted into patterns for MODULE_ALIAS
generation. Previously it put both the lower and the upper limits into
the pattern, dlXdhY, making it impossible to fnmatch against except for
a few special cases, like dl*dh* or dlXdhX.
The patch makes it generate multiple MODULE_ALIAS lines covering the
whole range with fnmatch-able patterns. E.g. for a range between 0x0001
and 0xa345 it gives the following patterns:
000[123456789ABCDEF]*
00[123456789ABCDEF]*
0[123456789ABCDEF]*
[123456789]*
A[012]*
A3[0123]*
A34[012345]*
Since bcdDevice is 2 bytes wide = 4 digits in hex representation, the
max no. of patters is 2 * 4 - 1 = 7.
Explicit lists of allowed characters inside brackets are used to avoid
dependencies on locale collation order with patterns using a dash, like
[3-B].
The patch uses "d" prefix for bcdDevice; the most common (and almost the
only working) case of dl*dh* becomes d* and thus continues to work.
Please consider applying.
Roman.
Signed-off-by: Roman Kagan <rkagan@mail.ru>
scripts/mod/file2alias.c | 112 +++++++++++++++++++++++++++++++++++++----------
1 files changed, 89 insertions(+), 23 deletions(-)
--- linux-2.6.11-rc4/scripts/mod/file2alias.c.orig 2005-02-13 06:06:23.000000000 +0300
+++ linux-2.6.11-rc4/scripts/mod/file2alias.c 2005-02-26 19:15:49.769160544 +0300
@@ -47,32 +47,34 @@ do {
sprintf(str + strlen(str), "*"); \
} while(0)
-/* Looks like "usb:vNpNdlNdhNdcNdscNdpNicNiscNipN" */
-static int do_usb_entry(const char *filename,
- struct usb_device_id *id, char *alias)
+/* USB is special because the bcdDevice can be matched against a numeric range */
+/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */
+static void do_usb_entry(struct usb_device_id *id,
+ unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
+ unsigned char range_lo, unsigned char range_hi,
+ struct module *mod)
{
- id->match_flags = TO_NATIVE(id->match_flags);
- id->idVendor = TO_NATIVE(id->idVendor);
- id->idProduct = TO_NATIVE(id->idProduct);
- id->bcdDevice_lo = TO_NATIVE(id->bcdDevice_lo);
- id->bcdDevice_hi = TO_NATIVE(id->bcdDevice_hi);
-
- /*
- * Some modules (visor) have empty slots as placeholder for
- * run-time specification that results in catch-all alias
- */
- if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass))
- return 1;
-
+ static const char hexdigits[] = "0123456789ABCDEF";
+ char alias[500];
strcpy(alias, "usb:");
ADD(alias, "v", id->match_flags&USB_DEVICE_ID_MATCH_VENDOR,
id->idVendor);
ADD(alias, "p", id->match_flags&USB_DEVICE_ID_MATCH_PRODUCT,
id->idProduct);
- ADD(alias, "dl", id->match_flags&USB_DEVICE_ID_MATCH_DEV_LO,
- id->bcdDevice_lo);
- ADD(alias, "dh", id->match_flags&USB_DEVICE_ID_MATCH_DEV_HI,
- id->bcdDevice_hi);
+
+ strcat(alias, "d");
+ if (bcdDevice_initial_digits)
+ sprintf(alias + strlen(alias), "%0*X",
+ bcdDevice_initial_digits, bcdDevice_initial);
+ if (range_lo = range_hi)
+ strncat(alias, hexdigits + range_lo, 1);
+ else if (range_lo > 0x0 || range_hi < 0xf) {
+ strcat(alias, "[");
+ strncat(alias, hexdigits + range_lo, range_hi - range_lo + 1);
+ strcat(alias, "]");
+ }
+ strcat(alias, "*");
+
ADD(alias, "dc", id->match_flags&USB_DEVICE_ID_MATCH_DEV_CLASS,
id->bDeviceClass);
ADD(alias, "dsc",
@@ -90,7 +92,71 @@ static int do_usb_entry(const char *file
ADD(alias, "ip",
id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
id->bInterfaceProtocol);
- return 1;
+
+ /* Always end in a wildcard, for future extension */
+ if (alias[strlen(alias)-1] != '*')
+ strcat(alias, "*");
+ buf_printf(&mod->dev_table_buf,
+ "MODULE_ALIAS(\"%s\");\n", alias);
+}
+
+static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
+{
+ unsigned int devlo, devhi;
+ unsigned char chi, clo;
+ int ndigits;
+
+ id->match_flags = TO_NATIVE(id->match_flags);
+ id->idVendor = TO_NATIVE(id->idVendor);
+ id->idProduct = TO_NATIVE(id->idProduct);
+
+ devlo = id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO ?
+ TO_NATIVE(id->bcdDevice_lo) : 0x0U;
+ devhi = id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI ?
+ TO_NATIVE(id->bcdDevice_hi) : ~0x0U;
+
+ /*
+ * Some modules (visor) have empty slots as placeholder for
+ * run-time specification that results in catch-all alias
+ */
+ if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass))
+ return;
+
+ /* Convert numeric bcdDevice range into fnmatch-able pattern(s) */
+ for (ndigits = sizeof(id->bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) {
+ clo = devlo & 0xf;
+ chi = devhi & 0xf;
+ devlo >>= 4;
+ devhi >>= 4;
+
+ if (devlo = devhi || !ndigits) {
+ do_usb_entry(id, devlo, ndigits, clo, chi, mod);
+ break;
+ }
+
+ if (clo != 0x0)
+ do_usb_entry(id, devlo++, ndigits, clo, 0xf, mod);
+
+ if (chi != 0xf)
+ do_usb_entry(id, devhi--, ndigits, 0x0, chi, mod);
+ }
+}
+
+static void do_usb_table(void *symval, unsigned long size,
+ struct module *mod)
+{
+ unsigned int i;
+ const unsigned long id_size = sizeof(struct usb_device_id);
+
+ if (size % id_size || size < id_size) {
+ fprintf(stderr, "*** Warning: %s ids %lu bad size "
+ "(each on %lu)\n", mod->name, size, id_size);
+ }
+ /* Leave last one: it's the terminator. */
+ size -= id_size;
+
+ for (i = 0; i < size; i += id_size)
+ do_usb_entry_multi(symval + i, mod);
}
/* Looks like: ieee1394:venNmoNspNverN */
@@ -262,8 +328,8 @@ void handle_moddevtable(struct module *m
do_table(symval, sym->st_size, sizeof(struct pci_device_id),
do_pci_entry, mod);
else if (sym_is(symname, "__mod_usb_device_table"))
- do_table(symval, sym->st_size, sizeof(struct usb_device_id),
- do_usb_entry, mod);
+ /* special case to handle bcdDevice ranges */
+ do_usb_table(symval, sym->st_size, mod);
else if (sym_is(symname, "__mod_ieee1394_device_table"))
do_table(symval, sym->st_size, sizeof(struct ieee1394_device_id),
do_ieee1394_entry, mod);
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
next reply other threads:[~2005-02-26 16:55 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-02-26 16:55 Roman Kagan [this message]
2005-03-27 20:19 ` [PATCH] scripts/mod/file2alias.c: handle numeric ranges for USB bcdDevice Roman Kagan
2005-03-28 10:11 ` Erik van Konijnenburg
2005-04-05 8:30 ` [linux-usb-devel] " Roman Kagan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050226165517.GA2404@katya \
--to=rkagan@mail.ru \
--cc=linux-hotplug@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).