aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorNathaniel McCallum <nathaniel@natemccallum.com>2009-11-18 20:11:23 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:55:20 -0500
commitafe2dab4f6d32d5650aaba42f2c7ec9c0622f4dd (patch)
treeb733d1e21f6482a46a262b25e15f4e628e74464b /scripts
parentc1479a92cf0a7792298d364e44a781550621cb58 (diff)
USB: add hex/bcd detection to usb modalias generation
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 by detecting when a driver uses a hex formatted bcdDevice_(lo|hi) and adjusts the output to hex format accordingly. Drivers for devices which have bcdDevice conforming to BCD will have no change in modalias output. Drivers for devices which don't conform (i.e. ibmcam) 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* Signed-off-by: Nathaniel McCallum <nathaniel@natemccallum.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/mod/file2alias.c48
1 files changed, 36 insertions, 12 deletions
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 62a9025cdcc7..e31f03aaf294 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -104,7 +104,7 @@ static void device_id_check(const char *modname, const char *device_id,
104static void do_usb_entry(struct usb_device_id *id, 104static void do_usb_entry(struct usb_device_id *id,
105 unsigned int bcdDevice_initial, int bcdDevice_initial_digits, 105 unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
106 unsigned char range_lo, unsigned char range_hi, 106 unsigned char range_lo, unsigned char range_hi,
107 struct module *mod) 107 unsigned char max, struct module *mod)
108{ 108{
109 char alias[500]; 109 char alias[500];
110 strcpy(alias, "usb:"); 110 strcpy(alias, "usb:");
@@ -118,9 +118,22 @@ static void do_usb_entry(struct usb_device_id *id,
118 sprintf(alias + strlen(alias), "%0*X", 118 sprintf(alias + strlen(alias), "%0*X",
119 bcdDevice_initial_digits, bcdDevice_initial); 119 bcdDevice_initial_digits, bcdDevice_initial);
120 if (range_lo == range_hi) 120 if (range_lo == range_hi)
121 sprintf(alias + strlen(alias), "%u", range_lo); 121 sprintf(alias + strlen(alias), "%X", range_lo);
122 else if (range_lo > 0 || range_hi < 9) 122 else if (range_lo > 0 || range_hi < max) {
123 sprintf(alias + strlen(alias), "[%u-%u]", range_lo, range_hi); 123 if (range_lo > 0x9 || range_hi < 0xA)
124 sprintf(alias + strlen(alias),
125 "[%X-%X]",
126 range_lo,
127 range_hi);
128 else {
129 sprintf(alias + strlen(alias),
130 range_lo < 0x9 ? "[%X-9" : "[%X",
131 range_lo);
132 sprintf(alias + strlen(alias),
133 range_hi > 0xA ? "a-%X]" : "%X]",
134 range_lo);
135 }
136 }
124 if (bcdDevice_initial_digits < (sizeof(id->bcdDevice_lo) * 2 - 1)) 137 if (bcdDevice_initial_digits < (sizeof(id->bcdDevice_lo) * 2 - 1))
125 strcat(alias, "*"); 138 strcat(alias, "*");
126 139
@@ -150,7 +163,7 @@ static void do_usb_entry(struct usb_device_id *id,
150static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod) 163static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
151{ 164{
152 unsigned int devlo, devhi; 165 unsigned int devlo, devhi;
153 unsigned char chi, clo; 166 unsigned char chi, clo, max;
154 int ndigits; 167 int ndigits;
155 168
156 id->match_flags = TO_NATIVE(id->match_flags); 169 id->match_flags = TO_NATIVE(id->match_flags);
@@ -162,6 +175,17 @@ static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
162 devhi = id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI ? 175 devhi = id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI ?
163 TO_NATIVE(id->bcdDevice_hi) : ~0x0U; 176 TO_NATIVE(id->bcdDevice_hi) : ~0x0U;
164 177
178 /* Figure out if this entry is in bcd or hex format */
179 max = 0x9; /* Default to decimal format */
180 for (ndigits = 0 ; ndigits < sizeof(id->bcdDevice_lo) * 2 ; ndigits++) {
181 clo = (devlo >> (ndigits << 2)) & 0xf;
182 chi = ((devhi > 0x9999 ? 0x9999 : devhi) >> (ndigits << 2)) & 0xf;
183 if (clo > max || chi > max) {
184 max = 0xf;
185 break;
186 }
187 }
188
165 /* 189 /*
166 * Some modules (visor) have empty slots as placeholder for 190 * Some modules (visor) have empty slots as placeholder for
167 * run-time specification that results in catch-all alias 191 * run-time specification that results in catch-all alias
@@ -173,21 +197,21 @@ static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
173 for (ndigits = sizeof(id->bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) { 197 for (ndigits = sizeof(id->bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) {
174 clo = devlo & 0xf; 198 clo = devlo & 0xf;
175 chi = devhi & 0xf; 199 chi = devhi & 0xf;
176 if (chi > 9) /* it's bcd not hex */ 200 if (chi > max) /* If we are in bcd mode, truncate if necessary */
177 chi = 9; 201 chi = max;
178 devlo >>= 4; 202 devlo >>= 4;
179 devhi >>= 4; 203 devhi >>= 4;
180 204
181 if (devlo == devhi || !ndigits) { 205 if (devlo == devhi || !ndigits) {
182 do_usb_entry(id, devlo, ndigits, clo, chi, mod); 206 do_usb_entry(id, devlo, ndigits, clo, chi, max, mod);
183 break; 207 break;
184 } 208 }
185 209
186 if (clo > 0) 210 if (clo > 0x0)
187 do_usb_entry(id, devlo++, ndigits, clo, 9, mod); 211 do_usb_entry(id, devlo++, ndigits, clo, max, max, mod);
188 212
189 if (chi < 9) 213 if (chi < max)
190 do_usb_entry(id, devhi--, ndigits, 0, chi, mod); 214 do_usb_entry(id, devhi--, ndigits, 0x0, chi, max, mod);
191 } 215 }
192} 216}
193 217