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.c51
1 files changed, 24 insertions, 27 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 688945662c15..39c98f940507 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -532,8 +532,7 @@ device_remove_files(struct device *dev)
532 532
533/* this is a simple abstraction for device_register that sets the 533/* this is a simple abstraction for device_register that sets the
534 * correct bus type and adds the bus specific files */ 534 * correct bus type and adds the bus specific files */
535int 535static int ccw_device_register(struct ccw_device *cdev)
536ccw_device_register(struct ccw_device *cdev)
537{ 536{
538 struct device *dev = &cdev->dev; 537 struct device *dev = &cdev->dev;
539 int ret; 538 int ret;
@@ -552,21 +551,19 @@ ccw_device_register(struct ccw_device *cdev)
552} 551}
553 552
554struct match_data { 553struct match_data {
555 unsigned int devno; 554 struct ccw_dev_id dev_id;
556 unsigned int ssid;
557 struct ccw_device * sibling; 555 struct ccw_device * sibling;
558}; 556};
559 557
560static int 558static int
561match_devno(struct device * dev, void * data) 559match_devno(struct device * dev, void * data)
562{ 560{
563 struct match_data * d = (struct match_data *)data; 561 struct match_data * d = data;
564 struct ccw_device * cdev; 562 struct ccw_device * cdev;
565 563
566 cdev = to_ccwdev(dev); 564 cdev = to_ccwdev(dev);
567 if ((cdev->private->state == DEV_STATE_DISCONNECTED) && 565 if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
568 (cdev->private->devno == d->devno) && 566 ccw_dev_id_is_equal(&cdev->private->dev_id, &d->dev_id) &&
569 (cdev->private->ssid == d->ssid) &&
570 (cdev != d->sibling)) { 567 (cdev != d->sibling)) {
571 cdev->private->state = DEV_STATE_NOT_OPER; 568 cdev->private->state = DEV_STATE_NOT_OPER;
572 return 1; 569 return 1;
@@ -574,15 +571,13 @@ match_devno(struct device * dev, void * data)
574 return 0; 571 return 0;
575} 572}
576 573
577static struct ccw_device * 574static struct ccw_device * get_disc_ccwdev_by_dev_id(struct ccw_dev_id *dev_id,
578get_disc_ccwdev_by_devno(unsigned int devno, unsigned int ssid, 575 struct ccw_device *sibling)
579 struct ccw_device *sibling)
580{ 576{
581 struct device *dev; 577 struct device *dev;
582 struct match_data data; 578 struct match_data data;
583 579
584 data.devno = devno; 580 data.dev_id = *dev_id;
585 data.ssid = ssid;
586 data.sibling = sibling; 581 data.sibling = sibling;
587 dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno); 582 dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno);
588 583
@@ -595,7 +590,7 @@ ccw_device_add_changed(void *data)
595 590
596 struct ccw_device *cdev; 591 struct ccw_device *cdev;
597 592
598 cdev = (struct ccw_device *)data; 593 cdev = data;
599 if (device_add(&cdev->dev)) { 594 if (device_add(&cdev->dev)) {
600 put_device(&cdev->dev); 595 put_device(&cdev->dev);
601 return; 596 return;
@@ -616,9 +611,9 @@ ccw_device_do_unreg_rereg(void *data)
616 struct subchannel *sch; 611 struct subchannel *sch;
617 int need_rename; 612 int need_rename;
618 613
619 cdev = (struct ccw_device *)data; 614 cdev = data;
620 sch = to_subchannel(cdev->dev.parent); 615 sch = to_subchannel(cdev->dev.parent);
621 if (cdev->private->devno != sch->schib.pmcw.dev) { 616 if (cdev->private->dev_id.devno != sch->schib.pmcw.dev) {
622 /* 617 /*
623 * The device number has changed. This is usually only when 618 * The device number has changed. This is usually only when
624 * a device has been detached under VM and then re-appeared 619 * a device has been detached under VM and then re-appeared
@@ -633,10 +628,12 @@ ccw_device_do_unreg_rereg(void *data)
633 * get possibly sick... 628 * get possibly sick...
634 */ 629 */
635 struct ccw_device *other_cdev; 630 struct ccw_device *other_cdev;
631 struct ccw_dev_id dev_id;
636 632
637 need_rename = 1; 633 need_rename = 1;
638 other_cdev = get_disc_ccwdev_by_devno(sch->schib.pmcw.dev, 634 dev_id.devno = sch->schib.pmcw.dev;
639 sch->schid.ssid, cdev); 635 dev_id.ssid = sch->schid.ssid;
636 other_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev);
640 if (other_cdev) { 637 if (other_cdev) {
641 struct subchannel *other_sch; 638 struct subchannel *other_sch;
642 639
@@ -652,7 +649,7 @@ ccw_device_do_unreg_rereg(void *data)
652 } 649 }
653 /* Update ssd info here. */ 650 /* Update ssd info here. */
654 css_get_ssd_info(sch); 651 css_get_ssd_info(sch);
655 cdev->private->devno = sch->schib.pmcw.dev; 652 cdev->private->dev_id.devno = sch->schib.pmcw.dev;
656 } else 653 } else
657 need_rename = 0; 654 need_rename = 0;
658 device_remove_files(&cdev->dev); 655 device_remove_files(&cdev->dev);
@@ -662,7 +659,7 @@ ccw_device_do_unreg_rereg(void *data)
662 snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", 659 snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",
663 sch->schid.ssid, sch->schib.pmcw.dev); 660 sch->schid.ssid, sch->schib.pmcw.dev);
664 PREPARE_WORK(&cdev->private->kick_work, 661 PREPARE_WORK(&cdev->private->kick_work,
665 ccw_device_add_changed, (void *)cdev); 662 ccw_device_add_changed, cdev);
666 queue_work(ccw_device_work, &cdev->private->kick_work); 663 queue_work(ccw_device_work, &cdev->private->kick_work);
667} 664}
668 665
@@ -687,7 +684,7 @@ io_subchannel_register(void *data)
687 int ret; 684 int ret;
688 unsigned long flags; 685 unsigned long flags;
689 686
690 cdev = (struct ccw_device *) data; 687 cdev = data;
691 sch = to_subchannel(cdev->dev.parent); 688 sch = to_subchannel(cdev->dev.parent);
692 689
693 if (klist_node_attached(&cdev->dev.knode_parent)) { 690 if (klist_node_attached(&cdev->dev.knode_parent)) {
@@ -759,7 +756,7 @@ io_subchannel_recog_done(struct ccw_device *cdev)
759 break; 756 break;
760 sch = to_subchannel(cdev->dev.parent); 757 sch = to_subchannel(cdev->dev.parent);
761 PREPARE_WORK(&cdev->private->kick_work, 758 PREPARE_WORK(&cdev->private->kick_work,
762 ccw_device_call_sch_unregister, (void *) cdev); 759 ccw_device_call_sch_unregister, cdev);
763 queue_work(slow_path_wq, &cdev->private->kick_work); 760 queue_work(slow_path_wq, &cdev->private->kick_work);
764 if (atomic_dec_and_test(&ccw_device_init_count)) 761 if (atomic_dec_and_test(&ccw_device_init_count))
765 wake_up(&ccw_device_init_wq); 762 wake_up(&ccw_device_init_wq);
@@ -774,7 +771,7 @@ io_subchannel_recog_done(struct ccw_device *cdev)
774 if (!get_device(&cdev->dev)) 771 if (!get_device(&cdev->dev))
775 break; 772 break;
776 PREPARE_WORK(&cdev->private->kick_work, 773 PREPARE_WORK(&cdev->private->kick_work,
777 io_subchannel_register, (void *) cdev); 774 io_subchannel_register, cdev);
778 queue_work(slow_path_wq, &cdev->private->kick_work); 775 queue_work(slow_path_wq, &cdev->private->kick_work);
779 break; 776 break;
780 } 777 }
@@ -792,9 +789,9 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
792 789
793 /* Init private data. */ 790 /* Init private data. */
794 priv = cdev->private; 791 priv = cdev->private;
795 priv->devno = sch->schib.pmcw.dev; 792 priv->dev_id.devno = sch->schib.pmcw.dev;
796 priv->ssid = sch->schid.ssid; 793 priv->dev_id.ssid = sch->schid.ssid;
797 priv->sch_no = sch->schid.sch_no; 794 priv->schid = sch->schid;
798 priv->state = DEV_STATE_NOT_OPER; 795 priv->state = DEV_STATE_NOT_OPER;
799 INIT_LIST_HEAD(&priv->cmb_list); 796 INIT_LIST_HEAD(&priv->cmb_list);
800 init_waitqueue_head(&priv->wait_q); 797 init_waitqueue_head(&priv->wait_q);
@@ -912,7 +909,7 @@ io_subchannel_remove (struct subchannel *sch)
912 */ 909 */
913 if (get_device(&cdev->dev)) { 910 if (get_device(&cdev->dev)) {
914 PREPARE_WORK(&cdev->private->kick_work, 911 PREPARE_WORK(&cdev->private->kick_work,
915 ccw_device_unregister, (void *) cdev); 912 ccw_device_unregister, cdev);
916 queue_work(ccw_device_work, &cdev->private->kick_work); 913 queue_work(ccw_device_work, &cdev->private->kick_work);
917 } 914 }
918 return 0; 915 return 0;
@@ -1055,7 +1052,7 @@ __ccwdev_check_busid(struct device *dev, void *id)
1055{ 1052{
1056 char *bus_id; 1053 char *bus_id;
1057 1054
1058 bus_id = (char *)id; 1055 bus_id = id;
1059 1056
1060 return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0); 1057 return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0);
1061} 1058}