The attach patch converts scsi_debug to use the virtual scsi bus.
It was built against scsi-rc-fixes-2.6.

The interface has changed a little. Here is an
example of adding and removing a single host:

cd /sys/bus/scsi_host/drivers/scsi_debug
[EMAIL PROTECTED] scsi_debug]# ls
add_host  dev_size_mb  every_nth  module     num_parts  opts   scsi_level
delay     dsense       max_luns   num_hosts  num_tgts   ptype
[EMAIL PROTECTED] scsi_debug]# echo 1 > add_host
[EMAIL PROTECTED] scsi_debug]# ls
add_host  dev_size_mb  every_nth  module     num_parts  opts   scsi_level
delay     dsense       max_luns   num_hosts  num_tgts   ptype  virt_host4
[EMAIL PROTECTED] scsi_debug]# cd virt_host4/
[EMAIL PROTECTED] virt_host4]# ls
detach_state  driver  host4  power  remove_host
[EMAIL PROTECTED] virt_host4]# echo 1 > remove_host


Mike
--- scsi-rc-fixes-2.6.orig/drivers/scsi/scsi_debug.c	2005-02-04 22:11:25.000000000 -0800
+++ scsi-rc-fixes-2.6.work/drivers/scsi/scsi_debug.c	2005-02-11 00:54:13.000000000 -0800
@@ -44,6 +44,7 @@
 #include <linux/blkdev.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_driver.h>
 #include <scsi/scsicam.h>
 
 #include <linux/stat.h>
@@ -112,7 +113,7 @@ static const char * scsi_debug_version_d
  * or "peripheral device" addressing (value 0) */
 #define SAM2_LUN_ADDRESS_METHOD 0
 
-static int scsi_debug_add_host = DEF_NUM_HOST;
+static int scsi_debug_num_hosts;
 static int scsi_debug_delay = DEF_DELAY;
 static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB;
 static int scsi_debug_every_nth = DEF_EVERY_NTH;
