diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dcssblk.c | 52 |
1 files changed, 23 insertions, 29 deletions
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index a5a55da2a1a..b6ad0de0793 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
@@ -69,23 +69,9 @@ static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *a | |||
69 | size_t count); | 69 | size_t count); |
70 | static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf, | 70 | static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf, |
71 | size_t count); | 71 | size_t count); |
72 | static ssize_t dcssblk_save_store(struct device * dev, struct device_attribute *attr, const char * buf, | ||
73 | size_t count); | ||
74 | static ssize_t dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf); | ||
75 | static ssize_t dcssblk_shared_store(struct device * dev, struct device_attribute *attr, const char * buf, | ||
76 | size_t count); | ||
77 | static ssize_t dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf); | ||
78 | static ssize_t dcssblk_seglist_show(struct device *dev, | ||
79 | struct device_attribute *attr, | ||
80 | char *buf); | ||
81 | 72 | ||
82 | static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store); | 73 | static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store); |
83 | static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store); | 74 | static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store); |
84 | static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show, | ||
85 | dcssblk_save_store); | ||
86 | static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show, | ||
87 | dcssblk_shared_store); | ||
88 | static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL); | ||
89 | 75 | ||
90 | static struct device *dcssblk_root_dev; | 76 | static struct device *dcssblk_root_dev; |
91 | 77 | ||
@@ -416,6 +402,8 @@ out: | |||
416 | up_write(&dcssblk_devices_sem); | 402 | up_write(&dcssblk_devices_sem); |
417 | return rc; | 403 | return rc; |
418 | } | 404 | } |
405 | static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show, | ||
406 | dcssblk_shared_store); | ||
419 | 407 | ||
420 | /* | 408 | /* |
421 | * device attribute for save operation on current copy | 409 | * device attribute for save operation on current copy |
@@ -476,6 +464,8 @@ dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char | |||
476 | up_write(&dcssblk_devices_sem); | 464 | up_write(&dcssblk_devices_sem); |
477 | return count; | 465 | return count; |
478 | } | 466 | } |
467 | static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show, | ||
468 | dcssblk_save_store); | ||
479 | 469 | ||
480 | /* | 470 | /* |
481 | * device attribute for showing all segments in a device | 471 | * device attribute for showing all segments in a device |
@@ -502,6 +492,21 @@ dcssblk_seglist_show(struct device *dev, struct device_attribute *attr, | |||
502 | up_read(&dcssblk_devices_sem); | 492 | up_read(&dcssblk_devices_sem); |
503 | return i; | 493 | return i; |
504 | } | 494 | } |
495 | static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL); | ||
496 | |||
497 | static struct attribute *dcssblk_dev_attrs[] = { | ||
498 | &dev_attr_shared.attr, | ||
499 | &dev_attr_save.attr, | ||
500 | &dev_attr_seglist.attr, | ||
501 | NULL, | ||
502 | }; | ||
503 | static struct attribute_group dcssblk_dev_attr_group = { | ||
504 | .attrs = dcssblk_dev_attrs, | ||
505 | }; | ||
506 | static const struct attribute_group *dcssblk_dev_attr_groups[] = { | ||
507 | &dcssblk_dev_attr_group, | ||
508 | NULL, | ||
509 | }; | ||
505 | 510 | ||
506 | /* | 511 | /* |
507 | * device attribute for adding devices | 512 | * device attribute for adding devices |
@@ -590,6 +595,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char | |||
590 | 595 | ||
591 | dev_set_name(&dev_info->dev, dev_info->segment_name); | 596 | dev_set_name(&dev_info->dev, dev_info->segment_name); |
592 | dev_info->dev.release = dcssblk_release_segment; | 597 | dev_info->dev.release = dcssblk_release_segment; |
598 | dev_info->dev.groups = dcssblk_dev_attr_groups; | ||
593 | INIT_LIST_HEAD(&dev_info->lh); | 599 | INIT_LIST_HEAD(&dev_info->lh); |
594 | dev_info->gd = alloc_disk(DCSSBLK_MINORS_PER_DISK); | 600 | dev_info->gd = alloc_disk(DCSSBLK_MINORS_PER_DISK); |
595 | if (dev_info->gd == NULL) { | 601 | if (dev_info->gd == NULL) { |
@@ -637,21 +643,10 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char | |||
637 | * register the device | 643 | * register the device |
638 | */ | 644 | */ |
639 | rc = device_register(&dev_info->dev); | 645 | rc = device_register(&dev_info->dev); |
640 | if (rc) { | ||
641 | module_put(THIS_MODULE); | ||
642 | goto dev_list_del; | ||
643 | } | ||
644 | get_device(&dev_info->dev); | ||
645 | rc = device_create_file(&dev_info->dev, &dev_attr_shared); | ||
646 | if (rc) | ||
647 | goto unregister_dev; | ||
648 | rc = device_create_file(&dev_info->dev, &dev_attr_save); | ||
649 | if (rc) | ||
650 | goto unregister_dev; | ||
651 | rc = device_create_file(&dev_info->dev, &dev_attr_seglist); | ||
652 | if (rc) | 646 | if (rc) |
653 | goto unregister_dev; | 647 | goto put_dev; |
654 | 648 | ||
649 | get_device(&dev_info->dev); | ||
655 | add_disk(dev_info->gd); | 650 | add_disk(dev_info->gd); |
656 | 651 | ||
657 | switch (dev_info->segment_type) { | 652 | switch (dev_info->segment_type) { |
@@ -668,12 +663,11 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char | |||
668 | rc = count; | 663 | rc = count; |
669 | goto out; | 664 | goto out; |
670 | 665 | ||
671 | unregister_dev: | 666 | put_dev: |
672 | list_del(&dev_info->lh); | 667 | list_del(&dev_info->lh); |
673 | blk_cleanup_queue(dev_info->dcssblk_queue); | 668 | blk_cleanup_queue(dev_info->dcssblk_queue); |
674 | dev_info->gd->queue = NULL; | 669 | dev_info->gd->queue = NULL; |
675 | put_disk(dev_info->gd); | 670 | put_disk(dev_info->gd); |
676 | device_unregister(&dev_info->dev); | ||
677 | list_for_each_entry(seg_info, &dev_info->seg_list, lh) { | 671 | list_for_each_entry(seg_info, &dev_info->seg_list, lh) { |
678 | segment_unload(seg_info->segment_name); | 672 | segment_unload(seg_info->segment_name); |
679 | } | 673 | } |