From 24669f75a3231fa37444977c92d1f4838bec1233 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jes@sgi.com>
Date: Mon, 16 Jan 2006 10:31:18 -0500
Subject: [SCSI] SCSI core kmalloc2kzalloc

Change the core SCSI code to use kzalloc rather than kmalloc+memset
where possible.

Signed-off-by: Jes Sorensen <jes@sgi.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
---
 drivers/scsi/sd.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'drivers/scsi/sd.c')

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 9d9872347f56..8ba2d988d051 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1517,11 +1517,10 @@ static int sd_probe(struct device *dev)
 					"sd_attach\n"));
 
 	error = -ENOMEM;
-	sdkp = kmalloc(sizeof(*sdkp), GFP_KERNEL);
+	sdkp = kzalloc(sizeof(*sdkp), GFP_KERNEL);
 	if (!sdkp)
 		goto out;
 
-	memset (sdkp, 0, sizeof(*sdkp));
 	kref_init(&sdkp->kref);
 
 	gd = alloc_disk(16);
-- 
cgit v1.2.3


From 5e3c34c1e988a0dfe177c38cf324e8e321c55ef5 Mon Sep 17 00:00:00 2001
From: Greg KH <gregkh@suse.de>
Date: Wed, 18 Jan 2006 16:17:46 -0800
Subject: [SCSI] Remove devfs support from the SCSI subsystem

As devfs has been disabled from the kernel tree for a number of months
now (5 to be exact), here's a patch against 2.6.16-rc1-git1 that removes
support for it from the SCSI subsystem.

The patch also removes the scsi_disk devfs_name field as it's no longer
needed.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
---
 drivers/scsi/sd.c | 2 --
 1 file changed, 2 deletions(-)

(limited to 'drivers/scsi/sd.c')

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 8ba2d988d051..76b4d14c0b3f 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1571,8 +1571,6 @@ static int sd_probe(struct device *dev)
 			'a' + m1, 'a' + m2, 'a' + m3);
 	}
 
-	strcpy(gd->devfs_name, sdp->devfs_name);
-
 	gd->private_data = &sdkp->driver;
 	gd->queue = sdkp->device->request_queue;
 
-- 
cgit v1.2.3


From 6d73c8514da241c6b1b8d710a6294786604d7142 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@ftp.linux.org.uk>
Date: Thu, 23 Feb 2006 02:03:16 +0100
Subject: [SCSI] scsi_lib: fix recognition of cache type of Initio SBP-2
 bridges

Regardless what mode page was asked for, Initio INIC-14x0 and
INIC-2430 always return page 6 without mode page headers.  Try to
recognise this as a special case in scsi_mode_sense and setting the
mode sense headers accordingly.

Signed-off-by: Al Viro <viro@ftp.linux.org.uk>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
---
 drivers/scsi/sd.c | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'drivers/scsi/sd.c')

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 76b4d14c0b3f..31c9685ebc5a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1333,6 +1333,12 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
 	if (!scsi_status_is_good(res))
 		goto bad_sense;
 
+	if (!data.header_length) {
+		modepage = 6;
+		printk(KERN_ERR "%s: missing header in MODE_SENSE response\n",
+		       diskname);
+	}
+
 	/* that went OK, now ask for the proper length */
 	len = data.length;
 
-- 
cgit v1.2.3


From f018fa552c52642a6b9db2bda90477762e42163f Mon Sep 17 00:00:00 2001
From: Rene Herman <rene.herman@keyaccess.nl>
Date: Wed, 8 Mar 2006 00:14:20 -0800
Subject: [SCSI] MODULE_ALIAS_{BLOCK,CHAR}DEV_MAJOR for drivers/scsi

Add device-major aliases in drivers/scsi, allowing kmod autoload:

MODULE_ALIAS_CHARDEV_MAJOR(SCSI_CHANGER_MAJOR)
MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR)
MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR)
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_CDROM_MAJOR)
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISKN_MAJOR)

Signed-off-by: Andrew Morton <akpm@osdl.org>
Acked-by: Kai Makisara <kai.makisara@kolumbus.fi>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
---
 drivers/scsi/sd.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

