aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/device.c')
-rw-r--r--drivers/s390/cio/device.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index d3d3716ff84b..0f604621de40 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -585,12 +585,13 @@ static struct ccw_device * get_disc_ccwdev_by_dev_id(struct ccw_dev_id *dev_id,
585} 585}
586 586
587static void 587static void
588ccw_device_add_changed(void *data) 588ccw_device_add_changed(struct work_struct *work)
589{ 589{
590 590 struct ccw_device_private *priv;
591 struct ccw_device *cdev; 591 struct ccw_device *cdev;
592 592
593 cdev = data; 593 priv = container_of(work, struct ccw_device_private, kick_work);
594 cdev = priv->cdev;
594 if (device_add(&cdev->dev)) { 595 if (device_add(&cdev->dev)) {
595 put_device(&cdev->dev); 596 put_device(&cdev->dev);
596 return; 597 return;
@@ -605,13 +606,15 @@ ccw_device_add_changed(void *data)
605extern int css_get_ssd_info(struct subchannel *sch); 606extern int css_get_ssd_info(struct subchannel *sch);
606 607
607void 608void
608ccw_device_do_unreg_rereg(void *data) 609ccw_device_do_unreg_rereg(struct work_struct *work)
609{ 610{
611 struct ccw_device_private *priv;
610 struct ccw_device *cdev; 612 struct ccw_device *cdev;
611 struct subchannel *sch; 613 struct subchannel *sch;
612 int need_rename; 614 int need_rename;
613 615
614 cdev = data; 616 priv = container_of(work, struct ccw_device_private, kick_work);
617 cdev = priv->cdev;
615 sch = to_subchannel(cdev->dev.parent); 618 sch = to_subchannel(cdev->dev.parent);
616 if (cdev->private->dev_id.devno != sch->schib.pmcw.dev) { 619 if (cdev->private->dev_id.devno != sch->schib.pmcw.dev) {
617 /* 620 /*
@@ -659,7 +662,7 @@ ccw_device_do_unreg_rereg(void *data)
659 snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", 662 snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",
660 sch->schid.ssid, sch->schib.pmcw.dev); 663 sch->schid.ssid, sch->schib.pmcw.dev);
661 PREPARE_WORK(&cdev->private->kick_work, 664 PREPARE_WORK(&cdev->private->kick_work,
662 ccw_device_add_changed, cdev); 665 ccw_device_add_changed);
663 queue_work(ccw_device_work, &cdev->private->kick_work); 666 queue_work(ccw_device_work, &cdev->private->kick_work);
664} 667}
665 668
@@ -677,14 +680,16 @@ ccw_device_release(struct device *dev)
677 * Register recognized device. 680 * Register recognized device.
678 */ 681 */
679static void 682static void
680io_subchannel_register(void *data) 683io_subchannel_register(struct work_struct *work)
681{ 684{
685 struct ccw_device_private *priv;
682 struct ccw_device *cdev; 686 struct ccw_device *cdev;
683 struct subchannel *sch; 687 struct subchannel *sch;
684 int ret; 688 int ret;
685 unsigned long flags; 689 unsigned long flags;
686 690
687 cdev = data; 691 priv = container_of(work, struct ccw_device_private, kick_work);
692 cdev = priv->cdev;
688 sch = to_subchannel(cdev->dev.parent); 693 sch = to_subchannel(cdev->dev.parent);
689 694
690 /* 695 /*
@@ -734,11 +739,14 @@ out:
734} 739}
735 740
736void 741void
737ccw_device_call_sch_unregister(void *data) 742ccw_device_call_sch_unregister(struct work_struct *work)
738{ 743{
739 struct ccw_device *cdev = data; 744 struct ccw_device_private *priv;
745 struct ccw_device *cdev;
740 struct subchannel *sch; 746 struct subchannel *sch;
741 747
748 priv = container_of(work, struct ccw_device_private, kick_work);
749 cdev = priv->cdev;
742 sch = to_subchannel(cdev->dev.parent); 750 sch = to_subchannel(cdev->dev.parent);
743 css_sch_device_unregister(sch); 751 css_sch_device_unregister(sch);
744 /* Reset intparm to zeroes. */ 752 /* Reset intparm to zeroes. */
@@ -768,7 +776,7 @@ io_subchannel_recog_done(struct ccw_device *cdev)
768 break; 776 break;
769 sch = to_subchannel(cdev->dev.parent); 777 sch = to_subchannel(cdev->dev.parent);
770 PREPARE_WORK(&cdev->private->kick_work, 778 PREPARE_WORK(&cdev->private->kick_work,
771 ccw_device_call_sch_unregister, cdev); 779 ccw_device_call_sch_unregister);
772 queue_work(slow_path_wq, &cdev->private->kick_work); 780 queue_work(slow_path_wq, &cdev->private->kick_work);
773 if (atomic_dec_and_test(&ccw_device_init_count)) 781 if (atomic_dec_and_test(&ccw_device_init_count))
774 wake_up(&ccw_device_init_wq); 782 wake_up(&ccw_device_init_wq);
@@ -783,7 +791,7 @@ io_subchannel_recog_done(struct ccw_device *cdev)
783 if (!get_device(&cdev->dev)) 791 if (!get_device(&cdev->dev))
784 break; 792 break;
785 PREPARE_WORK(&cdev->private->kick_work, 793 PREPARE_WORK(&cdev->private->kick_work,
786 io_subchannel_register, cdev); 794 io_subchannel_register);
787 queue_work(slow_path_wq, &cdev->private->kick_work); 795 queue_work(slow_path_wq, &cdev->private->kick_work);
788 break; 796 break;
789 } 797 }
@@ -865,6 +873,7 @@ io_subchannel_probe (struct subchannel *sch)
865 kfree(cdev); 873 kfree(cdev);
866 return -ENOMEM; 874 return -ENOMEM;
867 } 875 }
876 cdev->private->cdev = cdev;
868 atomic_set(&cdev->private->onoff, 0); 877 atomic_set(&cdev->private->onoff, 0);
869 cdev->dev.parent = &sch->dev; 878 cdev->dev.parent = &sch->dev;
870 cdev->dev.release = ccw_device_release; 879 cdev->dev.release = ccw_device_release;
@@ -890,12 +899,13 @@ io_subchannel_probe (struct subchannel *sch)
890 return rc; 899 return rc;
891} 900}
892 901
893static void 902static void ccw_device_unregister(struct work_struct *work)
894ccw_device_unregister(void *data)
895{ 903{
904 struct ccw_device_private *priv;
896 struct ccw_device *cdev; 905 struct ccw_device *cdev;
897 906
898 cdev = (struct ccw_device *)data; 907 priv = container_of(work, struct ccw_device_private, kick_work);
908 cdev = priv->cdev;
899 if (test_and_clear_bit(1, &cdev->private->registered)) 909 if (test_and_clear_bit(1, &cdev->private->registered))
900 device_unregister(&cdev->dev); 910 device_unregister(&cdev->dev);
901 put_device(&cdev->dev); 911 put_device(&cdev->dev);
@@ -921,7 +931,7 @@ io_subchannel_remove (struct subchannel *sch)
921 */ 931 */
922 if (get_device(&cdev->dev)) { 932 if (get_device(&cdev->dev)) {
923 PREPARE_WORK(&cdev->private->kick_work, 933 PREPARE_WORK(&cdev->private->kick_work,
924 ccw_device_unregister, cdev); 934 ccw_device_unregister);
925 queue_work(ccw_device_work, &cdev->private->kick_work); 935 queue_work(ccw_device_work, &cdev->private->kick_work);
926 } 936 }
927 return 0; 937 return 0;
@@ -1048,6 +1058,7 @@ ccw_device_probe_console(void)
1048 memset(&console_cdev, 0, sizeof(struct ccw_device)); 1058 memset(&console_cdev, 0, sizeof(struct ccw_device));
1049 memset(&console_private, 0, sizeof(struct ccw_device_private)); 1059 memset(&console_private, 0, sizeof(struct ccw_device_private));
1050 console_cdev.private = &console_private; 1060 console_cdev.private = &console_private;
1061 console_private.cdev = &console_cdev;
1051 ret = ccw_device_console_enable(&console_cdev, sch); 1062 ret = ccw_device_console_enable(&console_cdev, sch);
1052 if (ret) { 1063 if (ret) {
1053 cio_release_console(); 1064 cio_release_console();