Skip to content

Commit

Permalink
s390/dasd: extend dasd path handling
Browse files Browse the repository at this point in the history
Store flags and path_data per channel path.
Implement get/set functions for various path masks.
The patch does not add functional changes.

Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
Reviewed-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
  • Loading branch information
Stefan Haberland authored and Martin Schwidefsky committed Dec 12, 2016
1 parent 7df1160 commit c934615
Show file tree
Hide file tree
Showing 8 changed files with 475 additions and 143 deletions.
101 changes: 46 additions & 55 deletions drivers/s390/block/dasd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1448,9 +1448,9 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
cqr->starttime = jiffies;
cqr->retries--;
if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags)) {
cqr->lpm &= device->path_data.opm;
cqr->lpm &= dasd_path_get_opm(device);
if (!cqr->lpm)
cqr->lpm = device->path_data.opm;
cqr->lpm = dasd_path_get_opm(device);
}
if (cqr->cpmode == 1) {
rc = ccw_device_tm_start(device->cdev, cqr->cpaddr,
Expand Down Expand Up @@ -1483,8 +1483,8 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
DBF_DEV_EVENT(DBF_WARNING, device,
"start_IO: selected paths gone (%x)",
cqr->lpm);
} else if (cqr->lpm != device->path_data.opm) {
cqr->lpm = device->path_data.opm;
} else if (cqr->lpm != dasd_path_get_opm(device)) {
cqr->lpm = dasd_path_get_opm(device);
DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"start_IO: selected paths gone,"
" retry on all paths");
Expand All @@ -1493,11 +1493,10 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
"start_IO: all paths in opm gone,"
" do path verification");
dasd_generic_last_path_gone(device);
device->path_data.opm = 0;
device->path_data.ppm = 0;
device->path_data.npm = 0;
device->path_data.tbvpm =
ccw_device_get_path_mask(device->cdev);
dasd_path_no_path(device);
dasd_path_set_tbvpm(device,
ccw_device_get_path_mask(
device->cdev));
}
break;
case -ENODEV:
Expand Down Expand Up @@ -1642,7 +1641,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
switch (PTR_ERR(irb)) {
case -EIO:
if (cqr && cqr->status == DASD_CQR_CLEAR_PENDING) {
device = (struct dasd_device *) cqr->startdev;
device = cqr->startdev;
cqr->status = DASD_CQR_CLEARED;
dasd_device_clear_timer(device);
wake_up(&dasd_flush_wq);
Expand Down Expand Up @@ -1755,13 +1754,13 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
*/
if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags) &&
cqr->retries > 0) {
if (cqr->lpm == device->path_data.opm)
if (cqr->lpm == dasd_path_get_opm(device))
DBF_DEV_EVENT(DBF_DEBUG, device,
"default ERP in fastpath "
"(%i retries left)",
cqr->retries);
if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags))
cqr->lpm = device->path_data.opm;
cqr->lpm = dasd_path_get_opm(device);
cqr->status = DASD_CQR_QUEUED;
next = cqr;
} else
Expand Down Expand Up @@ -2002,17 +2001,18 @@ static void __dasd_device_check_path_events(struct dasd_device *device)
{
int rc;

if (device->path_data.tbvpm) {
if (device->stopped & ~(DASD_STOPPED_DC_WAIT |
DASD_UNRESUMED_PM))
return;
rc = device->discipline->verify_path(
device, device->path_data.tbvpm);
if (rc)
dasd_device_set_timer(device, 50);
else
device->path_data.tbvpm = 0;
}
if (!dasd_path_get_tbvpm(device))
return;

if (device->stopped &
~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM))
return;
rc = device->discipline->verify_path(device,
dasd_path_get_tbvpm(device));
if (rc)
dasd_device_set_timer(device, 50);
else
dasd_path_clear_all_verify(device);
};

