diff options
Diffstat (limited to 'drivers/s390/block')
-rw-r--r-- | drivers/s390/block/dasd_diag.c | 50 |
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 @@ | |||
6 | * Bugreports.to..: <Linux390@de.ibm.com> | 6 | * Bugreports.to..: <Linux390@de.ibm.com> |
7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
8 | * | 8 | * |
9 | * $Revision: 1.50 $ | 9 | * $Revision: 1.51 $ |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
@@ -404,37 +404,47 @@ dasd_diag_check_device(struct dasd_device *device) | |||
404 | private->iob.bio_list = &bio; | 404 | private->iob.bio_list = &bio; |
405 | private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; | 405 | private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; |
406 | rc = dia250(&private->iob, RW_BIO); | 406 | rc = dia250(&private->iob, RW_BIO); |
407 | if (rc == 0 || rc == 3) | 407 | if (rc == 3) { |
408 | break; | 408 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
409 | "DIAG call failed"); | ||
410 | rc = -EOPNOTSUPP; | ||
411 | goto out; | ||
412 | } | ||
409 | mdsk_term_io(device); | 413 | mdsk_term_io(device); |
414 | if (rc == 0) | ||
415 | break; | ||
410 | } | 416 | } |
411 | if (rc == 3) { | 417 | if (bsize > PAGE_SIZE) { |
412 | DEV_MESSAGE(KERN_WARNING, device, "%s", "DIAG call failed"); | ||
413 | rc = -EOPNOTSUPP; | ||
414 | } else if (rc != 0) { | ||
415 | DEV_MESSAGE(KERN_WARNING, device, "device access failed " | 418 | DEV_MESSAGE(KERN_WARNING, device, "device access failed " |
416 | "(rc=%d)", rc); | 419 | "(rc=%d)", rc); |
417 | rc = -EIO; | 420 | rc = -EIO; |
421 | goto out; | ||
422 | } | ||
423 | /* check for label block */ | ||
424 | if (memcmp(label->label_id, DASD_DIAG_CMS1, | ||
425 | sizeof(DASD_DIAG_CMS1)) == 0) { | ||
426 | /* get formatted blocksize from label block */ | ||
427 | bsize = (unsigned int) label->block_size; | ||
428 | device->blocks = (unsigned long) label->block_count; | ||
429 | } else | ||
430 | device->blocks = end_block; | ||
431 | device->bp_block = bsize; | ||
432 | device->s2b_shift = 0; /* bits to shift 512 to get a block */ | ||
433 | for (sb = 512; sb < bsize; sb = sb << 1) | ||
434 | device->s2b_shift++; | ||
435 | rc = mdsk_init_io(device, device->bp_block, 0, NULL); | ||
436 | if (rc) { | ||
437 | DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization " | ||
438 | "failed (rc=%d)", rc); | ||
439 | rc = -EIO; | ||
418 | } else { | 440 | } else { |
419 | if (memcmp(label->label_id, DASD_DIAG_CMS1, | ||
420 | sizeof(DASD_DIAG_CMS1)) == 0) { | ||
421 | /* get formatted blocksize from label block */ | ||
422 | bsize = (unsigned int) label->block_size; | ||
423 | device->blocks = (unsigned long) label->block_count; | ||
424 | } else | ||
425 | device->blocks = end_block; | ||
426 | device->bp_block = bsize; | ||
427 | device->s2b_shift = 0; /* bits to shift 512 to get a block */ | ||
428 | for (sb = 512; sb < bsize; sb = sb << 1) | ||
429 | device->s2b_shift++; | ||
430 | |||
431 | DEV_MESSAGE(KERN_INFO, device, | 441 | DEV_MESSAGE(KERN_INFO, device, |
432 | "(%ld B/blk): %ldkB", | 442 | "(%ld B/blk): %ldkB", |
433 | (unsigned long) device->bp_block, | 443 | (unsigned long) device->bp_block, |
434 | (unsigned long) (device->blocks << | 444 | (unsigned long) (device->blocks << |
435 | device->s2b_shift) >> 1); | 445 | device->s2b_shift) >> 1); |
436 | rc = 0; | ||
437 | } | 446 | } |
447 | out: | ||
438 | free_page((long) label); | 448 | free_page((long) label); |
439 | return rc; | 449 | return rc; |
440 | } | 450 | } |