modpost: i2c aliases need no trailing wildcard

Not all device types need a wildcard at the end of their module
aliases. In particular, for i2c module aliases, the trailing wildcard
is not only unneeded, it could also cause the wrong driver to be
loaded.

As I2C devices have no IDs, i2c module aliases are simple, arbitrary
device names. For example:

$ /sbin/modinfo lm90
filename:       /lib/modules/2.6.25-git18/kernel/drivers/hwmon/lm90.ko
author:         Jean Delvare <khali@linux-fr.org>
description:    LM90/ADM1032 driver
license:        GPL
vermagic:       2.6.25-git18 mod_unload
depends:        hwmon
alias:          i2c:lm90*
alias:          i2c:adm1032*
alias:          i2c:lm99*
alias:          i2c:lm86*
alias:          i2c:max6657*
alias:          i2c:adt7461*
alias:          i2c:max6680*
$

This would cause trouble if one I2C chip name matches the beginning of
another I2C chip name and both chips are supported by different
drivers. For example, an i2c device named lm9042 would cause the lm90
driver to be loaded, while it doesn't support that device. This case
has yet to be seen in practice, but still, I'd like to fix it now. The
cleanest fix is to remove the trailing wildcard from i2c module aliases.

Here's a patch doing this.

Not all device type aliases need a trailing wildcard, in particular
the i2c aliases don't. Don't add a wildcard by default in do_table(),
instead let each device type handler add it if needed.

I have tested types acpi, dmi, eisa, i2c, ide, ieee1394, input, pci,
pcmcia, platform, pnp, scsi, serio, ssb and usb. Other types (ccw, of,
vio, parisc, sdio and virtio) are untested.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Acked-by: Jochen Friedrich <jochen@scram.de>
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
This commit is contained in:
Jean Delvare 2008-05-02 20:37:21 +02:00 committed by Sam Ravnborg
parent afa26be86b
commit ac55182899

View File

@ -51,6 +51,15 @@ do { \
sprintf(str + strlen(str), "*"); \
} while(0)
/* Always end in a wildcard, for future extension */
static inline void add_wildcard(char *str)
{
int len = strlen(str);
if (str[len - 1] != '*')
strcat(str + len, "*");
}
unsigned int cross_build = 0;
/**
* Check that sizeof(device_id type) are consistent with size of section
@ -133,9 +142,7 @@ static void do_usb_entry(struct usb_device_id *id,
id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
id->bInterfaceProtocol);
/* Always end in a wildcard, for future extension */
if (alias[strlen(alias)-1] != '*')
strcat(alias, "*");
add_wildcard(alias);
buf_printf(&mod->dev_table_buf,
"MODULE_ALIAS(\"%s\");\n", alias);
}
@ -219,6 +226,7 @@ static int do_ieee1394_entry(const char *filename,
ADD(alias, "ver", id->match_flags & IEEE1394_MATCH_VERSION,
id->version);
add_wildcard(alias);
return 1;
}
@ -261,6 +269,7 @@ static int do_pci_entry(const char *filename,
ADD(alias, "bc", baseclass_mask == 0xFF, baseclass);
ADD(alias, "sc", subclass_mask == 0xFF, subclass);
ADD(alias, "i", interface_mask == 0xFF, interface);
add_wildcard(alias);
return 1;
}
@ -283,6 +292,7 @@ static int do_ccw_entry(const char *filename,
id->dev_type);
ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL,
id->dev_model);
add_wildcard(alias);
return 1;
}
@ -290,7 +300,7 @@ static int do_ccw_entry(const char *filename,
static int do_ap_entry(const char *filename,
struct ap_device_id *id, char *alias)
{
sprintf(alias, "ap:t%02X", id->dev_type);
sprintf(alias, "ap:t%02X*", id->dev_type);
return 1;
}
@ -309,6 +319,7 @@ static int do_serio_entry(const char *filename,
ADD(alias, "id", id->id != SERIO_ANY, id->id);
ADD(alias, "ex", id->extra != SERIO_ANY, id->extra);
add_wildcard(alias);
return 1;
}
@ -316,7 +327,7 @@ static int do_serio_entry(const char *filename,
static int do_acpi_entry(const char *filename,
struct acpi_device_id *id, char *alias)
{
sprintf(alias, "acpi*:%s:", id->id);
sprintf(alias, "acpi*:%s:*", id->id);
return 1;
}
@ -324,7 +335,7 @@ static int do_acpi_entry(const char *filename,
static int do_pnp_entry(const char *filename,
struct pnp_device_id *id, char *alias)
{
sprintf(alias, "pnp:d%s", id->id);
sprintf(alias, "pnp:d%s*", id->id);
return 1;
}
@ -409,6 +420,7 @@ static int do_pcmcia_entry(const char *filename,
ADD(alias, "pc", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3, id->prod_id_hash[2]);
ADD(alias, "pd", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4, id->prod_id_hash[3]);
add_wildcard(alias);
return 1;
}
@ -432,6 +444,7 @@ static int do_of_entry (const char *filename, struct of_device_id *of, char *ali
if (isspace (*tmp))
*tmp = '_';
add_wildcard(alias);
return 1;
}
@ -448,6 +461,7 @@ static int do_vio_entry(const char *filename, struct vio_device_id *vio,
if (isspace (*tmp))
*tmp = '_';
add_wildcard(alias);
return 1;
}
@ -511,6 +525,8 @@ static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa,
{
if (eisa->sig[0])
sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", eisa->sig);
else
strcat(alias, "*");
return 1;
}
@ -529,6 +545,7 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id,
ADD(alias, "rev", id->hversion_rev != PA_HVERSION_REV_ANY_ID, id->hversion_rev);
ADD(alias, "sv", id->sversion != PA_SVERSION_ANY_ID, id->sversion);
add_wildcard(alias);
return 1;
}
@ -544,6 +561,7 @@ static int do_sdio_entry(const char *filename,
ADD(alias, "c", id->class != (__u8)SDIO_ANY_ID, id->class);
ADD(alias, "v", id->vendor != (__u16)SDIO_ANY_ID, id->vendor);
ADD(alias, "d", id->device != (__u16)SDIO_ANY_ID, id->device);
add_wildcard(alias);
return 1;
}
@ -559,6 +577,7 @@ static int do_ssb_entry(const char *filename,
ADD(alias, "v", id->vendor != SSB_ANY_VENDOR, id->vendor);
ADD(alias, "id", id->coreid != SSB_ANY_ID, id->coreid);
ADD(alias, "rev", id->revision != SSB_ANY_REV, id->revision);
add_wildcard(alias);
return 1;
}
@ -573,6 +592,7 @@ static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
ADD(alias, "d", 1, id->device);
ADD(alias, "v", id->vendor != VIRTIO_DEV_ANY_ID, id->vendor);
add_wildcard(alias);
return 1;
}
@ -612,9 +632,6 @@ static void do_table(void *symval, unsigned long size,
for (i = 0; i < size; i += id_size) {
if (do_entry(mod->name, symval+i, alias)) {
/* 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);
}