Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 770b55c9 authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky
Browse files

s390/cio: fix return code after missing interrupt



When a timeout occurs for users of ccw_device_start_timeout
we will stop the IO and call the drivers int handler with
the irb pointer set to ERR_PTR(-ETIMEDOUT). Sometimes
however we'd set the irb pointer to ERR_PTR(-EIO) which is
not intended. Just set the correct value in all codepaths.

Reported-by: default avatarJulian Wiedmann <jwi@linux.vnet.ibm.com>
Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent f97a6b6c
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -795,6 +795,7 @@ ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event)


	ccw_device_set_timeout(cdev, 0);
	ccw_device_set_timeout(cdev, 0);
	cdev->private->iretry = 255;
	cdev->private->iretry = 255;
	cdev->private->async_kill_io_rc = -ETIMEDOUT;
	ret = ccw_device_cancel_halt_clear(cdev);
	ret = ccw_device_cancel_halt_clear(cdev);
	if (ret == -EBUSY) {
	if (ret == -EBUSY) {
		ccw_device_set_timeout(cdev, 3*HZ);
		ccw_device_set_timeout(cdev, 3*HZ);
@@ -871,7 +872,7 @@ ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
	/* OK, i/o is dead now. Call interrupt handler. */
	/* OK, i/o is dead now. Call interrupt handler. */
	if (cdev->handler)
	if (cdev->handler)
		cdev->handler(cdev, cdev->private->intparm,
		cdev->handler(cdev, cdev->private->intparm,
			      ERR_PTR(-EIO));
			      ERR_PTR(cdev->private->async_kill_io_rc));
}
}


static void
static void
@@ -888,7 +889,7 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event)
	ccw_device_online_verify(cdev, 0);
	ccw_device_online_verify(cdev, 0);
	if (cdev->handler)
	if (cdev->handler)
		cdev->handler(cdev, cdev->private->intparm,
		cdev->handler(cdev, cdev->private->intparm,
			      ERR_PTR(-EIO));
			      ERR_PTR(cdev->private->async_kill_io_rc));
}
}


void ccw_device_kill_io(struct ccw_device *cdev)
void ccw_device_kill_io(struct ccw_device *cdev)
@@ -896,6 +897,7 @@ void ccw_device_kill_io(struct ccw_device *cdev)
	int ret;
	int ret;


	cdev->private->iretry = 255;
	cdev->private->iretry = 255;
	cdev->private->async_kill_io_rc = -EIO;
	ret = ccw_device_cancel_halt_clear(cdev);
	ret = ccw_device_cancel_halt_clear(cdev);
	if (ret == -EBUSY) {
	if (ret == -EBUSY) {
		ccw_device_set_timeout(cdev, 3*HZ);
		ccw_device_set_timeout(cdev, 3*HZ);
+1 −0
Original line number Original line Diff line number Diff line
@@ -157,6 +157,7 @@ struct ccw_device_private {
	unsigned long intparm;	/* user interruption parameter */
	unsigned long intparm;	/* user interruption parameter */
	struct qdio_irq *qdio_data;
	struct qdio_irq *qdio_data;
	struct irb irb;		/* device status */
	struct irb irb;		/* device status */
	int async_kill_io_rc;
	struct senseid senseid;	/* SenseID info */
	struct senseid senseid;	/* SenseID info */
	struct pgid pgid[8];	/* path group IDs per chpid*/
	struct pgid pgid[8];	/* path group IDs per chpid*/
	struct ccw1 iccws[2];	/* ccws for SNID/SID/SPGID commands */
	struct ccw1 iccws[2];	/* ccws for SNID/SID/SPGID commands */