
From: Heiko Carstens <heiko.carstens@de.ibm.com>

From: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>

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 <heiko.carstens@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 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 <linux/config.h>
@@ -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..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.39 $
+ * $Revision: 1.40 $
  */
 
 #include <linux/config.h>
@@ -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..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.65 $
+ * $Revision: 1.66 $
  */
 
 #include <linux/config.h>
@@ -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 <linux/config.h>
@@ -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);
_