@@ -161,13 +162,9 @@ struct sdebug_dev_info {
 struct sdebug_host_info {
 	struct list_head host_list;
 	struct Scsi_Host *shost;
-	struct device dev;
 	struct list_head dev_info_list;
 };
 
-#define to_sdebug_host(d)	\
-	container_of(d, struct sdebug_host_info, dev)
-
 static LIST_HEAD(sdebug_host_list);
 static DEFINE_SPINLOCK(sdebug_host_list_lock);
 
@@ -218,21 +215,12 @@ static DEFINE_RWLOCK(atomic_rw);
 
 static char sdebug_proc_name[] = "scsi_debug";
 
-static int sdebug_driver_probe(struct device *);
-static int sdebug_driver_remove(struct device *);
-static struct bus_type pseudo_lld_bus;
-
-static struct device_driver sdebug_driverfs_driver = {
-	.name 		= sdebug_proc_name,
-	.bus		= &pseudo_lld_bus,
-	.probe          = sdebug_driver_probe,
-	.remove         = sdebug_driver_remove,
-};
-
 static const int check_condition_result =
 		(DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
 
 /* function declarations */
+static int sdebug_driver_probe(struct scsi_virt_host *);
+static int sdebug_driver_remove(struct scsi_virt_host *);
 static int resp_inquiry(struct scsi_cmnd * SCpnt, int target,
 			struct sdebug_dev_info * devip);
 static int resp_requests(struct scsi_cmnd * SCpnt,
@@ -266,17 +254,11 @@ static void stop_all_queued(void);
 static int stop_queued_cmnd(struct scsi_cmnd * cmnd);
 static int inquiry_evpd_83(unsigned char * arr, int dev_id_num,
                            const char * dev_id_str, int dev_id_str_len);
-static void do_create_driverfs_files(void);
-static void do_remove_driverfs_files(void);
 
-static int sdebug_add_adapter(void);
-static void sdebug_remove_adapter(void);
+static int sdebug_add_adapter(struct sdebug_host_info * sdbg_host);
+static void sdebug_remove_adapter(struct sdebug_host_info * sdbg_host);
 static void sdebug_max_tgts_luns(void);
 
-static struct device pseudo_primary;
-static struct bus_type pseudo_lld_bus;
-
-
 static
 int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
 {
@@ -1054,7 +1036,7 @@ static struct sdebug_dev_info * devInfoR
 
 	if (devip)
 		return devip;
-	sdbg_host = *(struct sdebug_host_info **) sdev->host->hostdata;
+	sdbg_host = (struct sdebug_host_info *) sdev->host->hostdata;
         if(! sdbg_host) {
                 printk(KERN_ERR "Host info NULL\n");
 		return NULL;
@@ -1181,7 +1163,7 @@ static int scsi_debug_bus_reset(struct s
 		printk(KERN_INFO "scsi_debug: bus_reset\n");
 	++num_bus_resets;
 	if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) {
-		sdbg_host = *(struct sdebug_host_info **) hp->hostdata;
+		sdbg_host = (struct sdebug_host_info *) hp->hostdata;
 		if (sdbg_host) {
 			list_for_each_entry(dev_info,
                                             &sdbg_host->dev_info_list,
@@ -1379,7 +1361,6 @@ static int schedule_resp(struct scsi_cmn
  * of sysfs parameters (which module_param doesn't yet support).
  * Sysfs parameters defined explicitly below.
  */
-module_param_named(add_host, scsi_debug_add_host, int, 0); /* perm=0644 */
 module_param_named(delay, scsi_debug_delay, int, 0); /* perm=0644 */
 module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, 0);
 module_param_named(dsense, scsi_debug_dsense, int, 0);
@@ -1633,78 +1614,42 @@ static ssize_t sdebug_scsi_level_show(st
 }
 DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL);
 
-static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf)
+static ssize_t sdebug_num_hosts_show(struct device_driver * ddp, char * buf)
 {
-        return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host);
+        return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_hosts);
 }
+DRIVER_ATTR(num_hosts, S_IRUGO, sdebug_num_hosts_show, NULL);
 
-static ssize_t sdebug_add_host_store(struct device_driver * ddp,
-				     const char * buf, size_t count)
-{
-        int delta_hosts;
-	char work[20];
+static struct attribute *sdebug_attrs[] = {
+	&driver_attr_num_hosts.attr,
+	&driver_attr_delay.attr,
+	&driver_attr_dev_size_mb.attr,
+	&driver_attr_dsense.attr,
+	&driver_attr_every_nth.attr,
+	&driver_attr_max_luns.attr,
+	&driver_attr_num_tgts.attr,
+	&driver_attr_num_parts.attr,
+	&driver_attr_ptype.attr,
+	&driver_attr_opts.attr,
+	&driver_attr_scsi_level.attr,
+	NULL,
+};
 
-        if (1 != sscanf(buf, "%10s", work))
-		return -EINVAL;
-	{	/* temporary hack around sscanf() problem with -ve nums */
-		int neg = 0;
-
-		if ('-' == *work)
-			neg = 1;
-		if (1 != sscanf(work + neg, "%d", &delta_hosts))
-			return -EINVAL;
-		if (neg)
-			delta_hosts = -delta_hosts;
-	}
-	if (delta_hosts > 0) {
-		do {
-			sdebug_add_adapter();
-		} while (--delta_hosts);
-	} else if (delta_hosts < 0) {
-		do {
-			sdebug_remove_adapter();
-		} while (++delta_hosts);
-	}
-	return count;
-}
-DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, 
-	    sdebug_add_host_store);
+static struct attribute_group sdebug_attr_group = {
+	.attrs = sdebug_attrs,
+};
 
-static void do_create_driverfs_files(void)
-{
-	driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
-	driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay);
-	driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
-	driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense);
-	driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
-	driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
-	driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
-	driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
-	driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
-	driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
-	driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
-}
-
-static void do_remove_driverfs_files(void)
-{
-	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
-	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_opts);
-	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ptype);
-	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
-	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
-	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
-	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
-	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dsense);
-	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
-	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_delay);
-	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host);
-}
+static struct scsi_host_driver sdebug_driverfs_driver = {
+	.owner		= THIS_MODULE,
+	.name 		= sdebug_proc_name,
+	.attrs		= &sdebug_attr_group,
+	.probe          = sdebug_driver_probe,
+	.remove         = sdebug_driver_remove,
+};
 
 static int __init scsi_debug_init(void)
 {
 	unsigned long sz;
-	int host_to_add;
-	int k;
 
 	if (scsi_debug_dev_size_mb < 1)
 		scsi_debug_dev_size_mb = 1;  /* force minimum 1 MB ramdisk */
@@ -1740,42 +1685,19 @@ static int __init scsi_debug_init(void)
 
 	init_all_queued();
 
-	device_register(&pseudo_primary);
-	bus_register(&pseudo_lld_bus);
-	driver_register(&sdebug_driverfs_driver);
-	do_create_driverfs_files();
-
+	scsi_register_host_driver(&sdebug_driverfs_driver);
 	sdebug_driver_template.proc_name = (char *)sdebug_proc_name;
 
-	host_to_add = scsi_debug_add_host;
-        scsi_debug_add_host = 0;
-
-        for (k = 0; k < host_to_add; k++) {
-                if (sdebug_add_adapter()) {
-                        printk(KERN_ERR "scsi_debug_init: "
-                               "sdebug_add_adapter failed k=%d\n", k);
-                        break;
-                }
-        }
-
 	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
-		printk(KERN_INFO "scsi_debug_init: built %d host(s)\n",
-		       scsi_debug_add_host);
+		printk(KERN_INFO "scsi_debug driver\n");
 	}
 	return 0;
 }
 
 static void __exit scsi_debug_exit(void)
 {
-	int k = scsi_debug_add_host;
-
 	stop_all_queued();
-	for (; k; k--)
-		sdebug_remove_adapter();
-	do_remove_driverfs_files();
-	driver_unregister(&sdebug_driverfs_driver);
-	bus_unregister(&pseudo_lld_bus);
-	device_unregister(&pseudo_primary);
+	scsi_unregister_host_driver(&sdebug_driverfs_driver);
 
 	vfree(fake_storep);
 }
