[PATCH] Devices that ignore USB spec generate invalid modaliases

From: Nathaniel McCallum
Date: Wed Nov 11 2009 - 03:20:31 EST


Please CC me as I'm not subscribed to LKML.

The current code to generate usb modaliases from usb_device_id assumes that the device's bcdDevice descriptor will actually be in BCD format. While this should be a sane assumption, some devices don't follow spec and just use plain old hex. This causes drivers for these devices to generate invalid modalias lines which will never actually match for the hardware.

The following patch adds hex support for bcdDevice in file2alias.c. Drivers for devices which have bcdDevice conforming to BCD will have no change in modalias output. Drivers for devices which don't conform (primarily usb-storage and ibmcam in my initial survey) should now generate valid modaliases.

EXAMPLE OUTPUT (ibmcam; space added to highlight change)
Old: usb:v0545p800D d030[10-9] dc*dsc*dp*ic*isc*ip*
New: usb:v0545p800D d030a dc*dsc*dp*ic*isc*ip*

Patch attached. Questions/comments welcome.

Nathaniel McCallum --- linux-2.6.31.orig/scripts/mod/file2alias.c 2009-09-09 18:13:59.000000000 -0400
+++ linux-2.6.31/scripts/mod/file2alias.c 2009-11-11 02:51:02.446894908 -0500
@@ -118,9 +118,20 @@
sprintf(alias + strlen(alias), "%0*X",
bcdDevice_initial_digits, bcdDevice_initial);
if (range_lo == range_hi)
- sprintf(alias + strlen(alias), "%u", range_lo);
- else if (range_lo > 0 || range_hi < 9)
- sprintf(alias + strlen(alias), "[%u-%u]", range_lo, range_hi);
+ sprintf(alias + strlen(alias), "%x", range_lo);
+ else if (range_lo > 0x0 || range_hi < 0xf) {
+ if (range_lo > 0x9 || range_hi < 0xa)
+ sprintf(alias + strlen(alias),
+ "[%x-%x]", range_lo, range_hi);
+ else {
+ sprintf(alias + strlen(alias),
+ range_lo < 0x9 ? "[%x-9" : "[%x",
+ range_lo);
+ sprintf(alias + strlen(alias),
+ range_hi > 0xa ? "a-%x]" : "%x]",
+ range_hi);
+ }
+ }
if (bcdDevice_initial_digits < (sizeof(id->bcdDevice_lo) * 2 - 1))
strcat(alias, "*");

@@ -173,8 +184,6 @@
for (ndigits = sizeof(id->bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) {
clo = devlo & 0xf;
chi = devhi & 0xf;
- if (chi > 9) /* it's bcd not hex */
- chi = 9;
devlo >>= 4;
devhi >>= 4;

@@ -184,10 +193,10 @@
}

if (clo > 0)
- do_usb_entry(id, devlo++, ndigits, clo, 9, mod);
+ do_usb_entry(id, devlo++, ndigits, clo, 0xf, mod);

- if (chi < 9)
- do_usb_entry(id, devhi--, ndigits, 0, chi, mod);
+ if (chi < 0xf)
+ do_usb_entry(id, devhi--, ndigits, 0x0, chi, mod);
}
}