aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2014-03-21 10:24:27 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2014-04-01 03:23:36 -0400
commitbd1cb5de140d844f63389bf21b336c194a8c83a1 (patch)
treebf9d6e30ce80c0cf8f82d70903dff29fbf328822
parent0ccc8b7ac86053388e793bad20bd26bd777752eb (diff)
s390/3270: fix crash with multiple reset device requests
If the 3270 device is detached the initial reset device request will stays pending until the device is operational. A second reset device call will reuse the same request structure which will cause an oops. Add a check to see if the reset device request is already pending and do nothing in this case. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/char/raw3270.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 9f849df4381e..15b3459f8656 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -632,6 +632,8 @@ raw3270_reset_device_cb(struct raw3270_request *rq, void *data)
632 raw3270_size_device_done(rp); 632 raw3270_size_device_done(rp);
633 } else 633 } else
634 raw3270_writesf_readpart(rp); 634 raw3270_writesf_readpart(rp);
635 memset(&rp->init_reset, 0, sizeof(rp->init_reset));
636 memset(&rp->init_data, 0, sizeof(rp->init_data));
635} 637}
636 638
637static int 639static int
@@ -639,9 +641,10 @@ __raw3270_reset_device(struct raw3270 *rp)
639{ 641{
640 int rc; 642 int rc;
641 643
644 /* Check if reset is already pending */
645 if (rp->init_reset.view)
646 return -EBUSY;
642 /* Store reset data stream to init_data/init_reset */ 647 /* Store reset data stream to init_data/init_reset */
643 memset(&rp->init_reset, 0, sizeof(rp->init_reset));
644 memset(&rp->init_data, 0, sizeof(rp->init_data));
645 rp->init_data[0] = TW_KR; 648 rp->init_data[0] = TW_KR;
646 rp->init_reset.ccw.cmd_code = TC_EWRITEA; 649 rp->init_reset.ccw.cmd_code = TC_EWRITEA;
647 rp->init_reset.ccw.flags = CCW_FLAG_SLI; 650 rp->init_reset.ccw.flags = CCW_FLAG_SLI;
@@ -850,7 +853,7 @@ raw3270_create_device(struct ccw_device *cdev)
850 char *ascebc; 853 char *ascebc;
851 int rc; 854 int rc;
852 855
853 rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA); 856 rp = kzalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA);
854 if (!rp) 857 if (!rp)
855 return ERR_PTR(-ENOMEM); 858 return ERR_PTR(-ENOMEM);
856 ascebc = kmalloc(256, GFP_KERNEL); 859 ascebc = kmalloc(256, GFP_KERNEL);