(limited to 'drivers/scsi/sd.c')

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 31c9685ebc5a..3b01e5d6221c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -71,6 +71,27 @@
  */
 #define SD_MAJORS	16
 
+MODULE_AUTHOR("Eric Youngdale");
+MODULE_DESCRIPTION("SCSI disk (sd) driver");
+MODULE_LICENSE("GPL");
+
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK0_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK1_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK2_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK3_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK4_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK5_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK6_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK7_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK8_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK9_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK10_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK11_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK12_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK13_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK14_MAJOR);
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR);
+
 /*
  * This is limited by the naming scheme enforced in sd_probe,
  * add another character to it if you really need more disks.
@@ -1713,9 +1734,5 @@ static void __exit exit_sd(void)
 		unregister_blkdev(sd_major(i), "sd");
 }
 
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Eric Youngdale");
-MODULE_DESCRIPTION("SCSI disk (sd) driver");
-
 module_init(init_sd);
 module_exit(exit_sd);
-- 
cgit v1.2.3


From 6bdaa1f17dd32ec62345c7b57842f53e6278a2fa Mon Sep 17 00:00:00 2001
From: James Bottomley <James.Bottomley@steeleye.com>
Date: Sat, 18 Mar 2006 14:14:21 -0600
Subject: [SCSI] allow displaying and setting of cache type via sysfs

I think I promised to do this two years ago

This patch adds a scsi_disk class with the cache type and FUA
parameters, so user land application can easily obtain them without
having to parse dmesg.  It also allows setting the cache type (use with
care...)

This patch is a bit dangerous because I've replaced the disk kref with a
class device reference ...

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
---
 drivers/scsi/sd.c | 136 +++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 113 insertions(+), 23 deletions(-)

(limited to 'drivers/scsi/sd.c')

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 3b01e5d6221c..024ef86c5242 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -47,7 +47,6 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
-#include <linux/kref.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
@@ -115,12 +114,10 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR);
  */
 #define SD_BUF_SIZE		512
 
-static void scsi_disk_release(struct kref *kref);
-
 struct scsi_disk {
 	struct scsi_driver *driver;	/* always &sd_template */
 	struct scsi_device *device;
-	struct kref	kref;
+	struct class_device cdev;
 	struct gendisk	*disk;
 	unsigned int	openers;	/* protected by BKL for now, yuck */
 	sector_t	capacity;	/* size in 512-byte sectors */
@@ -131,6 +128,7 @@ struct scsi_disk {
 	unsigned	RCD : 1;	/* state of disk RCD bit, unused */
 	unsigned	DPOFUA : 1;	/* state of disk DPOFUA bit */
 };
+#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev)
 
 static DEFINE_IDR(sd_index_idr);
 static DEFINE_SPINLOCK(sd_index_lock);
@@ -152,6 +150,92 @@ static int sd_issue_flush(struct device *, sector_t *);
 static void sd_prepare_flush(request_queue_t *, struct request *);
 static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
 			     unsigned char *buffer);
