From: Heiko Carstens From: Peter Oberparleiter dasd driver changes: - Modify format analysis routine to use block size provided by on-disk label. - Search data structures when referencing use_diag/ro attribute values. - Correct return code checking when allocating memory. Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton --- 25-akpm/drivers/s390/block/dasd_devmap.c | 23 +++++++++++++++-------- 25-akpm/drivers/s390/block/dasd_diag.c | 16 +++++++++++----- 25-akpm/drivers/s390/block/dasd_eckd.c | 26 +++++++++++++------------- 25-akpm/drivers/s390/block/dasd_proc.c | 10 ++++++---- 4 files changed, 45 insertions(+), 30 deletions(-) diff -puN drivers/s390/block/dasd_devmap.c~s390-dasd-driver drivers/s390/block/dasd_devmap.c --- 25/drivers/s390/block/dasd_devmap.c~s390-dasd-driver 2004-12-28 00:39:19.490878528 -0800 +++ 25-akpm/drivers/s390/block/dasd_devmap.c 2004-12-28 00:39:19.499877160 -0800 @@ -11,7 +11,7 @@ * functions may not be called from interrupt context. In particular * dasd_get_device is a no-no from interrupt context. * - * $Revision: 1.34 $ + * $Revision: 1.35 $ */ #include @@ -553,6 +553,8 @@ dasd_delete_device(struct dasd_device *d /* First remove device pointer from devmap. */ devmap = dasd_find_busid(device->cdev->dev.bus_id); + if (IS_ERR(devmap)) + BUG(); spin_lock(&dasd_devmap_lock); if (devmap->device != device) { spin_unlock(&dasd_devmap_lock); @@ -626,8 +628,8 @@ dasd_ro_show(struct device *dev, char *b struct dasd_devmap *devmap; int ro_flag; - devmap = dev->driver_data; - if (devmap) + devmap = dasd_find_busid(dev->bus_id); + if (!IS_ERR(devmap)) ro_flag = (devmap->features & DASD_FEATURE_READONLY) != 0; else ro_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_READONLY) != 0; @@ -641,6 +643,8 @@ dasd_ro_store(struct device *dev, const int ro_flag; devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); + if (IS_ERR(devmap)) + return PTR_ERR(devmap); ro_flag = buf[0] == '1'; spin_lock(&dasd_devmap_lock); if (ro_flag) @@ -665,15 +669,14 @@ static DEVICE_ATTR(readonly, 0644, dasd_ * use_diag controls whether the driver should use diag rather than ssch * to talk to the device */ -/* TODO: Implement */ static ssize_t dasd_use_diag_show(struct device *dev, char *buf) { struct dasd_devmap *devmap; int use_diag; - devmap = dev->driver_data; - if (devmap) + devmap = dasd_find_busid(dev->bus_id); + if (!IS_ERR(devmap)) use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0; else use_diag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USEDIAG) != 0; @@ -684,21 +687,25 @@ static ssize_t dasd_use_diag_store(struct device *dev, const char *buf, size_t count) { struct dasd_devmap *devmap; + ssize_t rc; int use_diag; devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); + if (IS_ERR(devmap)) + return PTR_ERR(devmap); use_diag = buf[0] == '1'; spin_lock(&dasd_devmap_lock); /* Changing diag discipline flag is only allowed in offline state. */ + rc = count; if (!devmap->device) { if (use_diag) devmap->features |= DASD_FEATURE_USEDIAG; else devmap->features &= ~DASD_FEATURE_USEDIAG; } else - count = -EPERM; + rc = -EPERM; spin_unlock(&dasd_devmap_lock); - return count; + return rc; } static diff -puN drivers/s390/block/dasd_diag.c~s390-dasd-driver drivers/s390/block/dasd_diag.c --- 25/drivers/s390/block/dasd_diag.c~s390-dasd-driver 2004-12-28 00:39:19.491878376 -0800 +++ 25-akpm/drivers/s390/block/dasd_diag.c 2004-12-28 00:39:19.500877008 -0800 @@ -6,7 +6,7 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * - * $Revision: 1.39 $ + * $Revision: 1.40 $ */ #include @@ -274,6 +274,7 @@ dasd_diag_check_device(struct dasd_devic "No memory to allocate initialization request"); return -ENOMEM; } + /* try all sizes - needed for ECKD devices */ for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) { mdsk_init_io(device, bsize, 0, 64); memset(&bio, 0, sizeof (struct dasd_diag_bio)); @@ -291,8 +292,9 @@ dasd_diag_check_device(struct dasd_devic break; mdsk_term_io(device); } - if (bsize <= PAGE_SIZE && label[3] == bsize && - label[0] == 0xc3d4e2f1) { + if (bsize <= PAGE_SIZE && label[0] == 0xc3d4e2f1) { + /* get formatted blocksize from label block */ + bsize = (int) label[3]; device->blocks = label[7]; device->bp_block = bsize; device->s2b_shift = 0; /* bits to shift 512 to get a block */ @@ -305,8 +307,12 @@ dasd_diag_check_device(struct dasd_devic (device->blocks << device->s2b_shift) >> 1); rc = 0; } else { - DEV_MESSAGE(KERN_WARNING, device, "%s", - "volume has incompatible disk layout"); + if (bsize > PAGE_SIZE) + DEV_MESSAGE(KERN_WARNING, device, "%s", + "DIAG access failed"); + else + DEV_MESSAGE(KERN_WARNING, device, "%s", + "volume is not CMS formatted"); rc = -EMEDIUMTYPE; } free_page((long) label); diff -puN drivers/s390/block/dasd_eckd.c~s390-dasd-driver drivers/s390/block/dasd_eckd.c --- 25/drivers/s390/block/dasd_eckd.c~s390-dasd-driver 2004-12-28 00:39:19.493878072 -0800 +++ 25-akpm/drivers/s390/block/dasd_eckd.c 2004-12-28 00:39:19.501876856 -0800 @@ -7,7 +7,7 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * - * $Revision: 1.65 $ + * $Revision: 1.66 $ */ #include @@ -1192,10 +1192,10 @@ dasd_eckd_release(struct block_device *b cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1, 32, device); - if (cqr == NULL) { + if (IS_ERR(cqr)) { MESSAGE(KERN_WARNING, "%s", - "No memory to allocate initialization request"); - return -ENOMEM; + "Could not allocate initialization request"); + return PTR_ERR(cqr); } cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE; cqr->cpaddr->flags |= CCW_FLAG_SLI; @@ -1236,10 +1236,10 @@ dasd_eckd_reserve(struct block_device *b cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1, 32, device); - if (cqr == NULL) { + if (IS_ERR(cqr)) { MESSAGE(KERN_WARNING, "%s", - "No memory to allocate initialization request"); - return -ENOMEM; + "Could not allocate initialization request"); + return PTR_ERR(cqr); } cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE; cqr->cpaddr->flags |= CCW_FLAG_SLI; @@ -1279,10 +1279,10 @@ dasd_eckd_steal_lock(struct block_device cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1, 32, device); - if (cqr == NULL) { + if (IS_ERR(cqr)) { MESSAGE(KERN_WARNING, "%s", - "No memory to allocate initialization request"); - return -ENOMEM; + "Could not allocate initialization request"); + return PTR_ERR(cqr); } cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK; cqr->cpaddr->flags |= CCW_FLAG_SLI; @@ -1323,10 +1323,10 @@ dasd_eckd_performance(struct block_devic (sizeof (struct dasd_psf_prssd_data) + sizeof (struct dasd_rssd_perf_stats_t)), device); - if (cqr == NULL) { + if (IS_ERR(cqr)) { MESSAGE(KERN_WARNING, "%s", - "No memory to allocate initialization request"); - return -ENOMEM; + "Could not allocate initialization request"); + return PTR_ERR(cqr); } cqr->device = device; cqr->retries = 0; diff -puN drivers/s390/block/dasd_proc.c~s390-dasd-driver drivers/s390/block/dasd_proc.c --- 25/drivers/s390/block/dasd_proc.c~s390-dasd-driver 2004-12-28 00:39:19.494877920 -0800 +++ 25-akpm/drivers/s390/block/dasd_proc.c 2004-12-28 00:39:19.502876704 -0800 @@ -9,7 +9,7 @@ * * /proc interface for the dasd driver. * - * $Revision: 1.27 $ + * $Revision: 1.29 $ */ #include @@ -248,6 +248,8 @@ dasd_statistics_write(struct file *file, if (user_len > 65536) user_len = 65536; buffer = dasd_get_user_string(user_buf, user_len); + if (IS_ERR(buffer)) + return PTR_ERR(buffer); MESSAGE(KERN_INFO, "/proc/dasd/statictics: '%s'", buffer); /* check for valid verbs */ @@ -258,20 +260,20 @@ dasd_statistics_write(struct file *file, if (strcmp(str, "on") == 0) { /* switch on statistics profiling */ dasd_profile_level = DASD_PROFILE_ON; - MESSAGE(KERN_INFO, "%s", "Statictics switched on"); + MESSAGE(KERN_INFO, "%s", "Statistics switched on"); } else if (strcmp(str, "off") == 0) { /* switch off and reset statistics profiling */ memset(&dasd_global_profile, 0, sizeof (struct dasd_profile_info_t)); dasd_profile_level = DASD_PROFILE_OFF; - MESSAGE(KERN_INFO, "%s", "Statictics switched off"); + MESSAGE(KERN_INFO, "%s", "Statistics switched off"); } else goto out_error; } else if (strncmp(str, "reset", 5) == 0) { /* reset the statistics */ memset(&dasd_global_profile, 0, sizeof (struct dasd_profile_info_t)); - MESSAGE(KERN_INFO, "%s", "Statictics reset"); + MESSAGE(KERN_INFO, "%s", "Statistics reset"); } else goto out_error; kfree(buffer); _