firewire: Use device->groups for adding device attributes.
We dynamically create an attribute group for the key present on the device in hand and point device->group to it. This way the device core adds the sysfs attributes for us as the device is added. Signed-off-by: Kristian Høgsberg <krh@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
This commit is contained in:
parent
ecab413359
commit
6f2e53d513
@ -289,32 +289,29 @@ static struct config_rom_attribute config_rom_attributes[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_config_rom_attributes(struct device *dev)
|
init_fw_attribute_group(struct device *dev,
|
||||||
{
|
struct device_attribute *attrs,
|
||||||
int i;
|
struct fw_attribute_group *group)
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(config_rom_attributes); i++)
|
|
||||||
device_remove_file(dev, &config_rom_attributes[i].attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
add_config_rom_attributes(struct device *dev)
|
|
||||||
{
|
{
|
||||||
struct device_attribute *attr;
|
struct device_attribute *attr;
|
||||||
int i, err = 0;
|
int i, j;
|
||||||
|
|
||||||
|
for (j = 0; attrs[j].attr.name != NULL; j++)
|
||||||
|
group->attrs[j] = &attrs[j].attr;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(config_rom_attributes); i++) {
|
for (i = 0; i < ARRAY_SIZE(config_rom_attributes); i++) {
|
||||||
attr = &config_rom_attributes[i].attr;
|
attr = &config_rom_attributes[i].attr;
|
||||||
if (attr->show(dev, attr, NULL) < 0)
|
if (attr->show(dev, attr, NULL) < 0)
|
||||||
continue;
|
continue;
|
||||||
err = device_create_file(dev, attr);
|
group->attrs[j++] = &attr->attr;
|
||||||
if (err < 0) {
|
|
||||||
remove_config_rom_attributes(dev);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
BUG_ON(j >= ARRAY_SIZE(group->attrs));
|
||||||
|
group->attrs[j++] = NULL;
|
||||||
|
group->groups[0] = &group->group;
|
||||||
|
group->groups[1] = NULL;
|
||||||
|
group->group.attrs = group->attrs;
|
||||||
|
dev->groups = group->groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
@ -497,7 +494,6 @@ static void fw_unit_release(struct device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct device_type fw_unit_type = {
|
static struct device_type fw_unit_type = {
|
||||||
.attrs = fw_unit_attributes,
|
|
||||||
.uevent = fw_unit_uevent,
|
.uevent = fw_unit_uevent,
|
||||||
.release = fw_unit_release,
|
.release = fw_unit_release,
|
||||||
};
|
};
|
||||||
@ -534,16 +530,14 @@ static void create_units(struct fw_device *device)
|
|||||||
snprintf(unit->device.bus_id, sizeof unit->device.bus_id,
|
snprintf(unit->device.bus_id, sizeof unit->device.bus_id,
|
||||||
"%s.%d", device->device.bus_id, i++);
|
"%s.%d", device->device.bus_id, i++);
|
||||||
|
|
||||||
|
init_fw_attribute_group(&unit->device,
|
||||||
|
fw_unit_attributes,
|
||||||
|
&unit->attribute_group);
|
||||||
if (device_register(&unit->device) < 0)
|
if (device_register(&unit->device) < 0)
|
||||||
goto skip_unit;
|
goto skip_unit;
|
||||||
|
|
||||||
if (add_config_rom_attributes(&unit->device) < 0)
|
|
||||||
goto skip_unregister;
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
skip_unregister:
|
|
||||||
device_unregister(&unit->device);
|
|
||||||
skip_unit:
|
skip_unit:
|
||||||
kfree(unit);
|
kfree(unit);
|
||||||
}
|
}
|
||||||
@ -551,9 +545,6 @@ static void create_units(struct fw_device *device)
|
|||||||
|
|
||||||
static int shutdown_unit(struct device *device, void *data)
|
static int shutdown_unit(struct device *device, void *data)
|
||||||
{
|
{
|
||||||
struct fw_unit *unit = fw_unit(device);
|
|
||||||
|
|
||||||
remove_config_rom_attributes(&unit->device);
|
|
||||||
device_unregister(device);
|
device_unregister(device);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -583,15 +574,12 @@ static void fw_device_shutdown(struct work_struct *work)
|
|||||||
idr_remove(&fw_device_idr, minor);
|
idr_remove(&fw_device_idr, minor);
|
||||||
up_write(&fw_bus_type.subsys.rwsem);
|
up_write(&fw_bus_type.subsys.rwsem);
|
||||||
|
|
||||||
remove_config_rom_attributes(&device->device);
|
|
||||||
|
|
||||||
fw_device_cdev_remove(device);
|
fw_device_cdev_remove(device);
|
||||||
device_for_each_child(&device->device, NULL, shutdown_unit);
|
device_for_each_child(&device->device, NULL, shutdown_unit);
|
||||||
device_unregister(&device->device);
|
device_unregister(&device->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct device_type fw_device_type = {
|
static struct device_type fw_device_type = {
|
||||||
.attrs = fw_device_attributes,
|
|
||||||
.release = fw_device_release,
|
.release = fw_device_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -647,15 +635,14 @@ static void fw_device_init(struct work_struct *work)
|
|||||||
snprintf(device->device.bus_id, sizeof device->device.bus_id,
|
snprintf(device->device.bus_id, sizeof device->device.bus_id,
|
||||||
"fw%d", minor);
|
"fw%d", minor);
|
||||||
|
|
||||||
|
init_fw_attribute_group(&device->device,
|
||||||
|
fw_device_attributes,
|
||||||
|
&device->attribute_group);
|
||||||
if (device_add(&device->device)) {
|
if (device_add(&device->device)) {
|
||||||
fw_error("Failed to add device.\n");
|
fw_error("Failed to add device.\n");
|
||||||
goto error_with_cdev;
|
goto error_with_cdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = add_config_rom_attributes(&device->device);
|
|
||||||
if (err < 0)
|
|
||||||
goto error_with_register;
|
|
||||||
|
|
||||||
create_units(device);
|
create_units(device);
|
||||||
|
|
||||||
/* Transition the device to running state. If it got pulled
|
/* Transition the device to running state. If it got pulled
|
||||||
@ -682,8 +669,6 @@ static void fw_device_init(struct work_struct *work)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error_with_register:
|
|
||||||
device_unregister(&device->device);
|
|
||||||
error_with_cdev:
|
error_with_cdev:
|
||||||
down_write(&fw_bus_type.subsys.rwsem);
|
down_write(&fw_bus_type.subsys.rwsem);
|
||||||
idr_remove(&fw_device_idr, minor);
|
idr_remove(&fw_device_idr, minor);
|
||||||
|
@ -32,6 +32,12 @@ enum fw_device_state {
|
|||||||
FW_DEVICE_SHUTDOWN,
|
FW_DEVICE_SHUTDOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fw_attribute_group {
|
||||||
|
struct attribute_group *groups[2];
|
||||||
|
struct attribute_group group;
|
||||||
|
struct attribute *attrs[11];
|
||||||
|
};
|
||||||
|
|
||||||
struct fw_device {
|
struct fw_device {
|
||||||
atomic_t state;
|
atomic_t state;
|
||||||
struct fw_node *node;
|
struct fw_node *node;
|
||||||
@ -45,6 +51,7 @@ struct fw_device {
|
|||||||
size_t config_rom_length;
|
size_t config_rom_length;
|
||||||
int config_rom_retries;
|
int config_rom_retries;
|
||||||
struct delayed_work work;
|
struct delayed_work work;
|
||||||
|
struct fw_attribute_group attribute_group;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct fw_device *
|
static inline struct fw_device *
|
||||||
@ -72,6 +79,7 @@ extern int fw_cdev_major;
|
|||||||
struct fw_unit {
|
struct fw_unit {
|
||||||
struct device device;
|
struct device device;
|
||||||
u32 *directory;
|
u32 *directory;
|
||||||
|
struct fw_attribute_group attribute_group;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct fw_unit *
|
static inline struct fw_unit *
|
||||||
|
Loading…
Reference in New Issue
Block a user