+static void scsi_disk_release(struct class_device *cdev);
+
+static const char *sd_cache_types[] = {
+	"write through", "none", "write back",
+	"write back, no read (daft)"
+};
+
+static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf,
+				   size_t count)
+{
+	int i, ct = -1, rcd, wce, sp;
+	struct scsi_disk *sdkp = to_scsi_disk(cdev);
+	struct scsi_device *sdp = sdkp->device;
+	char buffer[64];
+	char *buffer_data;
+	struct scsi_mode_data data;
+	struct scsi_sense_hdr sshdr;
+	int len;
+
+	if (sdp->type != TYPE_DISK)
+		/* no cache control on RBC devices; theoretically they
+		 * can do it, but there's probably so many exceptions
+		 * it's not worth the risk */
+		return -EINVAL;
+
+	for (i = 0; i < sizeof(sd_cache_types)/sizeof(sd_cache_types[0]); i++) {
+		const int len = strlen(sd_cache_types[i]);
+		if (strncmp(sd_cache_types[i], buf, len) == 0 &&
+		    buf[len] == '\n') {
+			ct = i;
+			break;
+		}
+	}
+	if (ct < 0)
+		return -EINVAL;
+	rcd = ct & 0x01 ? 1 : 0;
+	wce = ct & 0x02 ? 1 : 0;
+	if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT,
+			    SD_MAX_RETRIES, &data, NULL))
+		return -EINVAL;
+	len = min(sizeof(buffer), data.length - data.header_length -
+		  data.block_descriptor_length);
+	buffer_data = buffer + data.header_length +
+		data.block_descriptor_length;
+	buffer_data[2] &= ~0x05;
+	buffer_data[2] |= wce << 2 | rcd;
+	sp = buffer_data[0] & 0x80 ? 1 : 0;
+
+	if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT,
+			     SD_MAX_RETRIES, &data, &sshdr)) {
+		if (scsi_sense_valid(&sshdr))
+			scsi_print_sense_hdr(sdkp->disk->disk_name, &sshdr);
+		return -EINVAL;
+	}
+	sd_revalidate_disk(sdkp->disk);
+	return count;
+}
+
+static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf)
+{
+	struct scsi_disk *sdkp = to_scsi_disk(cdev);
+	int ct = sdkp->RCD + 2*sdkp->WCE;
+
+	return snprintf(buf, 40, "%s\n", sd_cache_types[ct]);
+}
+
+static ssize_t sd_show_fua(struct class_device *cdev, char *buf)
+{
+	struct scsi_disk *sdkp = to_scsi_disk(cdev);
+
+	return snprintf(buf, 20, "%u\n", sdkp->DPOFUA);
+}
+
+static struct class_device_attribute sd_disk_attrs[] = {
+	__ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type,
+	       sd_store_cache_type),
+	__ATTR(FUA, S_IRUGO, sd_show_fua, NULL),
+	__ATTR_NULL,
+};
+
+static struct class sd_disk_class = {
+	.name		= "scsi_disk",
+	.owner		= THIS_MODULE,
+	.release	= scsi_disk_release,
+	.class_dev_attrs = sd_disk_attrs,
+};
 
 static struct scsi_driver sd_template = {
 	.owner			= THIS_MODULE,
@@ -195,8 +279,6 @@ static int sd_major(int major_idx)
 	}
 }
 
-#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,kref)
-
 static inline struct scsi_disk *scsi_disk(struct gendisk *disk)
 {
 	return container_of(disk->private_data, struct scsi_disk, driver);
@@ -209,7 +291,7 @@ static struct scsi_disk *__scsi_disk_get(struct gendisk *disk)
 	if (disk->private_data) {
 		sdkp = scsi_disk(disk);
 		if (scsi_device_get(sdkp->device) == 0)
-			kref_get(&sdkp->kref);
+			class_device_get(&sdkp->cdev);
 		else
 			sdkp = NULL;
 	}
@@ -243,7 +325,7 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
 	struct scsi_device *sdev = sdkp->device;
 
 	mutex_lock(&sd_ref_mutex);
-	kref_put(&sdkp->kref, scsi_disk_release);
+	class_device_put(&sdkp->cdev);
 	scsi_device_put(sdev);
 	mutex_unlock(&sd_ref_mutex);
 }
@@ -1381,10 +1463,6 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
 	res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr);
 
 	if (scsi_status_is_good(res)) {
-		const char *types[] = {
-			"write through", "none", "write back",
-			"write back, no read (daft)"
-		};
 		int ct = 0;
 		int offset = data.header_length + data.block_descriptor_length;
 
@@ -1417,7 +1495,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
 		ct =  sdkp->RCD + 2*sdkp->WCE;
 
 		printk(KERN_NOTICE "SCSI device %s: drive cache: %s%s\n",
-		       diskname, types[ct],
+		       diskname, sd_cache_types[ct],
 		       sdkp->DPOFUA ? " w/ FUA" : "");
 
 		return;
@@ -1548,8 +1626,6 @@ static int sd_probe(struct device *dev)
 	if (!sdkp)
 		goto out;
 
-	kref_init(&sdkp->kref);
-
 	gd = alloc_disk(16);
 	if (!gd)
 		goto out_free;
@@ -1566,7 +1642,16 @@ static int sd_probe(struct device *dev)
 	if (error)
 		goto out_put;
 
+	class_device_initialize(&sdkp->cdev);
+	sdkp->cdev.dev = &sdp->sdev_gendev;
+	sdkp->cdev.class = &sd_disk_class;
+	strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
+
+	if (class_device_add(&sdkp->cdev))
+		goto out_put;
+
 	get_device(&sdp->sdev_gendev);
+
 	sdkp->device = sdp;
 	sdkp->driver = &sd_template;
 	sdkp->disk = gd;
@@ -1616,11 +1701,11 @@ static int sd_probe(struct device *dev)
 
 	return 0;
 
-out_put:
+ out_put:
 	put_disk(gd);
-out_free:
+ out_free:
 	kfree(sdkp);
-out:
+ out:
 	return error;
 }
 
