aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorStefan Weinhuber <wein@de.ibm.com>2009-06-12 04:26:39 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-06-12 04:27:36 -0400
commit6cc7f168954fe8b3d8988a90b2478a9c11c5ebcb (patch)
treede3ee836f75f4cd1010a78c49d42393198b6f955 /drivers/s390
parent736e6ea0bf97ec79521f88704ce8506e5d60d078 (diff)
[S390] dasd: forward internal errors to dasd_sleep_on caller
If a DASD requests is started with dasd_sleep_on and fails, then the calling function may need to know the reason for the failure. In cases of hardware errors it can inspect the sense data in the irb, but when the reason is internal (e.g. start_IO failed) then it needs a meaningfull return code. Signed-off-by: Stefan Weinhuber <wein@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd.c30
-rw-r--r--drivers/s390/block/dasd_diag.c1
-rw-r--r--drivers/s390/block/dasd_eckd.c8
-rw-r--r--drivers/s390/block/dasd_int.h1
4 files changed, 31 insertions, 9 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 35f43bea5d07..442bb98a2821 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -851,8 +851,10 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
851 851
852 /* Check the cqr */ 852 /* Check the cqr */
853 rc = dasd_check_cqr(cqr); 853 rc = dasd_check_cqr(cqr);
854 if (rc) 854 if (rc) {
855 cqr->intrc = rc;
855 return rc; 856 return rc;
857 }
856 device = (struct dasd_device *) cqr->startdev; 858 device = (struct dasd_device *) cqr->startdev;
857 if (cqr->retries < 0) { 859 if (cqr->retries < 0) {
858 /* internal error 14 - start_IO run out of retries */ 860 /* internal error 14 - start_IO run out of retries */
@@ -915,6 +917,7 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
915 BUG(); 917 BUG();
916 break; 918 break;
917 } 919 }
920 cqr->intrc = rc;
918 return rc; 921 return rc;
919} 922}
920 923
@@ -1454,8 +1457,12 @@ int dasd_sleep_on(struct dasd_ccw_req *cqr)
1454 dasd_add_request_tail(cqr); 1457 dasd_add_request_tail(cqr);
1455 wait_event(generic_waitq, _wait_for_wakeup(cqr)); 1458 wait_event(generic_waitq, _wait_for_wakeup(cqr));
1456 1459
1457 /* Request status is either done or failed. */ 1460 if (cqr->status == DASD_CQR_DONE)
1458 rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; 1461 rc = 0;
1462 else if (cqr->intrc)
1463 rc = cqr->intrc;
1464 else
1465 rc = -EIO;
1459 return rc; 1466 return rc;
1460} 1467}
1461 1468
@@ -1477,8 +1484,15 @@ int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr)
1477 dasd_cancel_req(cqr); 1484 dasd_cancel_req(cqr);
1478 /* wait (non-interruptible) for final status */ 1485 /* wait (non-interruptible) for final status */
1479 wait_event(generic_waitq, _wait_for_wakeup(cqr)); 1486 wait_event(generic_waitq, _wait_for_wakeup(cqr));
1487 cqr->intrc = rc;
1480 } 1488 }
1481 rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; 1489
1490 if (cqr->status == DASD_CQR_DONE)
1491 rc = 0;
1492 else if (cqr->intrc)
1493 rc = cqr->intrc;
1494 else
1495 rc = -EIO;
1482 return rc; 1496 return rc;
1483} 1497}
1484 1498
@@ -1523,8 +1537,12 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
1523 1537
1524 wait_event(generic_waitq, _wait_for_wakeup(cqr)); 1538 wait_event(generic_waitq, _wait_for_wakeup(cqr));
1525 1539
1526 /* Request status is either done or failed. */ 1540 if (cqr->status == DASD_CQR_DONE)
1527 rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; 1541 rc = 0;
1542 else if (cqr->intrc)
1543 rc = cqr->intrc;
1544 else
1545 rc = -EIO;
1528 return rc; 1546 return rc;
1529} 1547}
1530 1548
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 2efaddfae560..644086ba2ede 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -202,6 +202,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr)
202 rc = -EIO; 202 rc = -EIO;
203 break; 203 break;
204 } 204 }
205 cqr->intrc = rc;
205 return rc; 206 return rc;
206} 207}
207 208
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 216c09bcd222..cf0cfdba1244 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -3017,8 +3017,9 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
3017 " I/O status report for device %s:\n", 3017 " I/O status report for device %s:\n",
3018 dev_name(&device->cdev->dev)); 3018 dev_name(&device->cdev->dev));
3019 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3019 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3020 " in req: %p CS: 0x%02X DS: 0x%02X\n", req, 3020 " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d\n",
3021 scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw)); 3021 req, scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
3022 scsw_cc(&irb->scsw), req->intrc);
3022 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3023 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3023 " device %s: Failing CCW: %p\n", 3024 " device %s: Failing CCW: %p\n",
3024 dev_name(&device->cdev->dev), 3025 dev_name(&device->cdev->dev),
@@ -3119,9 +3120,10 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
3119 " I/O status report for device %s:\n", 3120 " I/O status report for device %s:\n",
3120 dev_name(&device->cdev->dev)); 3121 dev_name(&device->cdev->dev));
3121 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3122 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3122 " in req: %p CS: 0x%02X DS: 0x%02X " 3123 " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d "
3123 "fcxs: 0x%02X schxs: 0x%02X\n", req, 3124 "fcxs: 0x%02X schxs: 0x%02X\n", req,
3124 scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw), 3125 scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
3126 scsw_cc(&irb->scsw), req->intrc,
3125 irb->scsw.tm.fcxs, irb->scsw.tm.schxs); 3127 irb->scsw.tm.fcxs, irb->scsw.tm.schxs);
3126 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3128 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3127 " device %s: Failing TCW: %p\n", 3129 " device %s: Failing TCW: %p\n",
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 3ab69b5a41f6..f97ceb795078 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -173,6 +173,7 @@ struct dasd_ccw_req {
173 void *data; /* pointer to data area */ 173 void *data; /* pointer to data area */
174 174
175 /* these are important for recovering erroneous requests */ 175 /* these are important for recovering erroneous requests */
176 int intrc; /* internal error, e.g. from start_IO */
176 struct irb irb; /* device status in case of an error */ 177 struct irb irb; /* device status in case of an error */
177 struct dasd_ccw_req *refers; /* ERP-chain queueing. */ 178 struct dasd_ccw_req *refers; /* ERP-chain queueing. */
178 void *function; /* originating ERP action */ 179 void *function; /* originating ERP action */