|
@@ -37,6 +37,9 @@
|
|
|
*/
|
|
|
#define DASD_CHANQ_MAX_SIZE 4
|
|
|
|
|
|
+#define DASD_SLEEPON_START_TAG (void *) 1
|
|
|
+#define DASD_SLEEPON_END_TAG (void *) 2
|
|
|
+
|
|
|
/*
|
|
|
* SECTION: exported variables of dasd.c
|
|
|
*/
|
|
@@ -1472,7 +1475,10 @@ void dasd_add_request_tail(struct dasd_ccw_req *cqr)
|
|
|
*/
|
|
|
static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data)
|
|
|
{
|
|
|
- wake_up((wait_queue_head_t *) data);
|
|
|
+ spin_lock_irq(get_ccwdev_lock(cqr->startdev->cdev));
|
|
|
+ cqr->callback_data = DASD_SLEEPON_END_TAG;
|
|
|
+ spin_unlock_irq(get_ccwdev_lock(cqr->startdev->cdev));
|
|
|
+ wake_up(&generic_waitq);
|
|
|
}
|
|
|
|
|
|
static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr)
|
|
@@ -1482,10 +1488,7 @@ static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr)
|
|
|
|
|
|
device = cqr->startdev;
|
|
|
spin_lock_irq(get_ccwdev_lock(device->cdev));
|
|
|
- rc = ((cqr->status == DASD_CQR_DONE ||
|
|
|
- cqr->status == DASD_CQR_NEED_ERP ||
|
|
|
- cqr->status == DASD_CQR_TERMINATED) &&
|
|
|
- list_empty(&cqr->devlist));
|
|
|
+ rc = (cqr->callback_data == DASD_SLEEPON_END_TAG);
|
|
|
spin_unlock_irq(get_ccwdev_lock(device->cdev));
|
|
|
return rc;
|
|
|
}
|
|
@@ -1573,7 +1576,7 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
|
|
|
wait_event(generic_waitq, !(device->stopped));
|
|
|
|
|
|
cqr->callback = dasd_wakeup_cb;
|
|
|
- cqr->callback_data = (void *) &generic_waitq;
|
|
|
+ cqr->callback_data = DASD_SLEEPON_START_TAG;
|
|
|
dasd_add_request_tail(cqr);
|
|
|
if (interruptible) {
|
|
|
rc = wait_event_interruptible(
|
|
@@ -1652,7 +1655,7 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
|
|
|
}
|
|
|
|
|
|
cqr->callback = dasd_wakeup_cb;
|
|
|
- cqr->callback_data = (void *) &generic_waitq;
|
|
|
+ cqr->callback_data = DASD_SLEEPON_START_TAG;
|
|
|
cqr->status = DASD_CQR_QUEUED;
|
|
|
list_add(&cqr->devlist, &device->ccw_queue);
|
|
|
|