diff options
-rw-r--r-- | drivers/firewire/fw-device.c | 55 | ||||
-rw-r--r-- | drivers/firewire/fw-device.h | 8 |
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 | ||
291 | static void | 291 | static void |
292 | remove_config_rom_attributes(struct device *dev) | 292 | init_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 | |||
300 | static int | ||
301 | add_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 | ||
320 | static ssize_t | 317 | static ssize_t |
@@ -497,7 +494,6 @@ static void fw_unit_release(struct device *dev) | |||
497 | } | 494 | } |
498 | 495 | ||
499 | static struct device_type fw_unit_type = { | 496 | static 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 | ||
552 | static int shutdown_unit(struct device *device, void *data) | 546 | static 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 | ||
593 | static struct device_type fw_device_type = { | 582 | static 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 | ||
35 | struct fw_attribute_group { | ||
36 | struct attribute_group *groups[2]; | ||
37 | struct attribute_group group; | ||
38 | struct attribute *attrs[11]; | ||
39 | }; | ||
40 | |||
35 | struct fw_device { | 41 | struct 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 | ||
50 | static inline struct fw_device * | 57 | static inline struct fw_device * |
@@ -72,6 +79,7 @@ extern int fw_cdev_major; | |||
72 | struct fw_unit { | 79 | struct 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 | ||
77 | static inline struct fw_unit * | 85 | static inline struct fw_unit * |