diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-02-15 18:22:05 -0500 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-06-05 10:26:17 -0400 |
commit | e41f8d709c31b42129a34305a99d29c38aff75c4 (patch) | |
tree | d361c3818d6e14f96555f0e6700aace29c7c449d /drivers/firewire/fw-device.c | |
parent | b3b2988841ac6215e137e34e38b71acc915d1f00 (diff) |
firewire: also use vendor ID in root directory for driver matches
Due to AV/C protocol extensions, FireDTV devices need a vendor-specific
driver. But their configuration ROM features a vendor ID only in the
root directory, not in the unit directory.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-device.c')
-rw-r--r-- | drivers/firewire/fw-device.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index 47b5b422616b..7d2f6135e009 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c | |||
@@ -58,7 +58,7 @@ EXPORT_SYMBOL(fw_csr_iterator_next); | |||
58 | 58 | ||
59 | static int is_fw_unit(struct device *dev); | 59 | static int is_fw_unit(struct device *dev); |
60 | 60 | ||
61 | static int match_unit_directory(u32 *directory, | 61 | static int match_unit_directory(u32 *directory, u32 match_flags, |
62 | const struct ieee1394_device_id *id) | 62 | const struct ieee1394_device_id *id) |
63 | { | 63 | { |
64 | struct fw_csr_iterator ci; | 64 | struct fw_csr_iterator ci; |
@@ -77,21 +77,31 @@ static int match_unit_directory(u32 *directory, | |||
77 | match |= IEEE1394_MATCH_VERSION; | 77 | match |= IEEE1394_MATCH_VERSION; |
78 | } | 78 | } |
79 | 79 | ||
80 | return (match & id->match_flags) == id->match_flags; | 80 | return (match & match_flags) == match_flags; |
81 | } | 81 | } |
82 | 82 | ||
83 | static int fw_unit_match(struct device *dev, struct device_driver *drv) | 83 | static int fw_unit_match(struct device *dev, struct device_driver *drv) |
84 | { | 84 | { |
85 | struct fw_unit *unit = fw_unit(dev); | 85 | struct fw_unit *unit = fw_unit(dev); |
86 | struct fw_driver *driver = fw_driver(drv); | 86 | struct fw_device *device; |
87 | int i; | 87 | const struct ieee1394_device_id *id; |
88 | 88 | ||
89 | /* We only allow binding to fw_units. */ | 89 | /* We only allow binding to fw_units. */ |
90 | if (!is_fw_unit(dev)) | 90 | if (!is_fw_unit(dev)) |
91 | return 0; | 91 | return 0; |
92 | 92 | ||
93 | for (i = 0; driver->id_table[i].match_flags != 0; i++) { | 93 | device = fw_device(unit->device.parent); |
94 | if (match_unit_directory(unit->directory, &driver->id_table[i])) | 94 | |
95 | for (id = fw_driver(drv)->id_table; id->match_flags != 0; id++) { | ||
96 | if (match_unit_directory(unit->directory, id->match_flags, id)) | ||
97 | return 1; | ||
98 | |||
99 | /* Also check vendor ID in the root directory. */ | ||
100 | if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) && | ||
101 | match_unit_directory(&device->config_rom[5], | ||
102 | IEEE1394_MATCH_VENDOR_ID, id) && | ||
103 | match_unit_directory(unit->directory, id->match_flags | ||
104 | & ~IEEE1394_MATCH_VENDOR_ID, id)) | ||
95 | return 1; | 105 | return 1; |
96 | } | 106 | } |
97 | 107 | ||