All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mike Christie <michaelc@cs.wisc.edu>
To: linux-scsi <linux-scsi@vger.kernel.org>
Subject: [PATCH] cpnvert scsi_debug to use virtual host bus
Date: Fri, 11 Feb 2005 17:38:11 -0800	[thread overview]
Message-ID: <420D5E03.2020409@cs.wisc.edu> (raw)

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

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
[root@mina 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
[root@mina scsi_debug]# echo 1 > add_host
[root@mina 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
[root@mina scsi_debug]# cd virt_host4/
[root@mina virt_host4]# ls
detach_state  driver  host4  power  remove_host
[root@mina virt_host4]# echo 1 > remove_host


Mike

[-- Attachment #2: use-ml-virtual-bus.patch --]
[-- Type: text/x-patch, Size: 13963 bytes --]

--- 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	other threads:[~2005-02-12  1:38 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-12  1:38 Mike Christie [this message]
2005-02-15  5:13 ` [PATCH] cpnvert scsi_debug to use virtual host bus Douglas Gilbert
2005-02-15 18:48   ` Mike Christie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=420D5E03.2020409@cs.wisc.edu \
    --to=michaelc@cs.wisc.edu \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.