Skip to content

Commit b6a3805

Browse files
committed
firewire: core: detect numeric model identifier for legacy layout of configuration ROM
As the part of support for legacy layout of configuration ROM, this commit traverses vendor directory as well as root directory when showing device attribute for node device. This change expects 'model' attribute appears in node device, however it is probable to see the other types of immediate values if the vendor directory includes. Suggested-by: Adam Goldman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Sakamoto <[email protected]>
1 parent 58aae0a commit b6a3805

File tree

2 files changed

+49
-15
lines changed

2 files changed

+49
-15
lines changed

drivers/firewire/core-device.c

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,22 @@ int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value)
4949
}
5050
EXPORT_SYMBOL(fw_csr_iterator_next);
5151

52+
static const u32 *search_directory(const u32 *directory, int search_key)
53+
{
54+
struct fw_csr_iterator ci;
55+
int key, value;
56+
57+
search_key |= CSR_DIRECTORY;
58+
59+
fw_csr_iterator_init(&ci, directory);
60+
while (fw_csr_iterator_next(&ci, &key, &value)) {
61+
if (key == search_key)
62+
return ci.p - 1 + value;
63+
}
64+
65+
return NULL;
66+
}
67+
5268
static const u32 *search_leaf(const u32 *directory, int search_key)
5369
{
5470
struct fw_csr_iterator ci;
@@ -253,27 +269,44 @@ static ssize_t show_immediate(struct device *dev,
253269
struct config_rom_attribute *attr =
254270
container_of(dattr, struct config_rom_attribute, attr);
255271
struct fw_csr_iterator ci;
256-
const u32 *dir;
257-
int key, value, ret = -ENOENT;
272+
const u32 *directories[] = {NULL, NULL};
273+
int i, value = -1;
258274

259275
down_read(&fw_device_rwsem);
260276

261-
if (is_fw_unit(dev))
262-
dir = fw_unit(dev)->directory;
263-
else
264-
dir = fw_device(dev)->config_rom + ROOT_DIR_OFFSET;
277+
if (is_fw_unit(dev)) {
278+
directories[0] = fw_unit(dev)->directory;
279+
} else {
280+
const u32 *root_directory = fw_device(dev)->config_rom + ROOT_DIR_OFFSET;
281+
const u32 *vendor_directory = search_directory(root_directory, CSR_VENDOR);
265282

266-
fw_csr_iterator_init(&ci, dir);
267-
while (fw_csr_iterator_next(&ci, &key, &value))
268-
if (attr->key == key) {
269-
ret = snprintf(buf, buf ? PAGE_SIZE : 0,
270-
"0x%06x\n", value);
271-
break;
283+
if (!vendor_directory) {
284+
directories[0] = root_directory;
285+
} else {
286+
// Legacy layout of configuration ROM described in Annex 1 of
287+
// 'Configuration ROM for AV/C Devices 1.0 (December 12, 2000, 1394 Trading
288+
// Association, TA Document 1999027)'.
289+
directories[0] = vendor_directory;
290+
directories[1] = root_directory;
291+
}
292+
}
293+
294+
for (i = 0; i < ARRAY_SIZE(directories) && !!directories[i]; ++i) {
295+
int key, val;
296+
297+
fw_csr_iterator_init(&ci, directories[i]);
298+
while (fw_csr_iterator_next(&ci, &key, &val)) {
299+
if (attr->key == key)
300+
value = val;
272301
}
302+
}
273303

274304
up_read(&fw_device_rwsem);
275305

276-
return ret;
306+
if (value < 0)
307+
return -ENOENT;
308+
309+
return snprintf(buf, buf ? PAGE_SIZE : 0, "0x%06x\n", value);
277310
}
278311

279312
#define IMMEDIATE_ATTR(name, key) \

drivers/firewire/device-attribute-test.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,9 @@ static void device_attr_legacy_avc(struct kunit *test)
199199
KUNIT_EXPECT_GT(test, show_immediate(node_dev, &config_rom_attributes[0].attr, buf), 0);
200200
KUNIT_EXPECT_STREQ(test, buf, "0x012345\n");
201201

202-
// Model immediate entry is not found.
203-
KUNIT_EXPECT_LT(test, show_immediate(node_dev, &config_rom_attributes[4].attr, buf), 0);
202+
// Model immediate entry is found.
203+
KUNIT_EXPECT_GT(test, show_immediate(node_dev, &config_rom_attributes[4].attr, buf), 0);
204+
KUNIT_EXPECT_STREQ(test, buf, "0xfedcba\n");
204205

205206
// Descriptor leaf entry for vendor is not found.
206207
KUNIT_EXPECT_LT(test, show_text_leaf(node_dev, &config_rom_attributes[5].attr, buf), 0);

0 commit comments

Comments
 (0)