aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>2005-11-07 00:59:08 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 07:53:34 -0800
commit1e0291bade7678efe4d3ab70ed14bd7bd216bcef (patch)
tree5f8a47c016e2f84fcb22c106666c680e7b19173c
parent[PATCH] s390: dasd diag inline assembly (diff)
downloadlinux-dev-1e0291bade7678efe4d3ab70ed14bd7bd216bcef.tar.xz
linux-dev-1e0291bade7678efe4d3ab70ed14bd7bd216bcef.zip
[PATCH] s390: dasd diag with block sizes > 512
Access to FBA disks via DIAG fails for block sizes > 512 byte. The device analysis code of the DIAG discipline does not properly initialize the DIAG250 device environment after completion of the analysis. This results in VM only serving 512 bytes per block I/O request whereas Linux expects larger block sizes. Add proper device environment setup to end of analysis code. Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/s390/block/dasd_diag.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 9aa608f528eb..ab8754e566bc 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -6,7 +6,7 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
*
- * $Revision: 1.50 $
+ * $Revision: 1.51 $
*/
#include <linux/config.h>
@@ -404,37 +404,47 @@ dasd_diag_check_device(struct dasd_device *device)
private->iob.bio_list = &bio;
private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
rc = dia250(&private->iob, RW_BIO);
- if (rc == 0 || rc == 3)
- break;
+ if (rc == 3) {
+ DEV_MESSAGE(KERN_WARNING, device, "%s",
+ "DIAG call failed");
+ rc = -EOPNOTSUPP;
+ goto out;
+ }
mdsk_term_io(device);
+ if (rc == 0)
+ break;
}
- if (rc == 3) {
- DEV_MESSAGE(KERN_WARNING, device, "%s", "DIAG call failed");
- rc = -EOPNOTSUPP;
- } else if (rc != 0) {
+ if (bsize > PAGE_SIZE) {
DEV_MESSAGE(KERN_WARNING, device, "device access failed "
"(rc=%d)", rc);
rc = -EIO;
+ goto out;
+ }
+ /* check for label block */
+ if (memcmp(label->label_id, DASD_DIAG_CMS1,
+ sizeof(DASD_DIAG_CMS1)) == 0) {
+ /* get formatted blocksize from label block */
+ bsize = (unsigned int) label->block_size;
+ device->blocks = (unsigned long) label->block_count;
+ } else
+ device->blocks = end_block;
+ device->bp_block = bsize;
+ device->s2b_shift = 0; /* bits to shift 512 to get a block */
+ for (sb = 512; sb < bsize; sb = sb << 1)
+ device->s2b_shift++;
+ rc = mdsk_init_io(device, device->bp_block, 0, NULL);
+ if (rc) {
+ DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization "
+ "failed (rc=%d)", rc);
+ rc = -EIO;
} else {
- if (memcmp(label->label_id, DASD_DIAG_CMS1,
- sizeof(DASD_DIAG_CMS1)) == 0) {
- /* get formatted blocksize from label block */
- bsize = (unsigned int) label->block_size;
- device->blocks = (unsigned long) label->block_count;
- } else
- device->blocks = end_block;
- device->bp_block = bsize;
- device->s2b_shift = 0; /* bits to shift 512 to get a block */
- for (sb = 512; sb < bsize; sb = sb << 1)
- device->s2b_shift++;
-
DEV_MESSAGE(KERN_INFO, device,
"(%ld B/blk): %ldkB",
(unsigned long) device->bp_block,
(unsigned long) (device->blocks <<
device->s2b_shift) >> 1);
- rc = 0;
}
+out:
free_page((long) label);
return rc;
}