aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/block/dasd.c')
-rw-r--r--drivers/s390/block/dasd.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index ac6d4d3218b3..1a4025683362 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -63,6 +63,7 @@ static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *);
63 */ 63 */
64static wait_queue_head_t dasd_init_waitq; 64static wait_queue_head_t dasd_init_waitq;
65static wait_queue_head_t dasd_flush_wq; 65static wait_queue_head_t dasd_flush_wq;
66static wait_queue_head_t generic_waitq;
66 67
67/* 68/*
68 * Allocate memory for a new device structure. 69 * Allocate memory for a new device structure.
@@ -925,6 +926,8 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
925 struct dasd_ccw_req *cqr; 926 struct dasd_ccw_req *cqr;
926 struct dasd_device *device; 927 struct dasd_device *device;
927 928
929 if (!intparm)
930 return;
928 cqr = (struct dasd_ccw_req *) intparm; 931 cqr = (struct dasd_ccw_req *) intparm;
929 if (cqr->status != DASD_CQR_IN_IO) { 932 if (cqr->status != DASD_CQR_IN_IO) {
930 MESSAGE(KERN_DEBUG, 933 MESSAGE(KERN_DEBUG,
@@ -976,17 +979,16 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
976 if (IS_ERR(irb)) { 979 if (IS_ERR(irb)) {
977 switch (PTR_ERR(irb)) { 980 switch (PTR_ERR(irb)) {
978 case -EIO: 981 case -EIO:
979 dasd_handle_killed_request(cdev, intparm);
980 break; 982 break;
981 case -ETIMEDOUT: 983 case -ETIMEDOUT:
982 printk(KERN_WARNING"%s(%s): request timed out\n", 984 printk(KERN_WARNING"%s(%s): request timed out\n",
983 __func__, cdev->dev.bus_id); 985 __func__, cdev->dev.bus_id);
984 //FIXME - dasd uses own timeout interface...
985 break; 986 break;
986 default: 987 default:
987 printk(KERN_WARNING"%s(%s): unknown error %ld\n", 988 printk(KERN_WARNING"%s(%s): unknown error %ld\n",
988 __func__, cdev->dev.bus_id, PTR_ERR(irb)); 989 __func__, cdev->dev.bus_id, PTR_ERR(irb));
989 } 990 }
991 dasd_handle_killed_request(cdev, intparm);
990 return; 992 return;
991 } 993 }
992 994
@@ -1150,11 +1152,15 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
1150 struct list_head *l, *n; 1152 struct list_head *l, *n;
1151 struct dasd_ccw_req *cqr; 1153 struct dasd_ccw_req *cqr;
1152 struct dasd_block *block; 1154 struct dasd_block *block;
1155 void (*callback)(struct dasd_ccw_req *, void *data);
1156 void *callback_data;
1153 1157
1154 list_for_each_safe(l, n, final_queue) { 1158 list_for_each_safe(l, n, final_queue) {
1155 cqr = list_entry(l, struct dasd_ccw_req, devlist); 1159 cqr = list_entry(l, struct dasd_ccw_req, devlist);
1156 list_del_init(&cqr->devlist); 1160 list_del_init(&cqr->devlist);
1157 block = cqr->block; 1161 block = cqr->block;
1162 callback = cqr->callback;
1163 callback_data = cqr->callback_data;
1158 if (block) 1164 if (block)
1159 spin_lock_bh(&block->queue_lock); 1165 spin_lock_bh(&block->queue_lock);
1160 switch (cqr->status) { 1166 switch (cqr->status) {
@@ -1175,7 +1181,7 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
1175 BUG(); 1181 BUG();
1176 } 1182 }
1177 if (cqr->callback != NULL) 1183 if (cqr->callback != NULL)
1178 (cqr->callback)(cqr, cqr->callback_data); 1184 (callback)(cqr, callback_data);
1179 if (block) 1185 if (block)
1180 spin_unlock_bh(&block->queue_lock); 1186 spin_unlock_bh(&block->queue_lock);
1181 } 1187 }
@@ -1405,17 +1411,15 @@ static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr)
1405 */ 1411 */
1406int dasd_sleep_on(struct dasd_ccw_req *cqr) 1412int dasd_sleep_on(struct dasd_ccw_req *cqr)
1407{ 1413{
1408 wait_queue_head_t wait_q;
1409 struct dasd_device *device; 1414 struct dasd_device *device;
1410 int rc; 1415 int rc;
1411 1416
1412 device = cqr->startdev; 1417 device = cqr->startdev;
1413 1418
1414 init_waitqueue_head (&wait_q);
1415 cqr->callback = dasd_wakeup_cb; 1419 cqr->callback = dasd_wakeup_cb;
1416 cqr->callback_data = (void *) &wait_q; 1420 cqr->callback_data = (void *) &generic_waitq;
1417 dasd_add_request_tail(cqr); 1421 dasd_add_request_tail(cqr);
1418 wait_event(wait_q, _wait_for_wakeup(cqr)); 1422 wait_event(generic_waitq, _wait_for_wakeup(cqr));
1419 1423
1420 /* Request status is either done or failed. */ 1424 /* Request status is either done or failed. */
1421 rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; 1425 rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO;
@@ -1428,20 +1432,18 @@ int dasd_sleep_on(struct dasd_ccw_req *cqr)
1428 */ 1432 */
1429int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr) 1433int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr)
1430{ 1434{
1431 wait_queue_head_t wait_q;
1432 struct dasd_device *device; 1435 struct dasd_device *device;
1433 int rc; 1436 int rc;
1434 1437
1435 device = cqr->startdev; 1438 device = cqr->startdev;
1436 init_waitqueue_head (&wait_q);
1437 cqr->callback = dasd_wakeup_cb; 1439 cqr->callback = dasd_wakeup_cb;
1438 cqr->callback_data = (void *) &wait_q; 1440 cqr->callback_data = (void *) &generic_waitq;
1439 dasd_add_request_tail(cqr); 1441 dasd_add_request_tail(cqr);
1440 rc = wait_event_interruptible(wait_q, _wait_for_wakeup(cqr)); 1442 rc = wait_event_interruptible(generic_waitq, _wait_for_wakeup(cqr));
1441 if (rc == -ERESTARTSYS) { 1443 if (rc == -ERESTARTSYS) {
1442 dasd_cancel_req(cqr); 1444 dasd_cancel_req(cqr);
1443 /* wait (non-interruptible) for final status */ 1445 /* wait (non-interruptible) for final status */
1444 wait_event(wait_q, _wait_for_wakeup(cqr)); 1446 wait_event(generic_waitq, _wait_for_wakeup(cqr));
1445 } 1447 }
1446 rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; 1448 rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO;
1447 return rc; 1449 return rc;
@@ -1465,7 +1467,6 @@ static inline int _dasd_term_running_cqr(struct dasd_device *device)
1465 1467
1466int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr) 1468int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
1467{ 1469{
1468 wait_queue_head_t wait_q;
1469 struct dasd_device *device; 1470 struct dasd_device *device;
1470 int rc; 1471 int rc;
1471 1472
@@ -1477,9 +1478,8 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
1477 return rc; 1478 return rc;
1478 } 1479 }
1479 1480
1480 init_waitqueue_head (&wait_q);
1481 cqr->callback = dasd_wakeup_cb; 1481 cqr->callback = dasd_wakeup_cb;
1482 cqr->callback_data = (void *) &wait_q; 1482 cqr->callback_data = (void *) &generic_waitq;
1483 cqr->status = DASD_CQR_QUEUED; 1483 cqr->status = DASD_CQR_QUEUED;
1484 list_add(&cqr->devlist, &device->ccw_queue); 1484 list_add(&cqr->devlist, &device->ccw_queue);
1485 1485
@@ -1488,7 +1488,7 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
1488 1488
1489 spin_unlock_irq(get_ccwdev_lock(device->cdev)); 1489 spin_unlock_irq(get_ccwdev_lock(device->cdev));
1490 1490
1491 wait_event(wait_q, _wait_for_wakeup(cqr)); 1491 wait_event(generic_waitq, _wait_for_wakeup(cqr));
1492 1492
1493 /* Request status is either done or failed. */ 1493 /* Request status is either done or failed. */
1494 rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; 1494 rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO;
@@ -2429,6 +2429,7 @@ static int __init dasd_init(void)
2429 2429
2430 init_waitqueue_head(&dasd_init_waitq); 2430 init_waitqueue_head(&dasd_init_waitq);
2431 init_waitqueue_head(&dasd_flush_wq); 2431 init_waitqueue_head(&dasd_flush_wq);
2432 init_waitqueue_head(&generic_waitq);
2432 2433
2433 /* register 'common' DASD debug area, used for all DBF_XXX calls */ 2434 /* register 'common' DASD debug area, used for all DBF_XXX calls */
2434 dasd_debug_area = debug_register("dasd", 1, 1, 8 * sizeof(long)); 2435 dasd_debug_area = debug_register("dasd", 1, 1, 8 * sizeof(long));