public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] add scsi bus for virtual drivers take3
@ 2005-02-12  5:23 Mike Christie
  2005-02-14 18:02 ` Randy.Dunlap
  0 siblings, 1 reply; 2+ messages in thread
From: Mike Christie @ 2005-02-12  5:23 UTC (permalink / raw)
  To: linux-iscsi-devel, linux-scsi

[-- Attachment #1: Type: text/plain, Size: 99 bytes --]

I do not know what I was diffing the last time.
The attached patch should work now.

Sorry.

Mike


[-- Attachment #2: add-ml-virtual-bus3.patch --]
[-- Type: text/x-patch, Size: 16961 bytes --]

diff -aurp scsi-rc-fixes-2.6.orig/drivers/scsi/hosts.c scsi-rc-fixes-2.6.work/drivers/scsi/hosts.c
--- scsi-rc-fixes-2.6.orig/drivers/scsi/hosts.c	2005-02-04 22:10:09.000000000 -0800
+++ scsi-rc-fixes-2.6.work/drivers/scsi/hosts.c	2005-02-11 16:18:20.000000000 -0800
@@ -31,6 +31,7 @@
 #include <linux/transport_class.h>
 
 #include <scsi/scsi_device.h>
+#include <scsi/scsi_driver.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport.h>
 
@@ -39,6 +40,7 @@
 
 
 static int scsi_host_next_hn;		/* host_no for next new host */
+static int scsi_host_next_vhn;		/* host_no for next new virtual host */
 
 
 static void scsi_host_cls_release(struct class_device *class_dev)
@@ -51,6 +53,16 @@ static struct class shost_class = {
 	.release	= scsi_host_cls_release,
 };
 
+static int scsi_host_match(struct device *dev, struct device_driver *gendrv)
+{
+	return 1;
+}
+
+static struct bus_type shost_bus_type = {
+        .name		= "scsi_host",
+        .match		= scsi_host_match,
+};
+
 /**
  * scsi_host_cancel - cancel outstanding IO to this host
  * @shost:	pointer to struct Scsi_Host
@@ -379,12 +391,23 @@ EXPORT_SYMBOL(scsi_host_put);
 
 int scsi_init_hosts(void)
 {
-	return class_register(&shost_class);
+	int error;
+
+	error = class_register(&shost_class);
+	if (error)
+		return error;
+
+	error = bus_register(&shost_bus_type);
+	if (error)
+		class_unregister(&shost_class);
+
+	return 0;
 }
 
 void scsi_exit_hosts(void)
 {
 	class_unregister(&shost_class);
+	bus_unregister(&shost_bus_type);
 }
 
 int scsi_is_host_device(const struct device *dev)
@@ -392,3 +415,141 @@ int scsi_is_host_device(const struct dev
 	return dev->release == scsi_host_dev_release;
 }
 EXPORT_SYMBOL(scsi_is_host_device);
+
+static void __scsi_host_driver_remove_host(struct scsi_host_driver *sdrv,
+					   struct scsi_virt_host *vhost)
+{
+	spin_lock(&sdrv->devices_lock);
+	list_del(&vhost->list);
+	spin_unlock(&sdrv->devices_lock);
+	device_unregister(&vhost->dev);
+}
+
+static ssize_t scsi_host_driver_remove_host(struct device *dev,
+					    const char *buf, size_t count)
+{
+	struct scsi_host_driver *sdrv = to_scsi_host_driver(dev->driver);
+	struct scsi_virt_host *vhost = to_scsi_virt_host(dev);
+
+	__scsi_host_driver_remove_host(sdrv, vhost);
+	return count;
+}
+static DEVICE_ATTR(remove_host, S_IWUSR, NULL, scsi_host_driver_remove_host);
+
+static void scsi_virt_host_release(struct device *dev)
+{
+	struct scsi_virt_host *vhost;
+
+	vhost = to_scsi_virt_host(dev);
+	kfree(vhost);
+}
+
+static ssize_t scsi_host_driver_add_host(struct device_driver *drv,
+					 const char *buf, size_t count)
+{
+	struct scsi_host_driver *sdrv = to_scsi_host_driver(drv);
+	struct device *dev;
+	struct scsi_virt_host *vhost;
+	int error;
+
+	vhost = kmalloc(sizeof(*vhost), GFP_KERNEL);
+	if (!vhost)
+		return -ENOMEM;
+
+	memset(vhost, 0, sizeof(*vhost));
+	INIT_LIST_HEAD(&vhost->list);
+	spin_lock(&sdrv->devices_lock);
+	list_add_tail(&vhost->list, &sdrv->devices);
+	spin_unlock(&sdrv->devices_lock);
+
+	dev = &vhost->dev;
+	dev->bus = &shost_bus_type;
+	dev->release = scsi_virt_host_release;
+	snprintf(dev->bus_id, BUS_ID_SIZE, "virt_host%d",
+		 scsi_host_next_vhn++);
+	error = device_register(dev);
+	if (error) {
+		kfree(vhost);
+		return error;
+	}
+	/*
+	 * this is not a ciritical file, so we can fail and limp on
+	 */
+	dev_attr_remove_host.attr.owner = sdrv->owner;
+	device_create_file(dev, &dev_attr_remove_host);
+
+	return count;
+}
+static DRIVER_ATTR(add_host, S_IWUSR, NULL, scsi_host_driver_add_host);
+
+static int scsi_host_driver_probe(struct device *dev)
+{
+	struct scsi_host_driver *sdrv;
+
+	sdrv = to_scsi_host_driver(dev->driver);
+	if (!sdrv->probe)
+		return 0;
+	return sdrv->probe(to_scsi_virt_host(dev));
+}
+
+static int scsi_host_driver_remove(struct device *dev)
+{
+	struct scsi_host_driver *sdrv;
+
+	sdrv = to_scsi_host_driver(dev->driver);
+	if (!sdrv->remove)
+		return 0;
+	return sdrv->remove(to_scsi_virt_host(dev));
+}
+
+int scsi_register_host_driver(struct scsi_host_driver *sdrv)
+{
+	int error;
+
+	INIT_LIST_HEAD(&sdrv->devices);
+	spin_lock_init(&sdrv->devices_lock);
+
+	sdrv->gendrv.name = sdrv->name;
+	sdrv->gendrv.owner = sdrv->owner;
+	sdrv->gendrv.probe = scsi_host_driver_probe;
+	sdrv->gendrv.remove = scsi_host_driver_remove;
+	sdrv->gendrv.bus = &shost_bus_type;
+
+	error = driver_register(&sdrv->gendrv);
+	if (error)
+		return error;
+
+	driver_attr_add_host.attr.owner = sdrv->owner;
+	error = driver_create_file(&sdrv->gendrv, &driver_attr_add_host);
+	if (error)
+		goto unregister_drv;
+
+	error = sysfs_create_group(&sdrv->gendrv.kobj, sdrv->attrs);
+	if (error)
+		goto remove_add_file;
+
+	return 0;
+
+ remove_add_file:
+	driver_remove_file(&sdrv->gendrv, &driver_attr_add_host);
+ unregister_drv:
+	driver_unregister(&sdrv->gendrv);
+	return error;
+}
+EXPORT_SYMBOL(scsi_register_host_driver);
+
+void scsi_unregister_host_driver(struct scsi_host_driver *sdrv)
+{
+	struct scsi_virt_host *vhost, *tmp;
+
+	driver_remove_file(&sdrv->gendrv, &driver_attr_add_host);
+	sysfs_remove_group(&sdrv->gendrv.kobj, sdrv->attrs);
+	/*
+	 * this is only called from LLDs module_exit functions
+	 * so we should not need a lock.
+	 */
+	list_for_each_entry_safe(vhost, tmp, &sdrv->devices, list)
+		__scsi_host_driver_remove_host(sdrv, vhost);
+	driver_unregister(&sdrv->gendrv);
+}
+EXPORT_SYMBOL(scsi_unregister_host_driver);
diff -aurp scsi-rc-fixes-2.6.orig/drivers/scsi/osst.c scsi-rc-fixes-2.6.work/drivers/scsi/osst.c
--- scsi-rc-fixes-2.6.orig/drivers/scsi/osst.c	2005-02-04 22:10:56.000000000 -0800
+++ scsi-rc-fixes-2.6.work/drivers/scsi/osst.c	2005-02-11 20:51:09.000000000 -0800
@@ -170,7 +170,7 @@ static int osst_copy_from_buffer(struct 
 static int osst_probe(struct device *);
 static int osst_remove(struct device *);
 
-struct scsi_driver osst_template = {
+struct scsi_device_driver osst_template = {
 	.owner			= THIS_MODULE,
 	.gendrv = {
 		.name		=  "osst",
@@ -5850,7 +5850,7 @@ static int __init init_osst(void) 
 	validate_options();
 	osst_sysfs_init();
 
-	if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
+	if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_device_driver(&osst_template)) {
 		printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
 		osst_sysfs_cleanup();
 		return 1;
@@ -5866,7 +5866,7 @@ static void __exit exit_osst (void)
 	struct osst_tape * STp;
 
 	osst_remove_driverfs_files(&osst_template.gendrv);
-	scsi_unregister_driver(&osst_template.gendrv);
+	scsi_unregister_device_driver(&osst_template);
 	unregister_chrdev(OSST_MAJOR, "osst");
 	osst_sysfs_cleanup();
 
diff -aurp scsi-rc-fixes-2.6.orig/drivers/scsi/osst.h scsi-rc-fixes-2.6.work/drivers/scsi/osst.h
--- scsi-rc-fixes-2.6.orig/drivers/scsi/osst.h	2005-02-04 22:11:33.000000000 -0800
+++ scsi-rc-fixes-2.6.work/drivers/scsi/osst.h	2005-02-11 20:55:23.000000000 -0800
@@ -529,7 +529,7 @@ struct osst_buffer {
 
 /* The OnStream tape drive descriptor */
 struct osst_tape {
-  struct scsi_driver *driver;
+  struct scsi_device_driver *driver;
   unsigned capacity;
   struct scsi_device *device;
   struct semaphore lock;       /* for serialization */
diff -aurp scsi-rc-fixes-2.6.orig/drivers/scsi/scsi_lib.c scsi-rc-fixes-2.6.work/drivers/scsi/scsi_lib.c
--- scsi-rc-fixes-2.6.orig/drivers/scsi/scsi_lib.c	2005-02-04 22:11:02.000000000 -0800
+++ scsi-rc-fixes-2.6.work/drivers/scsi/scsi_lib.c	2005-02-10 20:25:50.000000000 -0800
@@ -966,12 +966,12 @@ static int scsi_issue_flush_fn(request_q
 			       sector_t *error_sector)
 {
 	struct scsi_device *sdev = q->queuedata;
-	struct scsi_driver *drv;
+	struct scsi_device_driver *drv;
 
 	if (sdev->sdev_state != SDEV_RUNNING)
 		return -ENXIO;
 
-	drv = *(struct scsi_driver **) disk->private_data;
+	drv = *(struct scsi_device_driver **) disk->private_data;
 	if (drv->issue_flush)
 		return drv->issue_flush(&sdev->sdev_gendev, error_sector);
 
@@ -1073,7 +1073,7 @@ static int scsi_prep_fn(struct request_q
 	 * happening now.
 	 */
 	if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
-		struct scsi_driver *drv;
+		struct scsi_device_driver *drv;
 		int ret;
 
 		/*
@@ -1100,7 +1100,7 @@ static int scsi_prep_fn(struct request_q
 		/*
 		 * Initialize the actual SCSI command for this request.
 		 */
-		drv = *(struct scsi_driver **)req->rq_disk->private_data;
+		drv = *(struct scsi_device_driver **)req->rq_disk->private_data;
 		if (unlikely(!drv->init_command(cmd))) {
 			scsi_release_buffers(cmd);
 			scsi_put_command(cmd);
diff -aurp scsi-rc-fixes-2.6.orig/drivers/scsi/scsi_scan.c scsi-rc-fixes-2.6.work/drivers/scsi/scsi_scan.c
--- scsi-rc-fixes-2.6.orig/drivers/scsi/scsi_scan.c	2005-02-04 22:12:05.000000000 -0800
+++ scsi-rc-fixes-2.6.work/drivers/scsi/scsi_scan.c	2005-02-10 20:26:51.000000000 -0800
@@ -1089,12 +1089,12 @@ EXPORT_SYMBOL(__scsi_add_device);
 
 void scsi_rescan_device(struct device *dev)
 {
-	struct scsi_driver *drv;
+	struct scsi_device_driver *drv;
 	
 	if (!dev->driver)
 		return;
 
-	drv = to_scsi_driver(dev->driver);
+	drv = to_scsi_device_driver(dev->driver);
 	if (try_module_get(drv->owner)) {
 		if (drv->rescan)
 			drv->rescan(dev);
diff -aurp scsi-rc-fixes-2.6.orig/drivers/scsi/scsi_sysfs.c scsi-rc-fixes-2.6.work/drivers/scsi/scsi_sysfs.c
--- scsi-rc-fixes-2.6.orig/drivers/scsi/scsi_sysfs.c	2005-02-04 22:10:23.000000000 -0800
+++ scsi-rc-fixes-2.6.work/drivers/scsi/scsi_sysfs.c	2005-02-11 20:53:22.000000000 -0800
@@ -14,6 +14,7 @@
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
+#include <scsi/scsi_driver.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_transport.h>
@@ -653,13 +654,19 @@ out:
 }
 EXPORT_SYMBOL(scsi_remove_device);
 
-int scsi_register_driver(struct device_driver *drv)
+int scsi_register_device_driver(struct scsi_device_driver *sdrv)
 {
-	drv->bus = &scsi_bus_type;
+	sdrv->gendrv.bus = &scsi_bus_type;
 
-	return driver_register(drv);
+	return driver_register(&sdrv->gendrv);
 }
-EXPORT_SYMBOL(scsi_register_driver);
+EXPORT_SYMBOL(scsi_register_device_driver);
+
+void scsi_unregister_device_driver(struct scsi_device_driver *sdrv)
+{
+	driver_unregister(&sdrv->gendrv);
+}
+EXPORT_SYMBOL(scsi_unregister_device_driver);
 
 int scsi_register_interface(struct class_interface *intf)
 {
diff -aurp scsi-rc-fixes-2.6.orig/drivers/scsi/sd.c scsi-rc-fixes-2.6.work/drivers/scsi/sd.c
--- scsi-rc-fixes-2.6.orig/drivers/scsi/sd.c	2005-02-04 22:11:57.000000000 -0800
+++ scsi-rc-fixes-2.6.work/drivers/scsi/sd.c	2005-02-11 20:50:20.000000000 -0800
@@ -92,7 +92,7 @@
 static void scsi_disk_release(struct kref *kref);
 
 struct scsi_disk {
-	struct scsi_driver *driver;	/* always &sd_template */
+	struct scsi_device_driver *driver;	/* always &sd_template */
 	struct scsi_device *device;
 	struct kref	kref;
 	struct gendisk	*disk;
@@ -125,7 +125,7 @@ static int sd_issue_flush(struct device 
 static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
 		 struct scsi_request *SRpnt, unsigned char *buffer);
 
-static struct scsi_driver sd_template = {
+static struct scsi_device_driver sd_template = {
 	.owner			= THIS_MODULE,
 	.gendrv = {
 		.name		= "sd",
@@ -1631,7 +1631,7 @@ static int __init init_sd(void)
 	if (!majors)
 		return -ENODEV;
 
-	return scsi_register_driver(&sd_template.gendrv);
+	return scsi_register_device_driver(&sd_template);
 }
 
 /**
@@ -1645,7 +1645,7 @@ static void __exit exit_sd(void)
 
 	SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
 
-	scsi_unregister_driver(&sd_template.gendrv);
+	scsi_unregister_device_driver(&sd_template);
 	for (i = 0; i < SD_MAJORS; i++)
 		unregister_blkdev(sd_major(i), "sd");
 }
diff -aurp scsi-rc-fixes-2.6.orig/drivers/scsi/sr.c scsi-rc-fixes-2.6.work/drivers/scsi/sr.c
--- scsi-rc-fixes-2.6.orig/drivers/scsi/sr.c	2005-02-04 22:13:14.000000000 -0800
+++ scsi-rc-fixes-2.6.work/drivers/scsi/sr.c	2005-02-11 20:50:33.000000000 -0800
@@ -74,7 +74,7 @@ static int sr_probe(struct device *);
 static int sr_remove(struct device *);
 static int sr_init_command(struct scsi_cmnd *);
 
-static struct scsi_driver sr_template = {
+static struct scsi_device_driver sr_template = {
 	.owner			= THIS_MODULE,
 	.gendrv = {
 		.name   	= "sr",
@@ -947,12 +947,12 @@ static int __init init_sr(void)
 	rc = register_blkdev(SCSI_CDROM_MAJOR, "sr");
 	if (rc)
 		return rc;
-	return scsi_register_driver(&sr_template.gendrv);
+	return scsi_register_device_driver(&sr_template);
 }
 
 static void __exit exit_sr(void)
 {
-	scsi_unregister_driver(&sr_template.gendrv);
+	scsi_unregister_device_driver(&sr_template);
 	unregister_blkdev(SCSI_CDROM_MAJOR, "sr");
 }
 
diff -aurp scsi-rc-fixes-2.6.orig/drivers/scsi/sr.h scsi-rc-fixes-2.6.work/drivers/scsi/sr.h
--- scsi-rc-fixes-2.6.orig/drivers/scsi/sr.h	2005-02-04 22:10:40.000000000 -0800
+++ scsi-rc-fixes-2.6.work/drivers/scsi/sr.h	2005-02-11 20:55:00.000000000 -0800
@@ -28,7 +28,7 @@ struct scsi_device;
 
 
 typedef struct scsi_cd {
-	struct scsi_driver *driver;
+	struct scsi_device_driver *driver;
 	unsigned capacity;	/* size in blocks                       */
 	struct scsi_device *device;
 	unsigned int vendor;	/* vendor code, see sr_vendor.c         */
diff -aurp scsi-rc-fixes-2.6.orig/drivers/scsi/st.c scsi-rc-fixes-2.6.work/drivers/scsi/st.c
--- scsi-rc-fixes-2.6.orig/drivers/scsi/st.c	2005-02-04 22:11:33.000000000 -0800
+++ scsi-rc-fixes-2.6.work/drivers/scsi/st.c	2005-02-11 20:56:43.000000000 -0800
@@ -198,7 +198,7 @@ static void do_create_driverfs_files(voi
 static void do_remove_driverfs_files(void);
 static void do_create_class_files(struct scsi_tape *, int, int);
 
-static struct scsi_driver st_template = {
+static struct scsi_device_driver st_template = {
 	.owner			= THIS_MODULE,
 	.gendrv = {
 		.name		= "st",
@@ -4062,7 +4062,7 @@ static int __init init_st(void)
 
 	if (!register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
 				    ST_MAX_TAPE_ENTRIES, "st")) {
-		if (scsi_register_driver(&st_template.gendrv) == 0) {
+		if (scsi_register_device_driver(&st_template) == 0) {
 			do_create_driverfs_files();
 			return 0;
 		}
@@ -4083,7 +4083,7 @@ static void __exit exit_st(void)
 		class_simple_destroy(st_sysfs_class);
 	st_sysfs_class = NULL;
 	do_remove_driverfs_files();
-	scsi_unregister_driver(&st_template.gendrv);
+	scsi_unregister_device_driver(&st_template);
 	unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
 				 ST_MAX_TAPE_ENTRIES);
 	kfree(scsi_tapes);
diff -aurp scsi-rc-fixes-2.6.orig/drivers/scsi/st.h scsi-rc-fixes-2.6.work/drivers/scsi/st.h
--- scsi-rc-fixes-2.6.orig/drivers/scsi/st.h	2005-02-04 22:12:09.000000000 -0800
+++ scsi-rc-fixes-2.6.work/drivers/scsi/st.h	2005-02-11 20:55:39.000000000 -0800
@@ -73,7 +73,7 @@ struct st_partstat {
 
 /* The tape drive descriptor */
 struct scsi_tape {
-	struct scsi_driver *driver;
+	struct scsi_device_driver *driver;
 	struct scsi_device *device;
 	struct semaphore lock;	/* For serialization */
 	struct completion wait;	/* For SCSI commands */
diff -aurp scsi-rc-fixes-2.6.orig/include/scsi/scsi_driver.h scsi-rc-fixes-2.6.work/include/scsi/scsi_driver.h
--- scsi-rc-fixes-2.6.orig/include/scsi/scsi_driver.h	2005-02-04 22:11:49.000000000 -0800
+++ scsi-rc-fixes-2.6.work/include/scsi/scsi_driver.h	2005-02-11 20:47:43.000000000 -0800
@@ -7,7 +7,7 @@ struct module;
 struct scsi_cmnd;
 
 
-struct scsi_driver {
+struct scsi_device_driver {
 	struct module		*owner;
 	struct device_driver	gendrv;
 
@@ -15,15 +15,41 @@ struct scsi_driver {
 	void (*rescan)(struct device *);
 	int (*issue_flush)(struct device *, sector_t *);
 };
-#define to_scsi_driver(drv) \
-	container_of((drv), struct scsi_driver, gendrv)
+#define to_scsi_device_driver(drv) \
+	container_of((drv), struct scsi_device_driver, gendrv)
 
-extern int scsi_register_driver(struct device_driver *);
-#define scsi_unregister_driver(drv) \
-	driver_unregister(drv);
+extern int scsi_register_device_driver(struct scsi_device_driver *);
+extern void scsi_unregister_device_driver(struct scsi_device_driver *);
 
 extern int scsi_register_interface(struct class_interface *);
 #define scsi_unregister_interface(intf) \
 	class_interface_unregister(intf)
 
+struct scsi_virt_host {
+	struct device		dev;
+	struct list_head	list;
+};
+#define to_scsi_virt_host(_dev) \
+	container_of((_dev), struct scsi_virt_host, dev)
+
+struct scsi_host_driver {
+	char			*name;
+	struct module		*owner;
+	struct attribute_group	*attrs;
+
+	int (*probe)(struct scsi_virt_host *);
+	int (*remove)(struct scsi_virt_host *);
+	/*
+	 * internal fields
+	 */
+	struct device_driver	gendrv;
+	struct list_head	devices;
+	spinlock_t		devices_lock;
+};
+#define to_scsi_host_driver(_drv) \
+	container_of((_drv), struct scsi_host_driver, gendrv)
+
+extern int scsi_register_host_driver(struct scsi_host_driver *);
+extern void scsi_unregister_host_driver(struct scsi_host_driver *);
+
 #endif /* _SCSI_SCSI_DRIVER_H */

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2005-02-14 18:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-12  5:23 [PATCH] add scsi bus for virtual drivers take3 Mike Christie
2005-02-14 18:02 ` Randy.Dunlap

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox