summaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-04-19 09:59:15 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-04-19 09:59:15 -0700
commit3cdb455946193bb7ad13df15333c7fe0054db6c3 (patch)
treeaf72c748cf1cdd607c944d5f082076a383336be9 /drivers/s390/cio/device.c
parent9c6e84e4baf01a33a72cdfd1256d0f281c0ea812 (diff)
parentd111855ab7ffffc552f6a475259dc392f2319b6d (diff)
downloadlinux-stable-3cdb455946193bb7ad13df15333c7fe0054db6c3.tar.gz
linux-stable-3cdb455946193bb7ad13df15333c7fe0054db6c3.tar.bz2
linux-stable-3cdb455946193bb7ad13df15333c7fe0054db6c3.zip
Merge tag 's390-6.9-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Alexander Gordeev: - Fix NULL pointer dereference in program check handler - Fake IRBs are important events relevant for problem analysis. Add traces when queueing and delivering - Fix a race condition in ccw_device_set_online() that can cause the online process to fail - Deferred condition code 1 response indicates that I/O was not started and should be retried. The current QDIO implementation handles a cc1 response as an error, resulting in a failed QDIO setup. Fix that by retrying the setup when a cc1 response is received * tag 's390-6.9-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/mm: Fix NULL pointer dereference s390/cio: log fake IRB events s390/cio: fix race condition during online processing s390/qdio: handle deferred cc1
Diffstat (limited to 'drivers/s390/cio/device.c')
-rw-r--r--drivers/s390/cio/device.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index f95d12345d98..920f550bc313 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -363,10 +363,8 @@ int ccw_device_set_online(struct ccw_device *cdev)
spin_lock_irq(cdev->ccwlock);
ret = ccw_device_online(cdev);
- spin_unlock_irq(cdev->ccwlock);
- if (ret == 0)
- wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
- else {
+ if (ret) {
+ spin_unlock_irq(cdev->ccwlock);
CIO_MSG_EVENT(0, "ccw_device_online returned %d, "
"device 0.%x.%04x\n",
ret, cdev->private->dev_id.ssid,
@@ -375,7 +373,12 @@ int ccw_device_set_online(struct ccw_device *cdev)
put_device(&cdev->dev);
return ret;
}
- spin_lock_irq(cdev->ccwlock);
+ /* Wait until a final state is reached */
+ while (!dev_fsm_final_state(cdev)) {
+ spin_unlock_irq(cdev->ccwlock);
+ wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
+ spin_lock_irq(cdev->ccwlock);
+ }
/* Check if online processing was successful */
if ((cdev->private->state != DEV_STATE_ONLINE) &&
(cdev->private->state != DEV_STATE_W4SENSE)) {