diff options
Diffstat (limited to 'drivers/firewire/core-device.c')
-rw-r--r-- | drivers/firewire/core-device.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 2c8771305aca..fd4c025a3f70 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -317,17 +317,29 @@ static ssize_t show_text_leaf(struct device *dev, { struct config_rom_attribute *attr = container_of(dattr, struct config_rom_attribute, attr); - const u32 *dir; + const u32 *directories[] = {NULL, NULL}; size_t bufsize; char dummy_buf[2]; - int ret; + int i, ret = -ENOENT; down_read(&fw_device_rwsem); - if (is_fw_unit(dev)) - dir = fw_unit(dev)->directory; - else - dir = fw_device(dev)->config_rom + ROOT_DIR_OFFSET; + if (is_fw_unit(dev)) { + directories[0] = fw_unit(dev)->directory; + } else { + const u32 *root_directory = fw_device(dev)->config_rom + ROOT_DIR_OFFSET; + const u32 *vendor_directory = search_directory(root_directory, CSR_VENDOR); + + if (!vendor_directory) { + directories[0] = root_directory; + } else { + // Legacy layout of configuration ROM described in Annex 1 of + // 'Configuration ROM for AV/C Devices 1.0 (December 12, 2000, 1394 + // Trading Association, TA Document 1999027)'. + directories[0] = root_directory; + directories[1] = vendor_directory; + } + } if (buf) { bufsize = PAGE_SIZE - 1; @@ -336,7 +348,12 @@ static ssize_t show_text_leaf(struct device *dev, bufsize = 1; } - ret = fw_csr_string(dir, attr->key, buf, bufsize); + for (i = 0; i < ARRAY_SIZE(directories) && !!directories[i]; ++i) { + int result = fw_csr_string(directories[i], attr->key, buf, bufsize); + // Detected. + if (result >= 0) + ret = result; + } if (ret >= 0) { /* Strip trailing whitespace and add newline. */ |