diff options
Diffstat (limited to 'drivers/s390/block/dasd.c')
-rw-r--r-- | drivers/s390/block/dasd.c | 33 |
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 | */ |
64 | static wait_queue_head_t dasd_init_waitq; | 64 | static wait_queue_head_t dasd_init_waitq; |
65 | static wait_queue_head_t dasd_flush_wq; | 65 | static wait_queue_head_t dasd_flush_wq; |
66 | static 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 | */ |
1406 | int dasd_sleep_on(struct dasd_ccw_req *cqr) | 1412 | int 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 | */ |
1429 | int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr) | 1433 | int 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 | ||
1466 | int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr) | 1468 | int 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)); |