[S390] cio: notify drivers of channel path events
This patch adds a notification mechanism to inform ccw drivers about changes to channel paths, which occured while the device is online. Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:

zatwierdzone przez
Martin Schwidefsky

rodzic
eb4f5d93d7
commit
585b954e1f
@@ -349,9 +349,13 @@ out:
|
||||
|
||||
static void ccw_device_oper_notify(struct ccw_device *cdev)
|
||||
{
|
||||
struct subchannel *sch = to_subchannel(cdev->dev.parent);
|
||||
|
||||
if (ccw_device_notify(cdev, CIO_OPER) == NOTIFY_OK) {
|
||||
/* Reenable channel measurements, if needed. */
|
||||
ccw_device_sched_todo(cdev, CDEV_TODO_ENABLE_CMF);
|
||||
/* Save indication for new paths. */
|
||||
cdev->private->path_new_mask = sch->vpm;
|
||||
return;
|
||||
}
|
||||
/* Driver doesn't want device back. */
|
||||
@@ -462,6 +466,32 @@ static void ccw_device_request_event(struct ccw_device *cdev, enum dev_event e)
|
||||
}
|
||||
}
|
||||
|
||||
static void ccw_device_report_path_events(struct ccw_device *cdev)
|
||||
{
|
||||
struct subchannel *sch = to_subchannel(cdev->dev.parent);
|
||||
int path_event[8];
|
||||
int chp, mask;
|
||||
|
||||
for (chp = 0, mask = 0x80; chp < 8; chp++, mask >>= 1) {
|
||||
path_event[chp] = PE_NONE;
|
||||
if (mask & cdev->private->path_gone_mask & ~(sch->vpm))
|
||||
path_event[chp] |= PE_PATH_GONE;
|
||||
if (mask & cdev->private->path_new_mask & sch->vpm)
|
||||
path_event[chp] |= PE_PATH_AVAILABLE;
|
||||
if (mask & cdev->private->pgid_reset_mask & sch->vpm)
|
||||
path_event[chp] |= PE_PATHGROUP_ESTABLISHED;
|
||||
}
|
||||
if (cdev->online && cdev->drv->path_event)
|
||||
cdev->drv->path_event(cdev, path_event);
|
||||
}
|
||||
|
||||
static void ccw_device_reset_path_events(struct ccw_device *cdev)
|
||||
{
|
||||
cdev->private->path_gone_mask = 0;
|
||||
cdev->private->path_new_mask = 0;
|
||||
cdev->private->pgid_reset_mask = 0;
|
||||
}
|
||||
|
||||
void
|
||||
ccw_device_verify_done(struct ccw_device *cdev, int err)
|
||||
{
|
||||
@@ -498,6 +528,7 @@ callback:
|
||||
&cdev->private->irb);
|
||||
memset(&cdev->private->irb, 0, sizeof(struct irb));
|
||||
}
|
||||
ccw_device_report_path_events(cdev);
|
||||
break;
|
||||
case -ETIME:
|
||||
case -EUSERS:
|
||||
@@ -516,6 +547,7 @@ callback:
|
||||
ccw_device_done(cdev, DEV_STATE_NOT_OPER);
|
||||
break;
|
||||
}
|
||||
ccw_device_reset_path_events(cdev);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user