mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-26 05:40:53 +07:00
[S390] ccw_device_notify: improve return codes
Callers of ccw_device_notify could not distinguish between a driver who has no notifier registered and a driver who doesn't want to keep a device after a certain event. Change this by adding proper return codes. Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
b4c707214c
commit
76e6fb4b86
@ -1338,7 +1338,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch)
|
||||
/* Not operational. */
|
||||
if (!cdev)
|
||||
return IO_SCH_UNREG;
|
||||
if (!ccw_device_notify(cdev, CIO_GONE))
|
||||
if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
|
||||
return IO_SCH_UNREG;
|
||||
return IO_SCH_ORPH_UNREG;
|
||||
}
|
||||
@ -1346,12 +1346,12 @@ static enum io_sch_action sch_get_action(struct subchannel *sch)
|
||||
if (!cdev)
|
||||
return IO_SCH_ATTACH;
|
||||
if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) {
|
||||
if (!ccw_device_notify(cdev, CIO_GONE))
|
||||
if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
|
||||
return IO_SCH_UNREG_ATTACH;
|
||||
return IO_SCH_ORPH_ATTACH;
|
||||
}
|
||||
if ((sch->schib.pmcw.pam & sch->opm) == 0) {
|
||||
if (!ccw_device_notify(cdev, CIO_NO_PATH))
|
||||
if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK)
|
||||
return IO_SCH_UNREG;
|
||||
return IO_SCH_DISC;
|
||||
}
|
||||
@ -1788,7 +1788,7 @@ static void __ccw_device_pm_restore(struct ccw_device *cdev)
|
||||
static int resume_handle_boxed(struct ccw_device *cdev)
|
||||
{
|
||||
cdev->private->state = DEV_STATE_BOXED;
|
||||
if (ccw_device_notify(cdev, CIO_BOXED))
|
||||
if (ccw_device_notify(cdev, CIO_BOXED) == NOTIFY_OK)
|
||||
return 0;
|
||||
ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
|
||||
return -ENODEV;
|
||||
@ -1797,7 +1797,7 @@ static int resume_handle_boxed(struct ccw_device *cdev)
|
||||
static int resume_handle_disc(struct ccw_device *cdev)
|
||||
{
|
||||
cdev->private->state = DEV_STATE_DISCONNECTED;
|
||||
if (ccw_device_notify(cdev, CIO_GONE))
|
||||
if (ccw_device_notify(cdev, CIO_GONE) == NOTIFY_OK)
|
||||
return 0;
|
||||
ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
|
||||
return -ENODEV;
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <asm/ccwdev.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include <linux/notifier.h>
|
||||
#include "io_sch.h"
|
||||
|
||||
/*
|
||||
|
@ -313,21 +313,43 @@ ccw_device_sense_id_done(struct ccw_device *cdev, int err)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ccw_device_notify() - inform the device's driver about an event
|
||||
* @cdev: device for which an event occured
|
||||
* @event: event that occurred
|
||||
*
|
||||
* Returns:
|
||||
* -%EINVAL if the device is offline or has no driver.
|
||||
* -%EOPNOTSUPP if the device's driver has no notifier registered.
|
||||
* %NOTIFY_OK if the driver wants to keep the device.
|
||||
* %NOTIFY_BAD if the driver doesn't want to keep the device.
|
||||
*/
|
||||
int ccw_device_notify(struct ccw_device *cdev, int event)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (!cdev->drv)
|
||||
return 0;
|
||||
goto out;
|
||||
if (!cdev->online)
|
||||
return 0;
|
||||
goto out;
|
||||
CIO_MSG_EVENT(2, "notify called for 0.%x.%04x, event=%d\n",
|
||||
cdev->private->dev_id.ssid, cdev->private->dev_id.devno,
|
||||
event);
|
||||
return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0;
|
||||
if (!cdev->drv->notify) {
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
if (cdev->drv->notify(cdev, event))
|
||||
ret = NOTIFY_OK;
|
||||
else
|
||||
ret = NOTIFY_BAD;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ccw_device_oper_notify(struct ccw_device *cdev)
|
||||
{
|
||||
if (ccw_device_notify(cdev, CIO_OPER)) {
|
||||
if (ccw_device_notify(cdev, CIO_OPER) == NOTIFY_OK) {
|
||||
/* Reenable channel measurements, if needed. */
|
||||
ccw_device_sched_todo(cdev, CDEV_TODO_ENABLE_CMF);
|
||||
return;
|
||||
@ -361,14 +383,15 @@ ccw_device_done(struct ccw_device *cdev, int state)
|
||||
case DEV_STATE_BOXED:
|
||||
CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
|
||||
cdev->private->dev_id.devno, sch->schid.sch_no);
|
||||
if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED))
|
||||
if (cdev->online &&
|
||||
ccw_device_notify(cdev, CIO_BOXED) != NOTIFY_OK)
|
||||
ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
|
||||
cdev->private->flags.donotify = 0;
|
||||
break;
|
||||
case DEV_STATE_NOT_OPER:
|
||||
CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n",
|
||||
cdev->private->dev_id.devno, sch->schid.sch_no);
|
||||
if (!ccw_device_notify(cdev, CIO_GONE))
|
||||
if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
|
||||
ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
|
||||
else
|
||||
ccw_device_set_disconnected(cdev);
|
||||
@ -378,7 +401,7 @@ ccw_device_done(struct ccw_device *cdev, int state)
|
||||
CIO_MSG_EVENT(0, "Disconnected device %04x on subchannel "
|
||||
"%04x\n", cdev->private->dev_id.devno,
|
||||
sch->schid.sch_no);
|
||||
if (!ccw_device_notify(cdev, CIO_NO_PATH))
|
||||
if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK)
|
||||
ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
|
||||
else
|
||||
ccw_device_set_disconnected(cdev);
|
||||
@ -586,7 +609,7 @@ ccw_device_offline(struct ccw_device *cdev)
|
||||
static void ccw_device_generic_notoper(struct ccw_device *cdev,
|
||||
enum dev_event dev_event)
|
||||
{
|
||||
if (!ccw_device_notify(cdev, CIO_GONE))
|
||||
if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
|
||||
ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
|
||||
else
|
||||
ccw_device_set_disconnected(cdev);
|
||||
|
Loading…
Reference in New Issue
Block a user