@@ -1783,52 +1705,13 @@ static void __exit scsi_debug_exit(void)
 device_initcall(scsi_debug_init);
 module_exit(scsi_debug_exit);
 
-void pseudo_0_release(struct device * dev)
-{
-	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
-		printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n");
-}
-
-static struct device pseudo_primary = {
-	.bus_id		= "pseudo_0",
-	.release	= pseudo_0_release,
-};
-
-static int pseudo_lld_bus_match(struct device *dev,
-                          struct device_driver *dev_driver)
-{
-        return 1;
-}
-
-static struct bus_type pseudo_lld_bus = {
-        .name = "pseudo",
-        .match = pseudo_lld_bus_match,
-};
-
-static void sdebug_release_adapter(struct device * dev)
-{
-        struct sdebug_host_info *sdbg_host;
-
-	sdbg_host = to_sdebug_host(dev);
-        kfree(sdbg_host);
-}
-
-static int sdebug_add_adapter(void)
+static int sdebug_add_adapter(struct sdebug_host_info * sdbg_host)
 {
 	int k, devs_per_host;
         int error = 0;
-        struct sdebug_host_info *sdbg_host;
         struct sdebug_dev_info *sdbg_devinfo;
         struct list_head *lh, *lh_sf;
 
-        sdbg_host = kmalloc(sizeof(*sdbg_host),GFP_KERNEL);
-
-        if (NULL == sdbg_host) {
-                printk(KERN_ERR "%s: out of memory at line %d\n",
-                       __FUNCTION__, __LINE__);
-                return -ENOMEM;
-        }
-
         memset(sdbg_host, 0, sizeof(*sdbg_host));
         INIT_LIST_HEAD(&sdbg_host->dev_info_list);
 
@@ -1851,17 +1734,7 @@ static int sdebug_add_adapter(void)
         list_add_tail(&sdbg_host->host_list, &sdebug_host_list);
         spin_unlock(&sdebug_host_list_lock);
 
-        sdbg_host->dev.bus = &pseudo_lld_bus;
-        sdbg_host->dev.parent = &pseudo_primary;
-        sdbg_host->dev.release = &sdebug_release_adapter;
-        sprintf(sdbg_host->dev.bus_id, "adapter%d", scsi_debug_add_host);
-
-        error = device_register(&sdbg_host->dev);
-
-        if (error)
-		goto clean;
-
-	++scsi_debug_add_host;
+	++scsi_debug_num_hosts;
         return error;
 
 clean:
@@ -1872,77 +1745,64 @@ clean:
 		kfree(sdbg_devinfo);
 	}
 
