aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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)
127} 127}
128EXPORT_SYMBOL(fw_csr_string); 128EXPORT_SYMBOL(fw_csr_string);
129 129
130static bool is_fw_unit(struct device *dev); 130static void get_ids(const u32 *directory, int *id)
131
132static int match_unit_directory(const u32 *directory, u32 match_flags,
133 const struct ieee1394_device_id *id)
134{ 131{
135 struct fw_csr_iterator ci; 132 struct fw_csr_iterator ci;
136 int key, value, match; 133 int key, value;
137 134
138 match = 0;
139 fw_csr_iterator_init(&ci, directory); 135 fw_csr_iterator_init(&ci, directory);
140 while (fw_csr_iterator_next(&ci, &key, &value)) { 136 while (fw_csr_iterator_next(&ci, &key, &value)) {
141 if (key == CSR_VENDOR && value == id->vendor_id) 137 switch (key) {
142 match |= IEEE1394_MATCH_VENDOR_ID; 138 case CSR_VENDOR: id[0] = value; break;
143 if (key == CSR_MODEL && value == id->model_id) 139 case CSR_MODEL: id[1] = value; break;
144 match |= IEEE1394_MATCH_MODEL_ID; 140 case CSR_SPECIFIER_ID: id[2] = value; break;
145 if (key == CSR_SPECIFIER_ID && value == id->specifier_id) 141 case CSR_VERSION: id[3] = value; break;
146 match |= IEEE1394_MATCH_SPECIFIER_ID; 142 }
147 if (key == CSR_VERSION && value == id->version)
148 match |= IEEE1394_MATCH_VERSION;
149 } 143 }
144}
150 145
151 return (match & match_flags) == match_flags; 146static void get_modalias_ids(struct fw_unit *unit, int *id)
147{
148 get_ids(&fw_parent_device(unit)->config_rom[5], id);
149 get_ids(unit->directory, id);
150}
151
152static bool match_ids(const struct ieee1394_device_id *id_table, int *id)
153{
154 int match = 0;
155
156 if (id[0] == id_table->vendor_id)
157 match |= IEEE1394_MATCH_VENDOR_ID;
158 if (id[1] == id_table->model_id)
159 match |= IEEE1394_MATCH_MODEL_ID;
160 if (id[2] == id_table->specifier_id)
161 match |= IEEE1394_MATCH_SPECIFIER_ID;
162 if (id[3] == id_table->version)
163 match |= IEEE1394_MATCH_VERSION;
164
165 return (match & id_table->match_flags) == id_table->match_flags;
152} 166}
153 167
168static bool is_fw_unit(struct device *dev);
169
154static int fw_unit_match(struct device *dev, struct device_driver *drv) 170static int fw_unit_match(struct device *dev, struct device_driver *drv)
155{ 171{
156 struct fw_unit *unit = fw_unit(dev); 172 const struct ieee1394_device_id *id_table =
157 struct fw_device *device; 173 container_of(drv, struct fw_driver, driver)->id_table;
158 const struct ieee1394_device_id *id; 174 int id[] = {0, 0, 0, 0};
159 175
160 /* We only allow binding to fw_units. */ 176 /* We only allow binding to fw_units. */
161 if (!is_fw_unit(dev)) 177 if (!is_fw_unit(dev))
162 return 0; 178 return 0;
163 179
164 device = fw_parent_device(unit); 180 get_modalias_ids(fw_unit(dev), id);
165 id = container_of(drv, struct fw_driver, driver)->id_table;
166 181
167 for (; id->match_flags != 0; id++) { 182 for (; id_table->match_flags != 0; id_table++)
168 if (match_unit_directory(unit->directory, id->match_flags, id)) 183 if (match_ids(id_table, id))
169 return 1; 184 return 1;
170 185
171 /* Also check vendor ID in the root directory. */
172 if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
173 match_unit_directory(&device->config_rom[5],
174 IEEE1394_MATCH_VENDOR_ID, id) &&
175 match_unit_directory(unit->directory, id->match_flags
176 & ~IEEE1394_MATCH_VENDOR_ID, id))
177 return 1;
178 }
179
180 return 0; 186 return 0;
181} 187}
182 188
183static void get_modalias_ids(const u32 *directory, int *id)
184{
185 struct fw_csr_iterator ci;
186 int key, value;
187
188 fw_csr_iterator_init(&ci, directory);
189 while (fw_csr_iterator_next(&ci, &key, &value)) {
190 switch (key) {
191 case CSR_VENDOR: id[0] = value; break;
192 case CSR_MODEL: id[1] = value; break;
193 case CSR_SPECIFIER_ID: id[2] = value; break;
194 case CSR_VERSION: id[3] = value; break;
195 }
196 }
197}
198
199static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size) 189static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
200{ 190{
201 int id[] = {0, 0, 0, 0}; 191 int id[] = {0, 0, 0, 0};
202 192
203 get_modalias_ids(&fw_parent_device(unit)->config_rom[5], id); 193 get_modalias_ids(unit, id);
204 get_modalias_ids(unit->directory, id);
205 194
206 return snprintf(buffer, buffer_size, 195 return snprintf(buffer, buffer_size,
207 "ieee1394:ven%08Xmo%08Xsp%08Xver%08X", 196 "ieee1394:ven%08Xmo%08Xsp%08Xver%08X",