/*
Expand Down Expand Up @@ -3684,14 +3684,12 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
case CIO_GONE:
case CIO_BOXED:
case CIO_NO_PATH:
device->path_data.opm = 0;
device->path_data.ppm = 0;
device->path_data.npm = 0;
dasd_path_no_path(device);
ret = dasd_generic_last_path_gone(device);
break;
case CIO_OPER:
ret = 1;
if (device->path_data.opm)
if (dasd_path_get_opm(device))
ret = dasd_generic_path_operational(device);
break;
}
Expand All @@ -3702,66 +3700,59 @@ EXPORT_SYMBOL_GPL(dasd_generic_notify);

void dasd_generic_path_event(struct ccw_device *cdev, int *path_event)
{
int chp;
__u8 oldopm, eventlpm;
struct dasd_device *device;
int chp, oldopm;

device = dasd_device_from_cdev_locked(cdev);
if (IS_ERR(device))
return;

oldopm = dasd_path_get_opm(device);
for (chp = 0; chp < 8; chp++) {
eventlpm = 0x80 >> chp;
if (path_event[chp] & PE_PATH_GONE) {
oldopm = device->path_data.opm;
device->path_data.opm &= ~eventlpm;
device->path_data.ppm &= ~eventlpm;
device->path_data.npm &= ~eventlpm;
if (oldopm && !device->path_data.opm) {
dev_warn(&device->cdev->dev,
"No verified channel paths remain "
"for the device\n");
DBF_DEV_EVENT(DBF_WARNING, device,
"%s", "last verified path gone");
dasd_eer_write(device, NULL, DASD_EER_NOPATH);
dasd_device_set_stop_bits(device,
DASD_STOPPED_DC_WAIT);
}
dasd_path_notoper(device, chp);
}
if (path_event[chp] & PE_PATH_AVAILABLE) {
device->path_data.opm &= ~eventlpm;
device->path_data.ppm &= ~eventlpm;
device->path_data.npm &= ~eventlpm;
device->path_data.tbvpm |= eventlpm;
dasd_path_available(device, chp);
dasd_schedule_device_bh(device);
}
if (path_event[chp] & PE_PATHGROUP_ESTABLISHED) {
if (!(device->path_data.opm & eventlpm) &&
!(device->path_data.tbvpm & eventlpm)) {
if (!dasd_path_is_operational(device, chp) &&
!dasd_path_need_verify(device, chp)) {
/*
* we can not establish a pathgroup on an
* unavailable path, so trigger a path
* verification first
*/
device->path_data.tbvpm |= eventlpm;
dasd_schedule_device_bh(device);
dasd_path_available(device, chp);
dasd_schedule_device_bh(device);
}
DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Pathgroup re-established\n");
if (device->discipline->kick_validate)
device->discipline->kick_validate(device);
}
}
if (oldopm && !dasd_path_get_opm(device)) {
dev_warn(&device->cdev->dev,
"No verified channel paths remain for the device\n");
DBF_DEV_EVENT(DBF_WARNING, device,
"%s", "last verified path gone");
dasd_eer_write(device, NULL, DASD_EER_NOPATH);
dasd_device_set_stop_bits(device,
DASD_STOPPED_DC_WAIT);
}
dasd_put_device(device);
}
EXPORT_SYMBOL_GPL(dasd_generic_path_event);

int dasd_generic_verify_path(struct dasd_device *device, __u8 lpm)
{
if (!device->path_data.opm && lpm) {
device->path_data.opm = lpm;
if (!dasd_path_get_opm(device) && lpm) {
dasd_path_set_opm(device, lpm);
dasd_generic_path_operational(device);
} else
device->path_data.opm |= lpm;
dasd_path_add_opm(device, lpm);
return 0;
}
EXPORT_SYMBOL_GPL(dasd_generic_verify_path);
Expand Down
6 changes: 3 additions & 3 deletions drivers/s390/block/dasd_3990_erp.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
opm = ccw_device_get_path_mask(device->cdev);
spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
if (erp->lpm == 0)
erp->lpm = device->path_data.opm &
erp->lpm = dasd_path_get_opm(device) &
~(erp->irb.esw.esw0.sublog.lpum);
else
erp->lpm &= ~(erp->irb.esw.esw0.sublog.lpum);
Expand Down Expand Up @@ -273,7 +273,7 @@ static struct dasd_ccw_req *dasd_3990_erp_action_1(struct dasd_ccw_req *erp)
!test_bit(DASD_CQR_VERIFY_PATH, &erp->flags)) {
erp->status = DASD_CQR_FILLED;
erp->retries = 10;
erp->lpm = erp->startdev->path_data.opm;
erp->lpm = dasd_path_get_opm(erp->startdev);
erp->function = dasd_3990_erp_action_1_sec;
}
return erp;
Expand Down Expand Up @@ -1926,7 +1926,7 @@ dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense)
!test_bit(DASD_CQR_VERIFY_PATH, &erp->flags)) {
/* reset the lpm and the status to be able to
* try further actions. */
erp->lpm = erp->startdev->path_data.opm;
erp->lpm = dasd_path_get_opm(erp->startdev);
erp->status = DASD_CQR_NEED_ERP;
}
}
Expand Down
10 changes: 5 additions & 5 deletions drivers/s390/block/dasd_devmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1438,11 +1438,11 @@ static ssize_t dasd_pm_show(struct device *dev,
if (IS_ERR(device))
return sprintf(buf, "0\n");

opm = device->path_data.opm;
nppm = device->path_data.npm;
cablepm = device->path_data.cablepm;
cuirpm = device->path_data.cuirpm;
hpfpm = device->path_data.hpfpm;
opm = dasd_path_get_opm(device);
nppm = dasd_path_get_nppm(device);
cablepm = dasd_path_get_cablepm(device);
cuirpm = dasd_path_get_cuirpm(device);
hpfpm = dasd_path_get_hpfpm(device);
dasd_put_device(device);

return sprintf(buf, "%02x %02x %02x %02x %02x\n", opm, nppm,
Expand Down
Loading

0 comments on commit c934615

Please sign in to comment.