All of lore.kernel.org
 help / color / mirror / Atom feed
From: Roman Kagan <rkagan@mail.ru>
To: linux-hotplug@vger.kernel.org
Subject: Re: [PATCH] scripts/mod/file2alias.c: handle numeric ranges for USB bcdDevice
Date: Sun, 27 Mar 2005 20:19:36 +0000	[thread overview]
Message-ID: <20050327201936.GC2224@katya> (raw)
In-Reply-To: <20050226165517.GA2404@katya>

On Fri, Mar 25, 2005 at 09:40:48AM -0800, Greg KH wrote:
> On Fri, Mar 25, 2005 at 10:43:01AM +0300, Roman Kagan wrote:
> > > > The patch expects a matching change in scripts/mod/file2alias.c I sent
> > > > to linux-hotplug-devel list a few days ago (i.e. puts
> > > > bcdDevice in MODNAME as dXXXX, rather that dlXXXXdhXXXX).
> > > 
> > > I changed this back, as this change doesn't seem to have gone anywhere.
> > 
> > It was sent to linux-hotplug-devel and cc to you on Feb. 26, as I
> > thought it was up to you to include it.  Has it got lost and should I
> > resend it, or should I better send it to another list?  I think it's
> > worth merging as the current scheme bites everybody with nontrivial
> > bcdDevice range.
> 
> Ok, care to resend it?  I saw a lot of different patches floating
> around, and didn't know which one was the decided apon best fix.

Sure, here you are.  This is the latest version of the patch I sent on
Feb 26.  Erik van Konijnenburg reviewed it and was OK with it
(Erik mind adding your Signed-off-by?), so it's "decided upon best" by
the two of us :)

  Roman.

================
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

  reply	other threads:[~2005-03-27 20:19 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-26 16:55 [PATCH] scripts/mod/file2alias.c: handle numeric ranges for USB bcdDevice Roman Kagan
2005-03-27 20:19 ` Roman Kagan [this message]
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=20050327201936.GC2224@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.