diff options
Diffstat (limited to 'drivers/s390/block/dasd_eckd.c')
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 21254793c604..cb52da033f06 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -2019,15 +2019,23 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track( | |||
2019 | ccw++; | 2019 | ccw++; |
2020 | recid += count; | 2020 | recid += count; |
2021 | new_track = 0; | 2021 | new_track = 0; |
2022 | /* first idaw for a ccw may start anywhere */ | ||
2023 | if (!idaw_dst) | ||
2024 | idaw_dst = dst; | ||
2022 | } | 2025 | } |
2023 | /* If we start a new idaw, everything is fine and the | 2026 | /* If we start a new idaw, we must make sure that it |
2024 | * start of the new idaw is the start of this segment. | 2027 | * starts on an IDA_BLOCK_SIZE boundary. |
2025 | * If we continue an idaw, we must make sure that the | 2028 | * If we continue an idaw, we must make sure that the |
2026 | * current segment begins where the so far accumulated | 2029 | * current segment begins where the so far accumulated |
2027 | * idaw ends | 2030 | * idaw ends |
2028 | */ | 2031 | */ |
2029 | if (!idaw_dst) | 2032 | if (!idaw_dst) { |
2030 | idaw_dst = dst; | 2033 | if (__pa(dst) & (IDA_BLOCK_SIZE-1)) { |
2034 | dasd_sfree_request(cqr, startdev); | ||
2035 | return ERR_PTR(-ERANGE); | ||
2036 | } else | ||
2037 | idaw_dst = dst; | ||
2038 | } | ||
2031 | if ((idaw_dst + idaw_len) != dst) { | 2039 | if ((idaw_dst + idaw_len) != dst) { |
2032 | dasd_sfree_request(cqr, startdev); | 2040 | dasd_sfree_request(cqr, startdev); |
2033 | return ERR_PTR(-ERANGE); | 2041 | return ERR_PTR(-ERANGE); |