summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2010-03-19 00:39:07 +0100
committerStefan Richter <stefanr@s5r6.in-berlin.de>2010-03-24 22:01:47 +0100
commitfe43d6d9cf59d8f8cbfdcde2018de13ffd1285c7 (patch)
tree4eb14adaa43b7746cd8e0bc5416281b5d3839f9c /drivers
parent5ae73518cb39dd81e641dfa7ce20751c853579e0 (diff)
downloadlinux-fe43d6d9cf59d8f8cbfdcde2018de13ffd1285c7.tar.gz
linux-fe43d6d9cf59d8f8cbfdcde2018de13ffd1285c7.tar.bz2
linux-fe43d6d9cf59d8f8cbfdcde2018de13ffd1285c7.zip
firewire: core: align driver match with modalias
The driver match strategy was: - Match vendor/model/specifier/version of the unit directory. - If that was a miss, match vendor from the root directory and model/specifier/version of the unit directory. This was inconsistent with how the modalias string was constructed until recently (take vendor/model from root directory and specifier/ version from unit directory). It was also inconsistent with how it is done since the parent commit: - Use vendor/model/specifier/version of the unit directory if possible, - fall back to one or more of vendor/model/specifier/version from the root directory depending on which ones are not present at the unit directory. Fix this inconsistency by sharing the ROM scanner function between modalias printer function and driver match function. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/firewire/core-device.c87
1 files changed, 38 insertions, 49 deletions
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index c91d7179eb96..92b633d643f2 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -127,81 +127,70 @@ int fw_csr_string(const u32 *directory, int key, char *buf, size_t size)
}
EXPORT_SYMBOL(fw_csr_string);
-static bool is_fw_unit(struct device *dev);
-
-static int match_unit_directory(const u32 *directory, u32 match_flags,
- const struct ieee1394_device_id *id)
+static void get_ids(const u32 *directory, int *id)
{
struct fw_csr_iterator ci;
- int key, value, match;
+ int key, value;
- match = 0;
fw_csr_iterator_init(&ci, directory);
while (fw_csr_iterator_next(&ci, &key, &value)) {
- if (key == CSR_VENDOR && value == id->vendor_id)
- match |= IEEE1394_MATCH_VENDOR_ID;
- if (key == CSR_MODEL && value == id->model_id)
- match |= IEEE1394_MATCH_MODEL_ID;
- if (key == CSR_SPECIFIER_ID && value == id->specifier_id)
- match |= IEEE1394_MATCH_SPECIFIER_ID;
- if (key == CSR_VERSION && value == id->version)
- match |= IEEE1394_MATCH_VERSION;
+ switch (key) {
+ case CSR_VENDOR: id[0] = value; break;
+ case CSR_MODEL: id[1] = value; break;
+ case CSR_SPECIFIER_ID: id[2] = value; break;
+ case CSR_VERSION: id[3] = value; break;
+ }
}
+}
- return (match & match_flags) == match_flags;
+static void get_modalias_ids(struct fw_unit *unit, int *id)
+{
+ get_ids(&fw_parent_device(unit)->config_rom[5], id);
+ get_ids(unit->directory, id);
+}
+
+static bool match_ids(const struct ieee1394_device_id *id_table, int *id)
+{
+ int match = 0;
+
+ if (id[0] == id_table->vendor_id)
+ match |= IEEE1394_MATCH_VENDOR_ID;
+ if (id[1] == id_table->model_id)
+ match |= IEEE1394_MATCH_MODEL_ID;
+ if (id[2] == id_table->specifier_id)
+ match |= IEEE1394_MATCH_SPECIFIER_ID;
+ if (id[3] == id_table->version)
+ match |= IEEE1394_MATCH_VERSION;
+
+ return (match & id_table->match_flags) == id_table->match_flags;
}
+static bool is_fw_unit(struct device *dev);
+
static int fw_unit_match(struct device *dev, struct device_driver *drv)
{
- struct fw_unit *unit = fw_unit(dev);
- struct fw_device *device;
- const struct ieee1394_device_id *id;
+ const struct ieee1394_device_id *id_table =
+ container_of(drv, struct fw_driver, driver)->id_table;
+ int id[] = {0, 0, 0, 0};
/* We only allow binding to fw_units. */
if (!is_fw_unit(dev))
return 0;
- device = fw_parent_device(unit);
- id = container_of(drv, struct fw_driver, driver)->id_table;
+ get_modalias_ids(fw_unit(dev), id);
- for (; id->match_flags != 0; id++) {
- if (match_unit_directory(unit->directory, id->match_flags, id))
+ for (; id_table->match_flags != 0; id_table++)
+ if (match_ids(id_table, id))
return 1;
- /* Also check vendor ID in the root directory. */
- if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
- match_unit_directory(&device->config_rom[5],
- IEEE1394_MATCH_VENDOR_ID, id) &&
- match_unit_directory(unit->directory, id->match_flags
- & ~IEEE1394_MATCH_VENDOR_ID, id))
- return 1;
- }
-
return 0;
}
-static void get_modalias_ids(const u32 *directory, int *id)
-{
- struct fw_csr_iterator ci;
- int key, value;
-
- fw_csr_iterator_init(&ci, directory);
- while (fw_csr_iterator_next(&ci, &key, &value)) {
- switch (key) {
- case CSR_VENDOR: id[0] = value; break;
- case CSR_MODEL: id[1] = value; break;
- case CSR_SPECIFIER_ID: id[2] = value; break;
- case CSR_VERSION: id[3] = value; break;
- }
- }
-}
-
static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
{
int id[] = {0, 0, 0, 0};
- get_modalias_ids(&fw_parent_device(unit)->config_rom[5], id);
- get_modalias_ids(unit->directory, id);
+ get_modalias_ids(unit, id);
return snprintf(buffer, buffer_size,
"ieee1394:ven%08Xmo%08Xsp%08Xver%08X",