Skip to content

Commit d99e79e

Browse files
Sebastian OttMartin Schwidefsky
Sebastian Ott
authored and
Martin Schwidefsky
committed
s390/cio: fix pgid reserved check
The check to whom a device is reserved is done by checking the path state of the affected channel paths. If it turns out that one path is flagged as reserved by someone else the whole device is marked as such. However the meaning of the RESVD_ELSE bit is that the addressed device is reserved to a different pathgroup (and not reserved to a different LPAR). If we do this test on a path which is currently not a member of the pathgroup we could erroneously mark the device as reserved to someone else. To fix this collect the reserved state for all potential members of the pathgroup and only mark the device as reserved if all of those potential members have the RESVD_ELSE bit set. Cc: [email protected] Acked-by: Peter Oberparleiter <[email protected]> Signed-off-by: Sebastian Ott <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent 1150f25 commit d99e79e

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

drivers/s390/cio/device_pgid.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ static int pgid_cmp(struct pgid *p1, struct pgid *p2)
234234
* Determine pathgroup state from PGID data.
235235
*/
236236
static void pgid_analyze(struct ccw_device *cdev, struct pgid **p,
237-
int *mismatch, int *reserved, u8 *reset)
237+
int *mismatch, u8 *reserved, u8 *reset)
238238
{
239239
struct pgid *pgid = &cdev->private->pgid[0];
240240
struct pgid *first = NULL;
@@ -248,7 +248,7 @@ static void pgid_analyze(struct ccw_device *cdev, struct pgid **p,
248248
if ((cdev->private->pgid_valid_mask & lpm) == 0)
249249
continue;
250250
if (pgid->inf.ps.state2 == SNID_STATE2_RESVD_ELSE)
251-
*reserved = 1;
251+
*reserved |= lpm;
252252
if (pgid_is_reset(pgid)) {
253253
*reset |= lpm;
254254
continue;
@@ -316,14 +316,14 @@ static void snid_done(struct ccw_device *cdev, int rc)
316316
struct subchannel *sch = to_subchannel(cdev->dev.parent);
317317
struct pgid *pgid;
318318
int mismatch = 0;
319-
int reserved = 0;
319+
u8 reserved = 0;
320320
u8 reset = 0;
321321
u8 donepm;
322322

323323
if (rc)
324324
goto out;
325325
pgid_analyze(cdev, &pgid, &mismatch, &reserved, &reset);
326-
if (reserved)
326+
if (reserved == cdev->private->pgid_valid_mask)
327327
rc = -EUSERS;
328328
else if (mismatch)
329329
rc = -EOPNOTSUPP;
@@ -336,7 +336,7 @@ static void snid_done(struct ccw_device *cdev, int rc)
336336
}
337337
out:
338338
CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x "
339-
"todo=%02x mism=%d rsvd=%d reset=%02x\n", id->ssid,
339+
"todo=%02x mism=%d rsvd=%02x reset=%02x\n", id->ssid,
340340
id->devno, rc, cdev->private->pgid_valid_mask, sch->vpm,
341341
cdev->private->pgid_todo_mask, mismatch, reserved, reset);
342342
switch (rc) {

0 commit comments

Comments
 (0)