@@ -1639,12 +1724,13 @@ static int sd_remove(struct device *dev)
 {
 	struct scsi_disk *sdkp = dev_get_drvdata(dev);
 
+	class_device_del(&sdkp->cdev);
 	del_gendisk(sdkp->disk);
 	sd_shutdown(dev);
 
 	mutex_lock(&sd_ref_mutex);
 	dev_set_drvdata(dev, NULL);
-	kref_put(&sdkp->kref, scsi_disk_release);
+	class_device_put(&sdkp->cdev);
 	mutex_unlock(&sd_ref_mutex);
 
 	return 0;
@@ -1652,16 +1738,16 @@ static int sd_remove(struct device *dev)
 
 /**
  *	scsi_disk_release - Called to free the scsi_disk structure
- *	@kref: pointer to embedded kref
+ *	@cdev: pointer to embedded class device
  *
  *	sd_ref_mutex must be held entering this routine.  Because it is
  *	called on last put, you should always use the scsi_disk_get()
  *	scsi_disk_put() helpers which manipulate the semaphore directly
- *	and never do a direct kref_put().
+ *	and never do a direct class_device_put().
  **/
-static void scsi_disk_release(struct kref *kref)
+static void scsi_disk_release(struct class_device *cdev)
 {
-	struct scsi_disk *sdkp = to_scsi_disk(kref);
+	struct scsi_disk *sdkp = to_scsi_disk(cdev);
 	struct gendisk *disk = sdkp->disk;
 	
 	spin_lock(&sd_index_lock);
@@ -1715,6 +1801,8 @@ static int __init init_sd(void)
 	if (!majors)
 		return -ENODEV;
 
+	class_register(&sd_disk_class);
+
 	return scsi_register_driver(&sd_template.gendrv);
 }
 
@@ -1732,6 +1820,8 @@ static void __exit exit_sd(void)
 	scsi_unregister_driver(&sd_template.gendrv);
 	for (i = 0; i < SD_MAJORS; i++)
 		unregister_blkdev(sd_major(i), "sd");
+
+	class_unregister(&sd_disk_class);
 }
 
 module_init(init_sd);
-- 
cgit v1.2.3


From a9312fb839e90668d05a90024f3a7e7ff646a4a3 Mon Sep 17 00:00:00 2001
From: Andrew Morton <akpm@osdl.org>
Date: Sat, 25 Mar 2006 03:08:30 -0800
Subject: [PATCH] git-scsi-misc: min() warning fix

drivers/scsi/sd.c: In function `sd_store_cache_type':
drivers/scsi/sd.c:193: warning: comparison of distinct pointer types lacks a cast

Cc: James Bottomley <James.Bottomley@steeleye.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
 drivers/scsi/sd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/scsi/sd.c')

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 024ef86c5242..c647d85d97d1 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -190,7 +190,7 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf,
 	if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT,
 			    SD_MAX_RETRIES, &data, NULL))
 		return -EINVAL;
-	len = min(sizeof(buffer), data.length - data.header_length -
+	len = min_t(size_t, sizeof(buffer), data.length - data.header_length -
 		  data.block_descriptor_length);
 	buffer_data = buffer + data.header_length +
 		data.block_descriptor_length;
-- 
cgit v1.2.3