diff options
Diffstat (limited to 'drivers/s390/cio/device_ops.c')
-rw-r--r-- | drivers/s390/cio/device_ops.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index 6da84543dfe9..651976b54af8 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c @@ -687,6 +687,46 @@ int ccw_device_tm_start_timeout(struct ccw_device *cdev, struct tcw *tcw, EXPORT_SYMBOL(ccw_device_tm_start_timeout); /** + * ccw_device_get_mdc - accumulate max data count + * @cdev: ccw device for which the max data count is accumulated + * @mask: mask of paths to use + * + * Return the number of 64K-bytes blocks all paths at least support + * for a transport command. Return values <= 0 indicate failures. + */ +int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask) +{ + struct subchannel *sch = to_subchannel(cdev->dev.parent); + struct channel_path_desc_fmt1 desc; + struct chp_id chpid; + int mdc = 0, ret, i; + + /* Adjust requested path mask to excluded varied off paths. */ + if (mask) + mask &= sch->lpm; + else + mask = sch->lpm; + + chp_id_init(&chpid); + for (i = 0; i < 8; i++) { + if (!(mask & (0x80 >> i))) + continue; + chpid.id = sch->schib.pmcw.chpid[i]; + ret = chsc_determine_fmt1_channel_path_desc(chpid, &desc); + if (ret) + return ret; + if (!desc.f) + return 0; + if (!desc.r) + mdc = 1; + mdc = mdc ? min(mdc, (int)desc.mdc) : desc.mdc; + } + + return mdc; +} +EXPORT_SYMBOL(ccw_device_get_mdc); + +/** * ccw_device_tm_intrg - perform interrogate function * @cdev: ccw device on which to perform the interrogate function * |