Skip to content

Commit df2382e

Browse files
vneethvsmb49
authored andcommitted
s390/cio: Do not unregister the subchannel based on DNV
BugLink: https://bugs.launchpad.net/bugs/2101915 [ Upstream commit 8c58a229688ce3a097b3b1a2efe1b4f5508c2123 ] Starting with commit 2297791 ("s390/cio: dont unregister subchannel from child-drivers"), CIO does not unregister subchannels when the attached device is invalid or unavailable. Instead, it allows subchannels to exist without a connected device. However, if the DNV value is 0, such as, when all the CHPIDs of a subchannel are configured in standby state, the subchannel is unregistered, which contradicts the current subchannel specification. Update the logic so that subchannels are not unregistered based on the DNV value. Also update the SCHIB information even if the DNV bit is zero. Suggested-by: Peter Oberparleiter <oberpar@linux.ibm.com> Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com> Fixes: 2297791 ("s390/cio: dont unregister subchannel from child-drivers") Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Koichiro Den <koichiro.den@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
1 parent c0a53de commit df2382e

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

drivers/s390/cio/cio.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,10 +459,14 @@ int cio_update_schib(struct subchannel *sch)
459459
{
460460
struct schib schib;
461461

462-
if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
462+
if (stsch(sch->schid, &schib))
463463
return -ENODEV;
464464

465465
memcpy(&sch->schib, &schib, sizeof(schib));
466+
467+
if (!css_sch_is_valid(&schib))
468+
return -EACCES;
469+
466470
return 0;
467471
}
468472
EXPORT_SYMBOL_GPL(cio_update_schib);

drivers/s390/cio/device.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1387,21 +1387,35 @@ enum io_sch_action {
13871387
IO_SCH_VERIFY,
13881388
IO_SCH_DISC,
13891389
IO_SCH_NOP,
1390+
IO_SCH_ORPH_CDEV,
13901391
};
13911392

13921393
static enum io_sch_action sch_get_action(struct subchannel *sch)
13931394
{
13941395
struct ccw_device *cdev;
1396+
int rc;
13951397

13961398
cdev = sch_get_cdev(sch);
1397-
if (cio_update_schib(sch)) {
1399+
rc = cio_update_schib(sch);
1400+
1401+
if (rc == -ENODEV) {
13981402
/* Not operational. */
13991403
if (!cdev)
14001404
return IO_SCH_UNREG;
14011405
if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
14021406
return IO_SCH_UNREG;
14031407
return IO_SCH_ORPH_UNREG;
14041408
}
1409+
1410+
/* Avoid unregistering subchannels without working device. */
1411+
if (rc == -EACCES) {
1412+
if (!cdev)
1413+
return IO_SCH_NOP;
1414+
if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
1415+
return IO_SCH_UNREG_CDEV;
1416+
return IO_SCH_ORPH_CDEV;
1417+
}
1418+
14051419
/* Operational. */
14061420
if (!cdev)
14071421
return IO_SCH_ATTACH;
@@ -1471,6 +1485,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
14711485
rc = 0;
14721486
goto out_unlock;
14731487
case IO_SCH_ORPH_UNREG:
1488+
case IO_SCH_ORPH_CDEV:
14741489
case IO_SCH_ORPH_ATTACH:
14751490
ccw_device_set_disconnected(cdev);
14761491
break;
@@ -1502,6 +1517,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
15021517
/* Handle attached ccw device. */
15031518
switch (action) {
15041519
case IO_SCH_ORPH_UNREG:
1520+
case IO_SCH_ORPH_CDEV:
15051521
case IO_SCH_ORPH_ATTACH:
15061522
/* Move ccw device to orphanage. */
15071523
rc = ccw_device_move_to_orph(cdev);

0 commit comments

Comments
 (0)