s390/cio: unregister device when the only path is gone
authorVineeth Vijayan <vneethv@linux.ibm.com>
Thu, 4 May 2023 18:53:20 +0000 (20:53 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 28 Jun 2023 09:12:37 +0000 (11:12 +0200)
[ Upstream commit 89c0c62e947a01e7a36b54582fd9c9e346170255 ]

Currently, if the device is offline and all the channel paths are
either configured or varied offline, the associated subchannel gets
unregistered. Don't unregister the subchannel, instead unregister
offline device.

Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/s390/cio/device.c

index ba4c692..02813b6 100644 (file)
@@ -1367,6 +1367,7 @@ void ccw_device_set_notoper(struct ccw_device *cdev)
 enum io_sch_action {
        IO_SCH_UNREG,
        IO_SCH_ORPH_UNREG,
+       IO_SCH_UNREG_CDEV,
        IO_SCH_ATTACH,
        IO_SCH_UNREG_ATTACH,
        IO_SCH_ORPH_ATTACH,
@@ -1399,7 +1400,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch)
        }
        if ((sch->schib.pmcw.pam & sch->opm) == 0) {
                if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK)
-                       return IO_SCH_UNREG;
+                       return IO_SCH_UNREG_CDEV;
                return IO_SCH_DISC;
        }
        if (device_is_disconnected(cdev))
@@ -1461,6 +1462,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
        case IO_SCH_ORPH_ATTACH:
                ccw_device_set_disconnected(cdev);
                break;
+       case IO_SCH_UNREG_CDEV:
        case IO_SCH_UNREG_ATTACH:
        case IO_SCH_UNREG:
                if (!cdev)
@@ -1494,6 +1496,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
                if (rc)
                        goto out;
                break;
+       case IO_SCH_UNREG_CDEV:
        case IO_SCH_UNREG_ATTACH:
                spin_lock_irqsave(sch->lock, flags);
                sch_set_cdev(sch, NULL);