-	kfree(sdbg_host);
         return error;
 }
 
-static void sdebug_remove_adapter(void)
+static void sdebug_remove_adapter(struct sdebug_host_info * sdbg_host)
 {
-        struct sdebug_host_info * sdbg_host = NULL;
-
         spin_lock(&sdebug_host_list_lock);
-        if (!list_empty(&sdebug_host_list)) {
-                sdbg_host = list_entry(sdebug_host_list.prev,
-                                       struct sdebug_host_info, host_list);
-		list_del(&sdbg_host->host_list);
-	}
+	list_del(&sdbg_host->host_list);
         spin_unlock(&sdebug_host_list_lock);
 
-	if (!sdbg_host)
-		return;
-
-        device_unregister(&sdbg_host->dev);
-        --scsi_debug_add_host;
+        --scsi_debug_num_hosts;
 }
 
-static int sdebug_driver_probe(struct device * dev)
+static int sdebug_driver_probe(struct scsi_virt_host * vhost)
 {
         int error = 0;
         struct sdebug_host_info *sdbg_host;
         struct Scsi_Host *hpnt;
 
-	sdbg_host = to_sdebug_host(dev);
-
-        hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(sdbg_host));
+        hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(*sdbg_host));
         if (NULL == hpnt) {
                 printk(KERN_ERR "%s: scsi_register failed\n", __FUNCTION__);
                 error = -ENODEV;
 		return error;
         }
 
-        sdbg_host->shost = hpnt;
-	*((struct sdebug_host_info **)hpnt->hostdata) = sdbg_host;
+	sdbg_host = (struct sdebug_host_info *)hpnt->hostdata;
+	if (sdebug_add_adapter(sdbg_host))
+		goto failed;
+	sdbg_host->shost = hpnt;
+	dev_set_drvdata(&vhost->dev, sdbg_host);
+
 	if ((hpnt->this_id >= 0) && (scsi_debug_num_tgts > hpnt->this_id))
 		hpnt->max_id = scsi_debug_num_tgts + 1;
 	else
 		hpnt->max_id = scsi_debug_num_tgts;
 	hpnt->max_lun = scsi_debug_max_luns;
 
-        error = scsi_add_host(hpnt, &sdbg_host->dev);
-        if (error) {
-                printk(KERN_ERR "%s: scsi_add_host failed\n", __FUNCTION__);
-                error = -ENODEV;
-		scsi_host_put(hpnt);
-        } else
-		scsi_scan_host(hpnt);
-
+        error = scsi_add_host(hpnt, &vhost->dev);
+        if (error)
+		goto failed;
 
+	scsi_scan_host(hpnt);
         return error;
+
+ failed:
+	printk(KERN_ERR "%s: scsi_add_host failed\n", __FUNCTION__);
+	scsi_host_put(hpnt);
+	return -ENODEV;
 }
 
-static int sdebug_driver_remove(struct device * dev)
+static int sdebug_driver_remove(struct scsi_virt_host * vhost)
 {
         struct list_head *lh, *lh_sf;
         struct sdebug_host_info *sdbg_host;
         struct sdebug_dev_info *sdbg_devinfo;
 
-	sdbg_host = to_sdebug_host(dev);
-
-	if (!sdbg_host) {
-		printk(KERN_ERR "%s: Unable to locate host info\n",
-		       __FUNCTION__);
-		return -ENODEV;
-	}
+	sdbg_host = dev_get_drvdata(&vhost->dev);
+	sdebug_remove_adapter(sdbg_host);
 
         scsi_remove_host(sdbg_host->shost);
 

Reply via email to