From: Stefan Haberland <sth@linux.ibm.com>
To: linux-s390@vger.kernel.org
Cc: Jan Hoeppner <hoeppner@linux.ibm.com>,
Eduard Shishkin <edward6@linux.ibm.com>
Subject: [PATCH 1/3] s390/dasd: Re-initialize RCD buffer with "V1.0" before every start
Date: Fri, 23 Oct 2026 11:21:16 +0200 [thread overview]
Message-ID: <20261023092118.3152286-2-sth@linux.ibm.com> (raw)
In-Reply-To: <20261023092118.3152286-1-sth@linux.ibm.com>
Under z/VM the Read Configuration Data (RCD) buffer has to start with
EBCDIC "V1.0" to request the virtual device SNEQ that carries the
minidisk UIT. The request and the response share the same buffer:
CP evaluates the magic on the way out and the RCD data is written into
the same buffer on the way back.
The magic is only written when the request is built and again in
read_conf_cb() when the original request fails.
Several restart paths do not run that callback:
- ERP use the same buffer and if the same error occurs again,
the ERP restarts the existing ERP request;
if a different error occurs, it adds another ERP request.
Neither re-initializes the magic.
- Terminated (timed out) ERP requests, killed requests and requests
requeued after the last path was gone are restarted without it.
- dasd_sleep_on_immediately() overwrites cqr->callback, so read_conf_cb()
never ran for dasd_eckd_read_conf_immediately(), and its fastpath
retries in dasd_int_handler() do not call a callback either.
If such a restart succeeds, z/VM omits the virtual device SNEQ, the UID
of that path is built without the UIT and the paths are reported as
"Not all channel paths lead to the same device" although they lead to
the same minidisk.
Every start of a request, whatever path led to it, goes through
dasd_start_IO(). Add an optional prepare_io function to the request
that dasd_start_IO() calls before every start of the request and of
its ERP requests, and use it to write the magic for RCD requests.
The ERP handling stays unchanged. read_conf_cb() is no longer needed
and is removed, which also gets rid of its memset() that only cleared
a single byte.
Fixes: 5915a873fcb1 ("[S390] dasd: re-initialize read_conf buffer for retries")
Cc: stable@vger.kernel.org
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
---
drivers/s390/block/dasd.c | 1 +
drivers/s390/block/dasd_eckd.c | 52 ++++++++++++----------------------
drivers/s390/block/dasd_int.h | 15 ++++++++++
3 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index d74ef737ae26..3a55c937d0d6 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1396,6 +1396,7 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
cqr->status = DASD_CQR_ERROR;
return -EIO;
}
+ dasd_start_IO_prepare(cqr);
cqr->startclk = get_tod_clock();
cqr->starttime = jiffies;
cqr->retries--;
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 970b83467276..e910d6b35f0f 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -845,20 +845,29 @@ static int dasd_eckd_compare_path_uid(struct dasd_device *device,
return memcmp(&device_uid, &path_uid, sizeof(struct dasd_uid));
}
+/*
+ * The RCD buffer has to start with EBCDIC "V1.0" to show support for
+ * virtual device SNEQ. The RCD data is written into the same buffer, so
+ * a failed attempt may already have overwritten the magic. Re-initialize
+ * it before every start, including restarts by ERP requests.
+ */
+static void dasd_eckd_rcd_prepare_io(struct dasd_ccw_req *cqr)
+{
+ struct ccw1 *ccw = cqr->cpaddr;
+ __u8 *rcd_buffer = dma32_to_virt(ccw->cda);
+
+ rcd_buffer[0] = 0xE5;
+ rcd_buffer[1] = 0xF1;
+ rcd_buffer[2] = 0x4B;
+ rcd_buffer[3] = 0xF0;
+}
+
static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device,
struct dasd_ccw_req *cqr,
__u8 *rcd_buffer,
__u8 lpm)
{
struct ccw1 *ccw;
- /*
- * buffer has to start with EBCDIC "V1.0" to show
- * support for virtual device SNEQ
- */
- rcd_buffer[0] = 0xE5;
- rcd_buffer[1] = 0xF1;
- rcd_buffer[2] = 0x4B;
- rcd_buffer[3] = 0xF0;
ccw = cqr->cpaddr;
ccw->cmd_code = DASD_ECKD_CCW_RCD;
@@ -875,33 +884,10 @@ static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device,
cqr->retries = 256;
cqr->buildclk = get_tod_clock();
cqr->status = DASD_CQR_FILLED;
+ cqr->prepare_io = dasd_eckd_rcd_prepare_io;
set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags);
}
-/*
- * Wakeup helper for read_conf
- * if the cqr is not done and needs some error recovery
- * the buffer has to be re-initialized with the EBCDIC "V1.0"
- * to show support for virtual device SNEQ
- */
-static void read_conf_cb(struct dasd_ccw_req *cqr, void *data)
-{
- struct ccw1 *ccw;
- __u8 *rcd_buffer;
-
- if (cqr->status != DASD_CQR_DONE) {
- ccw = cqr->cpaddr;
- rcd_buffer = dma32_to_virt(ccw->cda);
- memset(rcd_buffer, 0, sizeof(*rcd_buffer));
-
- rcd_buffer[0] = 0xE5;
- rcd_buffer[1] = 0xF1;
- rcd_buffer[2] = 0x4B;
- rcd_buffer[3] = 0xF0;
- }
- dasd_wakeup_cb(cqr, data);
-}
-
static int dasd_eckd_read_conf_immediately(struct dasd_device *device,
struct dasd_ccw_req *cqr,
__u8 *rcd_buffer,
@@ -921,7 +907,6 @@ static int dasd_eckd_read_conf_immediately(struct dasd_device *device,
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);
cqr->retries = 5;
- cqr->callback = read_conf_cb;
rc = dasd_sleep_on_immediately(cqr);
return rc;
}
@@ -959,7 +944,6 @@ static int dasd_eckd_read_conf_lpm(struct dasd_device *device,
goto out_error;
}
dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buf, lpm);
- cqr->callback = read_conf_cb;
ret = dasd_sleep_on(cqr);
/*
* on success we update the user input parms
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 7b154cd43625..1ff5188f0b97 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -147,6 +147,8 @@ struct dasd_ccw_req {
void *data; /* pointer to data area */
struct irb irb; /* device status in case of an error */
struct dasd_ccw_req *refers; /* ERP-chain queueing. */
+ /* optional prepare function called before every start_io, must not sleep */
+ void (*prepare_io)(struct dasd_ccw_req *cqr);
void *function; /* originating ERP action */
void *mem_chunk;
@@ -891,6 +893,19 @@ static inline void *dasd_get_callback_data(struct dasd_ccw_req *cqr)
return cqr->callback_data;
}
+/*
+ * Walk down the ERP chain to the original CQR and call its
+ * prepare_io function if set.
+ */
+static inline void dasd_start_IO_prepare(struct dasd_ccw_req *cqr)
+{
+ /* ERP requests use the prepare function of the original request */
+ while (cqr->refers)
+ cqr = cqr->refers;
+ if (cqr->prepare_io)
+ cqr->prepare_io(cqr);
+}
+
static inline bool dasd_req_conflict(struct dasd_ccw_req *cqr1,
struct dasd_ccw_req *cqr2)
{
--
2.53.0
next prev parent reply other threads:[~2026-10-23 9:21 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-23 9:21 [PATCH 0/3] s390/dasd: Fix BIODASDCHECKFMT issues and RCD retry handling Stefan Haberland
2026-10-23 9:21 ` Stefan Haberland [this message]
2026-10-23 9:21 ` [PATCH 2/3] s390/dasd: Fix wrong free and refcount leak in build_check_tcw error path Stefan Haberland
2026-10-23 9:21 ` [PATCH 3/3] s390/dasd: Don't trust userspace-supplied result field in format check Stefan Haberland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261023092118.3152286-2-sth@linux.ibm.com \
--to=sth@linux.ibm.com \
--cc=edward6@linux.ibm.com \
--cc=hoeppner@linux.ibm.com \
--cc=linux-s390@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox