From: Mike Anderson <andmike@us.ibm.com>
To: linux-scsi@vger.kernel.org, Patrick Mochel <mochel@osdl.org>
Subject: [RFC] scsi host sysfs support again [2/4]
Date: Mon, 5 May 2003 01:35:40 -0700 [thread overview]
Message-ID: <20030505083540.GD8416@beaverton.ibm.com> (raw)
In-Reply-To: <20030505083445.GC8416@beaverton.ibm.com>
-andmike
--
Michael Anderson
andmike@us.ibm.com
DESC
This patch changes the structure of sdebug_host_info and changes the
method / order of driver model cleanup.
EDESC
drivers/scsi/scsi_debug.c | 215 ++++++++++++++++++++++++----------------------
drivers/scsi/scsi_debug.h | 2
2 files changed, 115 insertions(+), 102 deletions(-)
diff -puN drivers/scsi/scsi_debug.c~scsi_debug-sysfs drivers/scsi/scsi_debug.c
--- sysfs-scsi-misc-2.5/drivers/scsi/scsi_debug.c~scsi_debug-sysfs Thu May 1 18:09:26 2003
+++ sysfs-scsi-misc-2.5-andmike/drivers/scsi/scsi_debug.c Thu May 1 18:09:26 2003
@@ -55,7 +55,7 @@
#include "scsi_logging.h"
#include "scsi_debug.h"
-static const char * scsi_debug_version_str = "Version: 1.69 (20030329)";
+static const char * scsi_debug_version_str = "Version: 1.70 (20030416)";
/* Additional Sense Code (ASC) used */
#define NO_ADDED_SENSE 0x0
@@ -145,10 +145,13 @@ struct sdebug_dev_info {
struct sdebug_host_info {
struct list_head host_list;
struct Scsi_Host *shost;
- struct device *dev;
+ 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 spinlock_t sdebug_host_list_lock = SPIN_LOCK_UNLOCKED;
@@ -225,22 +228,6 @@ static struct bus_type pseudo_lld_bus;
static int scsi_debug_register_driver(struct device_driver *);
static int scsi_debug_unregister_driver(struct device_driver *);
-static struct sdebug_host_info *
- sdebug_shost_to_host_info(struct Scsi_Host *shost)
-{
- struct sdebug_host_info * sdbg_host, * found = NULL;
-
- spin_lock(&sdebug_host_list_lock);
- list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
- if (sdbg_host->shost == shost) {
- found = sdbg_host;
- break;
- }
- }
- spin_unlock(&sdebug_host_list_lock);
- return found;
-}
-
static unsigned char * scatg2virt(const struct scatterlist * sclp)
{
if (NULL == sclp)
@@ -644,6 +631,15 @@ static int resp_ctrl_m_pg(unsigned char
return sizeof(ctrl_m_pg);
}
+static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target)
+{ /* Informational Exceptions control mode page for mode_sense */
+ unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
+ 0, 0, 0x0, 0x0};
+ memcpy(p, iec_m_pg, sizeof(iec_m_pg));
+ if (1 == pcontrol)
+ memset(p + 2, 0, sizeof(iec_m_pg) - 2);
+ return sizeof(iec_m_pg);
+}
#define SDEBUG_MAX_MSENSE_SZ 256
@@ -710,12 +706,17 @@ static int resp_mode_sense(unsigned char
len = resp_ctrl_m_pg(ap, pcontrol, target);
offset += len;
break;
+ case 0x1c: /* Informational Exceptions Mode page, all devices */
+ len = resp_iec_m_pg(ap, pcontrol, target);
+ offset += len;
+ break;
case 0x3f: /* Read all Mode pages */
len = resp_err_recov_pg(ap, pcontrol, target);
len += resp_disconnect_pg(ap + len, pcontrol, target);
len += resp_format_pg(ap + len, pcontrol, target);
len += resp_caching_pg(ap + len, pcontrol, target);
len += resp_ctrl_m_pg(ap + len, pcontrol, target);
+ len += resp_iec_m_pg(ap + len, pcontrol, target);
offset += len;
break;
default:
@@ -939,9 +940,9 @@ static struct sdebug_dev_info * devInfoR
if (devip)
return devip;
- sdbg_host = sdebug_shost_to_host_info(sdev->host);
+ sdbg_host = *(struct sdebug_host_info **) sdev->host->hostdata;
if(! sdbg_host) {
- printk(KERN_ERR "Unable to locate host info\n");
+ printk(KERN_ERR "Host info NULL\n");
return NULL;
}
list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) {
@@ -1041,7 +1042,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 = sdebug_shost_to_host_info(hp);
+ sdbg_host = *(struct sdebug_host_info **) hp->hostdata;
if (sdbg_host) {
list_for_each_entry(dev_info,
&sdbg_host->dev_info_list,
@@ -1522,8 +1523,11 @@ static int __init scsi_debug_init(void)
static void __exit scsi_debug_exit(void)
{
- /* free up adapters here ?? */
+ int k = scsi_debug_add_host;
+
stop_all_queued();
+ for (; k; k--)
+ sdebug_remove_adapter();
do_remove_driverfs_files();
scsi_debug_unregister_driver(&sdebug_driverfs_driver);
bus_unregister(&pseudo_lld_bus);
@@ -1567,35 +1571,74 @@ static int scsi_debug_unregister_driver(
static void sdebug_release_adapter(struct device * dev)
{
- kfree(dev);
+ struct sdebug_host_info *sdbg_host;
+
+ sdbg_host = to_sdebug_host(dev);
+ kfree(sdbg_host);
}
static int sdebug_add_adapter()
{
- struct device * dev;
- int error;
+ 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);
- dev = kmalloc(sizeof(*dev),GFP_KERNEL);
- if (NULL == dev) {
+ if (NULL == sdbg_host) {
printk(KERN_ERR "%s: out of memory at line %d\n",
__FUNCTION__, __LINE__);
return -ENOMEM;
}
- memset(dev, 0, sizeof(*dev));
- dev->bus = &pseudo_lld_bus;
- dev->parent = &pseudo_primary;
- dev->release = &sdebug_release_adapter;
- sprintf(dev->name, "scsi debug adapter");
- sprintf(dev->bus_id, "adapter%d", scsi_debug_add_host);
+ memset(sdbg_host, 0, sizeof(*sdbg_host));
+ INIT_LIST_HEAD(&sdbg_host->dev_info_list);
+
+ devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns;
+ for (k = 0; k < devs_per_host; k++) {
+ sdbg_devinfo = kmalloc(sizeof(*sdbg_devinfo),GFP_KERNEL);
+ if (NULL == sdbg_devinfo) {
+ printk(KERN_ERR "%s: out of memory at line %d\n",
+ __FUNCTION__, __LINE__);
+ error = -ENOMEM;
+ goto clean1;
+ }
+ memset(sdbg_devinfo, 0, sizeof(*sdbg_devinfo));
+ sdbg_devinfo->sdbg_host = sdbg_host;
+ list_add_tail(&sdbg_devinfo->dev_list,
+ &sdbg_host->dev_info_list);
+ }
+
+ spin_lock(&sdebug_host_list_lock);
+ 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.name, "scsi debug adapter");
+ sprintf(sdbg_host->dev.bus_id, "adapter%d", scsi_debug_add_host);
- error = device_register(dev);
+ error = device_register(&sdbg_host->dev);
if (error)
- kfree(dev);
- else
- ++scsi_debug_add_host;
+ goto clean2;
+ ++scsi_debug_add_host;
+ return error;
+
+clean2:
+ list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) {
+ sdbg_devinfo = list_entry(lh, struct sdebug_dev_info,
+ dev_list);
+ list_del(&sdbg_devinfo->dev_list);
+ kfree(sdbg_devinfo);
+ }
+
+clean1:
+ kfree(sdbg_host);
return error;
}
@@ -1604,51 +1647,29 @@ static void sdebug_remove_adapter()
struct sdebug_host_info * sdbg_host = NULL;
spin_lock(&sdebug_host_list_lock);
- if (!list_empty(&sdebug_host_list))
+ 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);
+ }
spin_unlock(&sdebug_host_list_lock);
- device_unregister(sdbg_host->dev);
+ if (!sdbg_host)
+ return;
+
+ device_unregister(&sdbg_host->dev);
--scsi_debug_add_host;
}
static int sdebug_driver_probe(struct device * dev)
{
- 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;
struct Scsi_Host *hpnt;
- 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);
-
- devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns;
- for (k = 0; k < devs_per_host; k++) {
- sdbg_devinfo = kmalloc(sizeof(*sdbg_devinfo),GFP_KERNEL);
- if (NULL == sdbg_devinfo) {
- printk(KERN_ERR "%s: out of memory at line %d\n",
- __FUNCTION__, __LINE__);
- error = -ENOMEM;
- }
- memset(sdbg_devinfo, 0, sizeof(*sdbg_devinfo));
- sdbg_devinfo->sdbg_host = sdbg_host;
- list_add_tail(&sdbg_devinfo->dev_list,
- &sdbg_host->dev_info_list);
- }
-
- list_add_tail(&sdbg_host->host_list, &sdebug_host_list);
+ sdbg_host = to_sdebug_host(dev);
- hpnt = scsi_register(&sdebug_driver_template, 0);
+ hpnt = scsi_register(&sdebug_driver_template, sizeof(sdbg_host));
if (NULL == hpnt) {
printk(KERN_ERR "%s: scsi_register failed\n", __FUNCTION__);
error = -ENODEV;
@@ -1656,14 +1677,14 @@ static int sdebug_driver_probe(struct de
}
sdbg_host->shost = hpnt;
- sdbg_host->dev = dev;
+ *((struct sdebug_host_info **)hpnt->hostdata) = 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);
+ error = scsi_add_host(hpnt, &sdbg_host->dev);
if (error) {
printk(KERN_ERR "%s: scsi_add_host failed\n", __FUNCTION__);
error = -ENODEV;
@@ -1676,47 +1697,24 @@ static int sdebug_driver_probe(struct de
clean2:
scsi_unregister(hpnt);
clean1:
- list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) {
- sdbg_devinfo = list_entry(lh, struct sdebug_dev_info,
- dev_list);
- list_del(&sdbg_devinfo->dev_list);
- kfree(sdbg_devinfo);
- }
-
kfree(sdbg_host);
return error;
}
-static int sdebug_driver_remove(struct device * dev)
+static int scsi_debug_release(struct Scsi_Host * shost)
{
struct list_head *lh, *lh_sf;
struct sdebug_dev_info *sdbg_devinfo;
- struct sdebug_host_info *sdbg_host, *found = NULL;
-
- spin_lock(&sdebug_host_list_lock);
- list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
- if (sdbg_host->dev == dev) {
- list_del(&sdbg_host->host_list);
- found = sdbg_host;
- break;
- }
- }
- spin_unlock(&sdebug_host_list_lock);
-
- if (!found) {
- printk(KERN_ERR "%s: sdebug_host_info not found\n",
- __FUNCTION__);
- return -ENODEV;
- }
+ struct sdebug_host_info *sdbg_host;
+ sdbg_host = *(struct sdebug_host_info **)shost->hostdata;
+ scsi_unregister(shost);
- if (scsi_remove_host(sdbg_host->shost)) {
- printk(KERN_ERR "%s: scsi_remove_host failed\n", __FUNCTION__);
- return -EBUSY;
- }
-
- scsi_unregister(sdbg_host->shost);
+ if (!sdbg_host) {
+ printk(KERN_ERR "Unable to locate host info\n");
+ return 0;
+ }
list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) {
sdbg_devinfo = list_entry(lh, struct sdebug_dev_info,
@@ -1725,7 +1723,20 @@ static int sdebug_driver_remove(struct d
kfree(sdbg_devinfo);
}
- kfree(sdbg_host);
+ return 0;
+
+}
+
+static int sdebug_driver_remove(struct device * dev)
+{
+ struct sdebug_host_info *sdbg_host;
+
+ sdbg_host = to_sdebug_host(dev);
+
+ if (sdbg_host && scsi_remove_host(sdbg_host->shost)) {
+ printk(KERN_ERR "%s: scsi_remove_host failed\n", __FUNCTION__);
+ return -EBUSY;
+ }
return 0;
}
diff -puN drivers/scsi/scsi_debug.h~scsi_debug-sysfs drivers/scsi/scsi_debug.h
--- sysfs-scsi-misc-2.5/drivers/scsi/scsi_debug.h~scsi_debug-sysfs Thu May 1 18:09:26 2003
+++ sysfs-scsi-misc-2.5-andmike/drivers/scsi/scsi_debug.h Thu May 1 18:09:26 2003
@@ -16,6 +16,7 @@ static int scsi_debug_device_reset(struc
static int scsi_debug_host_reset(struct scsi_cmnd *);
static int scsi_debug_proc_info(char *, char **, off_t, int, int, int);
static const char * scsi_debug_info(struct Scsi_Host *);
+static int scsi_debug_release(struct Scsi_Host *);
/*
* This driver is written for the lk 2.5 series
@@ -27,6 +28,7 @@ static const char * scsi_debug_info(stru
static Scsi_Host_Template sdebug_driver_template = {
.proc_info = scsi_debug_proc_info,
.name = "SCSI DEBUG",
+ .release = scsi_debug_release,
.info = scsi_debug_info,
.slave_alloc = scsi_debug_slave_alloc,
.slave_configure = scsi_debug_slave_configure,
_
next prev parent reply other threads:[~2003-05-05 8:20 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-05-05 8:33 [RFC] scsi host sysfs support again [0/4] Mike Anderson
2003-05-05 8:34 ` [RFC] scsi host sysfs support again [1/4] Mike Anderson
2003-05-05 8:35 ` Mike Anderson [this message]
2003-05-05 8:37 ` [RFC] scsi host sysfs support again [3/4] Mike Anderson
2003-05-05 8:38 ` [RFC] scsi host sysfs support again [4/4] Mike Anderson
2003-05-05 8:38 ` [RFC] scsi host sysfs support again [0/4] Christoph Hellwig
2003-05-05 9:40 ` Douglas Gilbert
2003-05-05 10:00 ` Mike Anderson
2003-05-05 9:48 ` Mike Anderson
2003-05-05 10:17 ` Christoph Hellwig
2003-05-06 1:05 ` Mike Anderson
2003-05-07 15:44 ` Christoph Hellwig
2003-05-07 16:15 ` Mike Anderson
2003-05-07 16:41 ` Christoph Hellwig
2003-05-05 11:46 ` Douglas Gilbert
2003-05-05 21:45 ` Mike Anderson
2003-05-06 1:12 ` Douglas Gilbert
2003-05-06 16:28 ` James Bottomley
2003-05-06 17:23 ` Mike Anderson
2003-05-07 23:19 ` Willem Riede
2003-05-08 0:09 ` Douglas Gilbert
2003-05-08 1:44 ` Mike Anderson
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=20030505083540.GD8416@beaverton.ibm.com \
--to=andmike@us.ibm.com \
--cc=linux-scsi@vger.kernel.org \
--cc=mochel@osdl.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.