summaryrefslogtreecommitdiffstats
path: root/drivers/s390/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/block')
-rw-r--r--drivers/s390/block/dasd.c34
-rw-r--r--drivers/s390/block/dasd_diag.c1
-rw-r--r--drivers/s390/block/dasd_eckd.c44
-rw-r--r--drivers/s390/block/dasd_fba.c22
-rw-r--r--drivers/s390/block/dasd_int.h3
-rw-r--r--drivers/s390/block/dcssblk.c4
6 files changed, 73 insertions, 35 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 27a1be0cd4d4..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)
/* Check the cqr */
rc = dasd_check_cqr(cqr);
- if (rc)
+ if (rc) {
+ cqr->intrc = rc;
return rc;
+ }
device = (struct dasd_device *) cqr->startdev;
if (cqr->retries < 0) {
/* internal error 14 - start_IO run out of retries */
@@ -915,6 +917,7 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
BUG();
break;
}
+ cqr->intrc = rc;
return rc;
}
@@ -1454,8 +1457,12 @@ int dasd_sleep_on(struct dasd_ccw_req *cqr)
dasd_add_request_tail(cqr);
wait_event(generic_waitq, _wait_for_wakeup(cqr));
- /* Request status is either done or failed. */
- rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO;
+ if (cqr->status == DASD_CQR_DONE)
+ rc = 0;
+ else if (cqr->intrc)
+ rc = cqr->intrc;
+ else
+ rc = -EIO;
return rc;
}
@@ -1477,8 +1484,15 @@ int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr)
dasd_cancel_req(cqr);
/* wait (non-interruptible) for final status */
wait_event(generic_waitq, _wait_for_wakeup(cqr));
+ cqr->intrc = rc;
}
- rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO;
+
+ if (cqr->status == DASD_CQR_DONE)
+ rc = 0;
+ else if (cqr->intrc)
+ rc = cqr->intrc;
+ else
+ rc = -EIO;
return rc;
}
@@ -1523,8 +1537,12 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
wait_event(generic_waitq, _wait_for_wakeup(cqr));
- /* Request status is either done or failed. */
- rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO;
+ if (cqr->status == DASD_CQR_DONE)
+ rc = 0;
+ else if (cqr->intrc)
+ rc = cqr->intrc;
+ else
+ rc = -EIO;
return rc;
}
@@ -2427,12 +2445,12 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic,
- void **rdc_buffer, int rdc_buffer_size)
+ void *rdc_buffer, int rdc_buffer_size)
{
int ret;
struct dasd_ccw_req *cqr;
- cqr = dasd_generic_build_rdc(device, *rdc_buffer, rdc_buffer_size,
+ cqr = dasd_generic_build_rdc(device, rdc_buffer, rdc_buffer_size,
magic);
if (IS_ERR(cqr))
return PTR_ERR(cqr);
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)
rc = -EIO;
break;
}
+ cqr->intrc = rc;
return rc;
}
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index a41c94053e64..cf0cfdba1244 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1097,20 +1097,20 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
{
struct dasd_eckd_private *private;
struct dasd_block *block;
- void *rdc_data;
int is_known, rc;
private = (struct dasd_eckd_private *) device->private;
- if (private == NULL) {
- private = kzalloc(sizeof(struct dasd_eckd_private),
- GFP_KERNEL | GFP_DMA);
- if (private == NULL) {
+ if (!private) {
+ private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
+ if (!private) {
dev_warn(&device->cdev->dev,
"Allocating memory for private DASD data "
"failed\n");
return -ENOMEM;
}
device->private = (void *) private;
+ } else {
+ memset(private, 0, sizeof(*private));
}
/* Invalidate status of initial analysis. */
private->init_cqr_status = -1;
@@ -1161,9 +1161,8 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
goto out_err3;
/* Read Device Characteristics */
- rdc_data = (void *) &(private->rdc_data);
- memset(rdc_data, 0, sizeof(rdc_data));
- rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64);
+ rc = dasd_generic_read_dev_chars(device, "ECKD", &private->rdc_data,
+ 64);
if (rc) {
DBF_EVENT(DBF_WARNING,
"Read device characteristics failed, rc=%d for "
@@ -1183,7 +1182,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
private->rdc_data.dev_model,
private->rdc_data.cu_type,
private->rdc_data.cu_model.model,
- private->real_cyl,
+ private->real_cyl,
private->rdc_data.trk_per_cyl,
private->rdc_data.sec_per_trk);
return 0;
@@ -2336,9 +2335,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
{
int tpm, cmdrtd, cmdwtd;
int use_prefix;
-
- struct dasd_eckd_private *private;
+#if defined(CONFIG_64BIT)
int fcx_in_css, fcx_in_gneq, fcx_in_features;
+#endif
+ struct dasd_eckd_private *private;
struct dasd_device *basedev;
sector_t first_rec, last_rec;
sector_t first_trk, last_trk;
@@ -2361,11 +2361,15 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
last_offs = sector_div(last_trk, blk_per_trk);
cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
- /* is transport mode supported ? */
+ /* is transport mode supported? */
+#if defined(CONFIG_64BIT)
fcx_in_css = css_general_characteristics.fcx;
fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
fcx_in_features = private->features.feature[40] & 0x80;
tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
+#else
+ tpm = 0;
+#endif
/* is read track data and write track data in command mode supported? */
cmdrtd = private->features.feature[9] & 0x20;
@@ -3013,8 +3017,9 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
" I/O status report for device %s:\n",
dev_name(&device->cdev->dev));
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
- " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
- scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw));
+ " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d\n",
+ req, scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
+ scsw_cc(&irb->scsw), req->intrc);
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" device %s: Failing CCW: %p\n",
dev_name(&device->cdev->dev),
@@ -3115,9 +3120,10 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
" I/O status report for device %s:\n",
dev_name(&device->cdev->dev));
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
- " in req: %p CS: 0x%02X DS: 0x%02X "
+ " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d "
"fcxs: 0x%02X schxs: 0x%02X\n", req,
scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
+ scsw_cc(&irb->scsw), req->intrc,
irb->scsw.tm.fcxs, irb->scsw.tm.schxs);
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" device %s: Failing TCW: %p\n",
@@ -3273,8 +3279,14 @@ static struct dasd_discipline dasd_eckd_discipline = {
static int __init
dasd_eckd_init(void)
{
+ int ret;
+
ASCEBC(dasd_eckd_discipline.ebcname, 4);
- return ccw_driver_register(&dasd_eckd_driver);
+ ret = ccw_driver_register(&dasd_eckd_driver);
+ if (!ret)
+ wait_for_device_probe();
+
+ return ret;
}
static void __exit
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 8912358daa2f..597c6ffdb9f2 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -122,20 +122,20 @@ dasd_fba_check_characteristics(struct dasd_device *device)
struct dasd_block *block;
struct dasd_fba_private *private;
struct ccw_device *cdev = device->cdev;
- void *rdc_data;
int rc;
private = (struct dasd_fba_private *) device->private;
- if (private == NULL) {
- private = kzalloc(sizeof(struct dasd_fba_private),
- GFP_KERNEL | GFP_DMA);
- if (private == NULL) {
+ if (!private) {
+ private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
+ if (!private) {
dev_warn(&device->cdev->dev,
"Allocating memory for private DASD "
"data failed\n");
return -ENOMEM;
}
device->private = (void *) private;
+ } else {
+ memset(private, 0, sizeof(*private));
}
block = dasd_alloc_block();
if (IS_ERR(block)) {
@@ -150,8 +150,8 @@ dasd_fba_check_characteristics(struct dasd_device *device)
block->base = device;
/* Read Device Characteristics */
- rdc_data = (void *) &(private->rdc_data);
- rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32);
+ rc = dasd_generic_read_dev_chars(device, "FBA ", &private->rdc_data,
+ 32);
if (rc) {
DBF_EVENT(DBF_WARNING, "Read device characteristics returned "
"error %d for device: %s",
@@ -604,8 +604,14 @@ static struct dasd_discipline dasd_fba_discipline = {
static int __init
dasd_fba_init(void)
{
+ int ret;
+
ASCEBC(dasd_fba_discipline.ebcname, 4);
- return ccw_driver_register(&dasd_fba_driver);
+ ret = ccw_driver_register(&dasd_fba_driver);
+ if (!ret)
+ wait_for_device_probe();
+
+ return ret;
}
static void __exit
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index c1e487f774c6..f97ceb795078 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -173,6 +173,7 @@ struct dasd_ccw_req {
void *data; /* pointer to data area */
/* these are important for recovering erroneous requests */
+ int intrc; /* internal error, e.g. from start_IO */
struct irb irb; /* device status in case of an error */
struct dasd_ccw_req *refers; /* ERP-chain queueing. */
void *function; /* originating ERP action */
@@ -578,7 +579,7 @@ int dasd_generic_set_offline (struct ccw_device *cdev);
int dasd_generic_notify(struct ccw_device *, int);
void dasd_generic_handle_state_change(struct dasd_device *);
-int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int);
+int dasd_generic_read_dev_chars(struct dasd_device *, char *, void *, int);
char *dasd_get_sense(struct irb *);
/* externals in dasd_devmap.c */
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index a4c7ffcd9987..b21caf177e37 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -127,7 +127,7 @@ dcssblk_assign_free_minor(struct dcssblk_dev_info *dev_info)
found = 0;
// test if minor available
list_for_each_entry(entry, &dcssblk_devices, lh)
- if (minor == MINOR(disk_devt(entry->gd)))
+ if (minor == entry->gd->first_minor)
found++;
if (!found) break; // got unused minor
}
@@ -625,7 +625,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
if (rc)
goto release_gd;
sprintf(dev_info->gd->disk_name, "dcssblk%d",
- MINOR(disk_devt(dev_info->gd)));
+ dev_info->gd->first_minor);
list_add_tail(&dev_info->lh, &dcssblk_devices);
if (!try_module_get(THIS_MODULE)) {