aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firewire/fw-device.c50
-rw-r--r--drivers/firewire/fw-device.h2
2 files changed, 51 insertions, 1 deletions
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 98ce0841f4c9..551588342898 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -355,9 +355,56 @@ static ssize_t guid_show(struct device *dev,
355 return ret; 355 return ret;
356} 356}
357 357
358static int units_sprintf(char *buf, u32 *directory)
359{
360 struct fw_csr_iterator ci;
361 int key, value;
362 int specifier_id = 0;
363 int version = 0;
364
365 fw_csr_iterator_init(&ci, directory);
366 while (fw_csr_iterator_next(&ci, &key, &value)) {
367 switch (key) {
368 case CSR_SPECIFIER_ID:
369 specifier_id = value;
370 break;
371 case CSR_VERSION:
372 version = value;
373 break;
374 }
375 }
376
377 return sprintf(buf, "0x%06x:0x%06x ", specifier_id, version);
378}
379
380static ssize_t units_show(struct device *dev,
381 struct device_attribute *attr, char *buf)
382{
383 struct fw_device *device = fw_device(dev);
384 struct fw_csr_iterator ci;
385 int key, value, i = 0;
386
387 down_read(&fw_device_rwsem);
388 fw_csr_iterator_init(&ci, &device->config_rom[5]);
389 while (fw_csr_iterator_next(&ci, &key, &value)) {
390 if (key != (CSR_UNIT | CSR_DIRECTORY))
391 continue;
392 i += units_sprintf(&buf[i], ci.p + value - 1);
393 if (i >= PAGE_SIZE - (8 + 1 + 8 + 1))
394 break;
395 }
396 up_read(&fw_device_rwsem);
397
398 if (i)
399 buf[i - 1] = '\n';
400
401 return i;
402}
403
358static struct device_attribute fw_device_attributes[] = { 404static struct device_attribute fw_device_attributes[] = {
359 __ATTR_RO(config_rom), 405 __ATTR_RO(config_rom),
360 __ATTR_RO(guid), 406 __ATTR_RO(guid),
407 __ATTR_RO(units),
361 __ATTR_NULL, 408 __ATTR_NULL,
362}; 409};
363 410
@@ -1000,6 +1047,9 @@ static void fw_device_refresh(struct work_struct *work)
1000 1047
1001 create_units(device); 1048 create_units(device);
1002 1049
1050 /* Userspace may want to re-read attributes. */
1051 kobject_uevent(&device->device.kobj, KOBJ_CHANGE);
1052
1003 if (atomic_cmpxchg(&device->state, 1053 if (atomic_cmpxchg(&device->state,
1004 FW_DEVICE_INITIALIZING, 1054 FW_DEVICE_INITIALIZING,
1005 FW_DEVICE_RUNNING) == FW_DEVICE_GONE) 1055 FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
index 623cfee289bd..892dd5916276 100644
--- a/drivers/firewire/fw-device.h
+++ b/drivers/firewire/fw-device.h
@@ -42,7 +42,7 @@ enum fw_device_state {
42struct fw_attribute_group { 42struct fw_attribute_group {
43 struct attribute_group *groups[2]; 43 struct attribute_group *groups[2];
44 struct attribute_group group; 44 struct attribute_group group;
45 struct attribute *attrs[11]; 45 struct attribute *attrs[12];
46}; 46};
47 47
48struct fw_node; 48struct fw_node;