aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firewire/fw-device.c55
-rw-r--r--drivers/firewire/fw-device.h8
2 files changed, 28 insertions, 35 deletions
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 2bf86aa1c9bc..5db666fd265b 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -289,32 +289,29 @@ static struct config_rom_attribute config_rom_attributes[] = {
289}; 289};
290 290
291static void 291static void
292remove_config_rom_attributes(struct device *dev) 292init_fw_attribute_group(struct device *dev,
293{ 293 struct device_attribute *attrs,
294 int i; 294 struct fw_attribute_group *group)
295
296 for (i = 0; i < ARRAY_SIZE(config_rom_attributes); i++)
297 device_remove_file(dev, &config_rom_attributes[i].attr);
298}
299
300static int
301add_config_rom_attributes(struct device *dev)
302{ 295{
303 struct device_attribute *attr; 296 struct device_attribute *attr;
304 int i, err = 0; 297 int i, j;
298
299 for (j = 0; attrs[j].attr.name != NULL; j++)
300 group->attrs[j] = &attrs[j].attr;
305 301
306 for (i = 0; i < ARRAY_SIZE(config_rom_attributes); i++) { 302 for (i = 0; i < ARRAY_SIZE(config_rom_attributes); i++) {
307 attr = &config_rom_attributes[i].attr; 303 attr = &config_rom_attributes[i].attr;
308 if (attr->show(dev, attr, NULL) < 0) 304 if (attr->show(dev, attr, NULL) < 0)
309 continue; 305 continue;
310 err = device_create_file(dev, attr); 306 group->attrs[j++] = &attr->attr;
311 if (err < 0) {
312 remove_config_rom_attributes(dev);
313 break;
314 }
315 } 307 }
316 308
317 return err; 309 BUG_ON(j >= ARRAY_SIZE(group->attrs));
310 group->attrs[j++] = NULL;
311 group->groups[0] = &group->group;
312 group->groups[1] = NULL;
313 group->group.attrs = group->attrs;
314 dev->groups = group->groups;
318} 315}
319 316
320static ssize_t 317static ssize_t
@@ -497,7 +494,6 @@ static void fw_unit_release(struct device *dev)
497} 494}
498 495
499static struct device_type fw_unit_type = { 496static struct device_type fw_unit_type = {
500 .attrs = fw_unit_attributes,
501 .uevent = fw_unit_uevent, 497 .uevent = fw_unit_uevent,
502 .release = fw_unit_release, 498 .release = fw_unit_release,
503}; 499};
@@ -534,16 +530,14 @@ static void create_units(struct fw_device *device)
534 snprintf(unit->device.bus_id, sizeof unit->device.bus_id, 530 snprintf(unit->device.bus_id, sizeof unit->device.bus_id,
535 "%s.%d", device->device.bus_id, i++); 531 "%s.%d", device->device.bus_id, i++);
536 532
533 init_fw_attribute_group(&unit->device,
534 fw_unit_attributes,
535 &unit->attribute_group);
537 if (device_register(&unit->device) < 0) 536 if (device_register(&unit->device) < 0)
538 goto skip_unit; 537 goto skip_unit;
539 538
540 if (add_config_rom_attributes(&unit->device) < 0)
541 goto skip_unregister;
542
543 continue; 539 continue;
544 540
545 skip_unregister:
546 device_unregister(&unit->device);
547 skip_unit: 541 skip_unit:
548 kfree(unit); 542 kfree(unit);
549 } 543 }
@@ -551,9 +545,6 @@ static void create_units(struct fw_device *device)
551 545
552static int shutdown_unit(struct device *device, void *data) 546static int shutdown_unit(struct device *device, void *data)
553{ 547{
554 struct fw_unit *unit = fw_unit(device);
555
556 remove_config_rom_attributes(&unit->device);
557 device_unregister(device); 548 device_unregister(device);
558 549
559 return 0; 550 return 0;
@@ -583,15 +574,12 @@ static void fw_device_shutdown(struct work_struct *work)
583 idr_remove(&fw_device_idr, minor); 574 idr_remove(&fw_device_idr, minor);
584 up_write(&fw_bus_type.subsys.rwsem); 575 up_write(&fw_bus_type.subsys.rwsem);
585 576
586 remove_config_rom_attributes(&device->device);
587
588 fw_device_cdev_remove(device); 577 fw_device_cdev_remove(device);
589 device_for_each_child(&device->device, NULL, shutdown_unit); 578 device_for_each_child(&device->device, NULL, shutdown_unit);
590 device_unregister(&device->device); 579 device_unregister(&device->device);
591} 580}
592 581
593static struct device_type fw_device_type = { 582static struct device_type fw_device_type = {
594 .attrs = fw_device_attributes,
595 .release = fw_device_release, 583 .release = fw_device_release,
596}; 584};
597 585
@@ -647,15 +635,14 @@ static void fw_device_init(struct work_struct *work)
647 snprintf(device->device.bus_id, sizeof device->device.bus_id, 635 snprintf(device->device.bus_id, sizeof device->device.bus_id,
648 "fw%d", minor); 636 "fw%d", minor);
649 637
638 init_fw_attribute_group(&device->device,
639 fw_device_attributes,
640 &device->attribute_group);
650 if (device_add(&device->device)) { 641 if (device_add(&device->device)) {
651 fw_error("Failed to add device.\n"); 642 fw_error("Failed to add device.\n");
652 goto error_with_cdev; 643 goto error_with_cdev;
653 } 644 }
654 645
655 err = add_config_rom_attributes(&device->device);
656 if (err < 0)
657 goto error_with_register;
658
659 create_units(device); 646 create_units(device);
660 647
661 /* Transition the device to running state. If it got pulled 648 /* Transition the device to running state. If it got pulled
@@ -682,8 +669,6 @@ static void fw_device_init(struct work_struct *work)
682 669
683 return; 670 return;
684 671
685 error_with_register:
686 device_unregister(&device->device);
687 error_with_cdev: 672 error_with_cdev:
688 down_write(&fw_bus_type.subsys.rwsem); 673 down_write(&fw_bus_type.subsys.rwsem);
689 idr_remove(&fw_device_idr, minor); 674 idr_remove(&fw_device_idr, minor);
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
index ce47ab958840..c167d59da68a 100644
--- a/drivers/firewire/fw-device.h
+++ b/drivers/firewire/fw-device.h
@@ -32,6 +32,12 @@ enum fw_device_state {
32 FW_DEVICE_SHUTDOWN, 32 FW_DEVICE_SHUTDOWN,
33}; 33};
34 34
35struct fw_attribute_group {
36 struct attribute_group *groups[2];
37 struct attribute_group group;
38 struct attribute *attrs[11];
39};
40
35struct fw_device { 41struct fw_device {
36 atomic_t state; 42 atomic_t state;
37 struct fw_node *node; 43 struct fw_node *node;
@@ -45,6 +51,7 @@ struct fw_device {
45 size_t config_rom_length; 51 size_t config_rom_length;
46 int config_rom_retries; 52 int config_rom_retries;
47 struct delayed_work work; 53 struct delayed_work work;
54 struct fw_attribute_group attribute_group;
48}; 55};
49 56
50static inline struct fw_device * 57static inline struct fw_device *
@@ -72,6 +79,7 @@ extern int fw_cdev_major;
72struct fw_unit { 79struct fw_unit {
73 struct device device; 80 struct device device;
74 u32 *directory; 81 u32 *directory;
82 struct fw_attribute_group attribute_group;
75}; 83};
76 84
77static inline struct fw_unit * 85static inline struct fw_unit *