diff options
Diffstat (limited to 'drivers/s390/block')
-rw-r--r-- | drivers/s390/block/dasd.c | 39 | ||||
-rw-r--r-- | drivers/s390/block/dasd_devmap.c | 1 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 2 | ||||
-rw-r--r-- | drivers/s390/block/dasd_erp.c | 4 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 1 |
5 files changed, 34 insertions, 13 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index fb1b56a71475..1de089019268 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -212,16 +212,6 @@ static int dasd_state_known_to_new(struct dasd_device *device) { /* Disable extended error reporting for this device. */ dasd_eer_disable(device); - /* Forget the discipline information. */ - if (device->discipline) { - if (device->discipline->uncheck_device) - device->discipline->uncheck_device(device); - module_put(device->discipline->owner); - } - device->discipline = NULL; - if (device->base_discipline) - module_put(device->base_discipline->owner); - device->base_discipline = NULL; device->state = DASD_STATE_NEW; if (device->block) @@ -336,6 +326,7 @@ static int dasd_state_basic_to_ready(struct dasd_device *device) { int rc; struct dasd_block *block; + struct gendisk *disk; rc = 0; block = device->block; @@ -346,6 +337,9 @@ static int dasd_state_basic_to_ready(struct dasd_device *device) if (rc) { if (rc != -EAGAIN) { device->state = DASD_STATE_UNFMT; + disk = device->block->gdp; + kobject_uevent(&disk_to_dev(disk)->kobj, + KOBJ_CHANGE); goto out; } return rc; @@ -2274,6 +2268,15 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible) continue; } /* + * Don't try to start requests if device is in + * offline processing, it might wait forever + */ + if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) { + cqr->status = DASD_CQR_FAILED; + cqr->intrc = -ENODEV; + continue; + } + /* * Don't try to start requests if device is stopped * except path verification requests */ @@ -3364,6 +3367,22 @@ int dasd_generic_probe(struct ccw_device *cdev, } EXPORT_SYMBOL_GPL(dasd_generic_probe); +void dasd_generic_free_discipline(struct dasd_device *device) +{ + /* Forget the discipline information. */ + if (device->discipline) { + if (device->discipline->uncheck_device) + device->discipline->uncheck_device(device); + module_put(device->discipline->owner); + device->discipline = NULL; + } + if (device->base_discipline) { + module_put(device->base_discipline->owner); + device->base_discipline = NULL; + } +} +EXPORT_SYMBOL_GPL(dasd_generic_free_discipline); + /* * This will one day be called from a global not_oper handler. * It is also used by driver_unregister during module unload. diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 3cdbce45e464..15a1a70cace9 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -617,6 +617,7 @@ dasd_delete_device(struct dasd_device *device) /* Wait for reference counter to drop to zero. */ wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0); + dasd_generic_free_discipline(device); /* Disconnect dasd_device structure from ccw_device structure. */ cdev = device->cdev; device->cdev = NULL; diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 98bbec44bcd0..831935af7389 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -5201,7 +5201,7 @@ static int dasd_eckd_query_host_access(struct dasd_device *device, cqr->buildclk = get_tod_clock(); cqr->status = DASD_CQR_FILLED; - rc = dasd_sleep_on(cqr); + rc = dasd_sleep_on_interruptible(cqr); if (rc == 0) { *data = *host_access; } else { diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c index e1e88486b2b4..d138d0116734 100644 --- a/drivers/s390/block/dasd_erp.c +++ b/drivers/s390/block/dasd_erp.c @@ -169,12 +169,12 @@ dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb) device = cqr->startdev; if (cqr->intrc == -ETIMEDOUT) { dev_err(&device->cdev->dev, - "A timeout error occurred for cqr %p", cqr); + "A timeout error occurred for cqr %p\n", cqr); return; } if (cqr->intrc == -ENOLINK) { dev_err(&device->cdev->dev, - "A transport error occurred for cqr %p", cqr); + "A transport error occurred for cqr %p\n", cqr); return; } /* dump sense data */ diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index ac7027e6d52b..87ff6cef872f 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -725,6 +725,7 @@ void dasd_block_clear_timer(struct dasd_block *); int dasd_cancel_req(struct dasd_ccw_req *); int dasd_flush_device_queue(struct dasd_device *); int dasd_generic_probe (struct ccw_device *, struct dasd_discipline *); +void dasd_generic_free_discipline(struct dasd_device *); void dasd_generic_remove (struct ccw_device *cdev); int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); int dasd_generic_set_offline (struct ccw_device *cdev); |