summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/scsi/device_handler
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/scsi/device_handler')
-rw-r--r--kernel/drivers/scsi/device_handler/Kconfig2
-rw-r--r--kernel/drivers/scsi/device_handler/Makefile1
-rw-r--r--kernel/drivers/scsi/device_handler/scsi_dh.c621
-rw-r--r--kernel/drivers/scsi/device_handler/scsi_dh_alua.c31
-rw-r--r--kernel/drivers/scsi/device_handler/scsi_dh_emc.c58
-rw-r--r--kernel/drivers/scsi/device_handler/scsi_dh_hp_sw.c55
-rw-r--r--kernel/drivers/scsi/device_handler/scsi_dh_rdac.c84
7 files changed, 48 insertions, 804 deletions
diff --git a/kernel/drivers/scsi/device_handler/Kconfig b/kernel/drivers/scsi/device_handler/Kconfig
index 69abd0ad4..e5647d592 100644
--- a/kernel/drivers/scsi/device_handler/Kconfig
+++ b/kernel/drivers/scsi/device_handler/Kconfig
@@ -3,7 +3,7 @@
#
menuconfig SCSI_DH
- tristate "SCSI Device Handlers"
+ bool "SCSI Device Handlers"
depends on SCSI
default n
help
diff --git a/kernel/drivers/scsi/device_handler/Makefile b/kernel/drivers/scsi/device_handler/Makefile
index e1d2ea083..09866c50f 100644
--- a/kernel/drivers/scsi/device_handler/Makefile
+++ b/kernel/drivers/scsi/device_handler/Makefile
@@ -1,7 +1,6 @@
#
# SCSI Device Handler
#
-obj-$(CONFIG_SCSI_DH) += scsi_dh.o
obj-$(CONFIG_SCSI_DH_RDAC) += scsi_dh_rdac.o
obj-$(CONFIG_SCSI_DH_HP_SW) += scsi_dh_hp_sw.o
obj-$(CONFIG_SCSI_DH_EMC) += scsi_dh_emc.o
diff --git a/kernel/drivers/scsi/device_handler/scsi_dh.c b/kernel/drivers/scsi/device_handler/scsi_dh.c
deleted file mode 100644
index 1efebc9ee..000000000
--- a/kernel/drivers/scsi/device_handler/scsi_dh.c
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * SCSI device handler infrastruture.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright IBM Corporation, 2007
- * Authors:
- * Chandra Seetharaman <sekharan@us.ibm.com>
- * Mike Anderson <andmike@linux.vnet.ibm.com>
- */
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <scsi/scsi_dh.h>
-#include "../scsi_priv.h"
-
-static DEFINE_SPINLOCK(list_lock);
-static LIST_HEAD(scsi_dh_list);
-
-static struct scsi_device_handler *get_device_handler(const char *name)
-{
- struct scsi_device_handler *tmp, *found = NULL;
-
- spin_lock(&list_lock);
- list_for_each_entry(tmp, &scsi_dh_list, list) {
- if (!strncmp(tmp->name, name, strlen(tmp->name))) {
- found = tmp;
- break;
- }
- }
- spin_unlock(&list_lock);
- return found;
-}
-
-/*
- * device_handler_match_function - Match a device handler to a device
- * @sdev - SCSI device to be tested
- *
- * Tests @sdev against the match function of all registered device_handler.
- * Returns the found device handler or NULL if not found.
- */
-static struct scsi_device_handler *
-device_handler_match_function(struct scsi_device *sdev)
-{
- struct scsi_device_handler *tmp_dh, *found_dh = NULL;
-
- spin_lock(&list_lock);
- list_for_each_entry(tmp_dh, &scsi_dh_list, list) {
- if (tmp_dh->match && tmp_dh->match(sdev)) {
- found_dh = tmp_dh;
- break;
- }
- }
- spin_unlock(&list_lock);
- return found_dh;
-}
-
-/*
- * device_handler_match - Attach a device handler to a device
- * @scsi_dh - The device handler to match against or NULL
- * @sdev - SCSI device to be tested against @scsi_dh
- *
- * Tests @sdev against the device handler @scsi_dh or against
- * all registered device_handler if @scsi_dh == NULL.
- * Returns the found device handler or NULL if not found.
- */
-static struct scsi_device_handler *
-device_handler_match(struct scsi_device_handler *scsi_dh,
- struct scsi_device *sdev)
-{
- struct scsi_device_handler *found_dh;
-
- found_dh = device_handler_match_function(sdev);
-
- if (scsi_dh && found_dh != scsi_dh)
- found_dh = NULL;
-
- return found_dh;
-}
-
-/*
- * scsi_dh_handler_attach - Attach a device handler to a device
- * @sdev - SCSI device the device handler should attach to
- * @scsi_dh - The device handler to attach
- */
-static int scsi_dh_handler_attach(struct scsi_device *sdev,
- struct scsi_device_handler *scsi_dh)
-{
- struct scsi_dh_data *d;
-
- if (sdev->scsi_dh_data) {
- if (sdev->scsi_dh_data->scsi_dh != scsi_dh)
- return -EBUSY;
-
- kref_get(&sdev->scsi_dh_data->kref);
- return 0;
- }
-
- if (!try_module_get(scsi_dh->module))
- return -EINVAL;
-
- d = scsi_dh->attach(sdev);
- if (IS_ERR(d)) {
- sdev_printk(KERN_ERR, sdev, "%s: Attach failed (%ld)\n",
- scsi_dh->name, PTR_ERR(d));
- module_put(scsi_dh->module);
- return PTR_ERR(d);
- }
-
- d->scsi_dh = scsi_dh;
- kref_init(&d->kref);
- d->sdev = sdev;
-
- spin_lock_irq(sdev->request_queue->queue_lock);
- sdev->scsi_dh_data = d;
- spin_unlock_irq(sdev->request_queue->queue_lock);
- return 0;
-}
-
-static void __detach_handler (struct kref *kref)
-{
- struct scsi_dh_data *scsi_dh_data =
- container_of(kref, struct scsi_dh_data, kref);
- struct scsi_device_handler *scsi_dh = scsi_dh_data->scsi_dh;
- struct scsi_device *sdev = scsi_dh_data->sdev;
-
- scsi_dh->detach(sdev);
-
- spin_lock_irq(sdev->request_queue->queue_lock);
- sdev->scsi_dh_data = NULL;
- spin_unlock_irq(sdev->request_queue->queue_lock);
-
- sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", scsi_dh->name);
- module_put(scsi_dh->module);
-}
-
-/*
- * scsi_dh_handler_detach - Detach a device handler from a device
- * @sdev - SCSI device the device handler should be detached from
- * @scsi_dh - Device handler to be detached
- *
- * Detach from a device handler. If a device handler is specified,
- * only detach if the currently attached handler matches @scsi_dh.
- */
-static void scsi_dh_handler_detach(struct scsi_device *sdev,
- struct scsi_device_handler *scsi_dh)
-{
- if (!sdev->scsi_dh_data)
- return;
-
- if (scsi_dh && scsi_dh != sdev->scsi_dh_data->scsi_dh)
- return;
-
- if (!scsi_dh)
- scsi_dh = sdev->scsi_dh_data->scsi_dh;
-
- if (scsi_dh)
- kref_put(&sdev->scsi_dh_data->kref, __detach_handler);
-}
-
-/*
- * Functions for sysfs attribute 'dh_state'
- */
-static ssize_t
-store_dh_state(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct scsi_device *sdev = to_scsi_device(dev);
- struct scsi_device_handler *scsi_dh;
- int err = -EINVAL;
-
- if (sdev->sdev_state == SDEV_CANCEL ||
- sdev->sdev_state == SDEV_DEL)
- return -ENODEV;
-
- if (!sdev->scsi_dh_data) {
- /*
- * Attach to a device handler
- */
- if (!(scsi_dh = get_device_handler(buf)))
- return err;
- err = scsi_dh_handler_attach(sdev, scsi_dh);
- } else {
- scsi_dh = sdev->scsi_dh_data->scsi_dh;
- if (!strncmp(buf, "detach", 6)) {
- /*
- * Detach from a device handler
- */
- scsi_dh_handler_detach(sdev, scsi_dh);
- err = 0;
- } else if (!strncmp(buf, "activate", 8)) {
- /*
- * Activate a device handler
- */
- if (scsi_dh->activate)
- err = scsi_dh->activate(sdev, NULL, NULL);
- else
- err = 0;
- }
- }
-
- return err<0?err:count;
-}
-
-static ssize_t
-show_dh_state(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct scsi_device *sdev = to_scsi_device(dev);
-
- if (!sdev->scsi_dh_data)
- return snprintf(buf, 20, "detached\n");
-
- return snprintf(buf, 20, "%s\n", sdev->scsi_dh_data->scsi_dh->name);
-}
-
-static struct device_attribute scsi_dh_state_attr =
- __ATTR(dh_state, S_IRUGO | S_IWUSR, show_dh_state,
- store_dh_state);
-
-/*
- * scsi_dh_sysfs_attr_add - Callback for scsi_init_dh
- */
-static int scsi_dh_sysfs_attr_add(struct device *dev, void *data)
-{
- struct scsi_device *sdev;
- int err;
-
- if (!scsi_is_sdev_device(dev))
- return 0;
-
- sdev = to_scsi_device(dev);
-
- err = device_create_file(&sdev->sdev_gendev,
- &scsi_dh_state_attr);
-
- return 0;
-}
-
-/*
- * scsi_dh_sysfs_attr_remove - Callback for scsi_exit_dh
- */
-static int scsi_dh_sysfs_attr_remove(struct device *dev, void *data)
-{
- struct scsi_device *sdev;
-
- if (!scsi_is_sdev_device(dev))
- return 0;
-
- sdev = to_scsi_device(dev);
-
- device_remove_file(&sdev->sdev_gendev,
- &scsi_dh_state_attr);
-
- return 0;
-}
-
-/*
- * scsi_dh_notifier - notifier chain callback
- */
-static int scsi_dh_notifier(struct notifier_block *nb,
- unsigned long action, void *data)
-{
- struct device *dev = data;
- struct scsi_device *sdev;
- int err = 0;
- struct scsi_device_handler *devinfo = NULL;
-
- if (!scsi_is_sdev_device(dev))
- return 0;
-
- sdev = to_scsi_device(dev);
-
- if (action == BUS_NOTIFY_ADD_DEVICE) {
- err = device_create_file(dev, &scsi_dh_state_attr);
- /* don't care about err */
- devinfo = device_handler_match(NULL, sdev);
- if (devinfo)
- err = scsi_dh_handler_attach(sdev, devinfo);
- } else if (action == BUS_NOTIFY_DEL_DEVICE) {
- device_remove_file(dev, &scsi_dh_state_attr);
- scsi_dh_handler_detach(sdev, NULL);
- }
- return err;
-}
-
-/*
- * scsi_dh_notifier_add - Callback for scsi_register_device_handler
- */
-static int scsi_dh_notifier_add(struct device *dev, void *data)
-{
- struct scsi_device_handler *scsi_dh = data;
- struct scsi_device *sdev;
-
- if (!scsi_is_sdev_device(dev))
- return 0;
-
- if (!get_device(dev))
- return 0;
-
- sdev = to_scsi_device(dev);
-
- if (device_handler_match(scsi_dh, sdev))
- scsi_dh_handler_attach(sdev, scsi_dh);
-
- put_device(dev);
-
- return 0;
-}
-
-/*
- * scsi_dh_notifier_remove - Callback for scsi_unregister_device_handler
- */
-static int scsi_dh_notifier_remove(struct device *dev, void *data)
-{
- struct scsi_device_handler *scsi_dh = data;
- struct scsi_device *sdev;
-
- if (!scsi_is_sdev_device(dev))
- return 0;
-
- if (!get_device(dev))
- return 0;
-
- sdev = to_scsi_device(dev);
-
- scsi_dh_handler_detach(sdev, scsi_dh);
-
- put_device(dev);
-
- return 0;
-}
-
-/*
- * scsi_register_device_handler - register a device handler personality
- * module.
- * @scsi_dh - device handler to be registered.
- *
- * Returns 0 on success, -EBUSY if handler already registered.
- */
-int scsi_register_device_handler(struct scsi_device_handler *scsi_dh)
-{
-
- if (get_device_handler(scsi_dh->name))
- return -EBUSY;
-
- if (!scsi_dh->attach || !scsi_dh->detach)
- return -EINVAL;
-
- spin_lock(&list_lock);
- list_add(&scsi_dh->list, &scsi_dh_list);
- spin_unlock(&list_lock);
-
- bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, scsi_dh_notifier_add);
- printk(KERN_INFO "%s: device handler registered\n", scsi_dh->name);
-
- return SCSI_DH_OK;
-}
-EXPORT_SYMBOL_GPL(scsi_register_device_handler);
-
-/*
- * scsi_unregister_device_handler - register a device handler personality
- * module.
- * @scsi_dh - device handler to be unregistered.
- *
- * Returns 0 on success, -ENODEV if handler not registered.
- */
-int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
-{
-
- if (!get_device_handler(scsi_dh->name))
- return -ENODEV;
-
- bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh,
- scsi_dh_notifier_remove);
-
- spin_lock(&list_lock);
- list_del(&scsi_dh->list);
- spin_unlock(&list_lock);
- printk(KERN_INFO "%s: device handler unregistered\n", scsi_dh->name);
-
- return SCSI_DH_OK;
-}
-EXPORT_SYMBOL_GPL(scsi_unregister_device_handler);
-
-/*
- * scsi_dh_activate - activate the path associated with the scsi_device
- * corresponding to the given request queue.
- * Returns immediately without waiting for activation to be completed.
- * @q - Request queue that is associated with the scsi_device to be
- * activated.
- * @fn - Function to be called upon completion of the activation.
- * Function fn is called with data (below) and the error code.
- * Function fn may be called from the same calling context. So,
- * do not hold the lock in the caller which may be needed in fn.
- * @data - data passed to the function fn upon completion.
- *
- */
-int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
-{
- int err = 0;
- unsigned long flags;
- struct scsi_device *sdev;
- struct scsi_device_handler *scsi_dh = NULL;
- struct device *dev = NULL;
-
- spin_lock_irqsave(q->queue_lock, flags);
- sdev = q->queuedata;
- if (!sdev) {
- spin_unlock_irqrestore(q->queue_lock, flags);
- err = SCSI_DH_NOSYS;
- if (fn)
- fn(data, err);
- return err;
- }
-
- if (sdev->scsi_dh_data)
- scsi_dh = sdev->scsi_dh_data->scsi_dh;
- dev = get_device(&sdev->sdev_gendev);
- if (!scsi_dh || !dev ||
- sdev->sdev_state == SDEV_CANCEL ||
- sdev->sdev_state == SDEV_DEL)
- err = SCSI_DH_NOSYS;
- if (sdev->sdev_state == SDEV_OFFLINE)
- err = SCSI_DH_DEV_OFFLINED;
- spin_unlock_irqrestore(q->queue_lock, flags);
-
- if (err) {
- if (fn)
- fn(data, err);
- goto out;
- }
-
- if (scsi_dh->activate)
- err = scsi_dh->activate(sdev, fn, data);
-out:
- put_device(dev);
- return err;
-}
-EXPORT_SYMBOL_GPL(scsi_dh_activate);
-
-/*
- * scsi_dh_set_params - set the parameters for the device as per the
- * string specified in params.
- * @q - Request queue that is associated with the scsi_device for
- * which the parameters to be set.
- * @params - parameters in the following format
- * "no_of_params\0param1\0param2\0param3\0...\0"
- * for example, string for 2 parameters with value 10 and 21
- * is specified as "2\010\021\0".
- */
-int scsi_dh_set_params(struct request_queue *q, const char *params)
-{
- int err = -SCSI_DH_NOSYS;
- unsigned long flags;
- struct scsi_device *sdev;
- struct scsi_device_handler *scsi_dh = NULL;
-
- spin_lock_irqsave(q->queue_lock, flags);
- sdev = q->queuedata;
- if (sdev && sdev->scsi_dh_data)
- scsi_dh = sdev->scsi_dh_data->scsi_dh;
- if (scsi_dh && scsi_dh->set_params && get_device(&sdev->sdev_gendev))
- err = 0;
- spin_unlock_irqrestore(q->queue_lock, flags);
-
- if (err)
- return err;
- err = scsi_dh->set_params(sdev, params);
- put_device(&sdev->sdev_gendev);
- return err;
-}
-EXPORT_SYMBOL_GPL(scsi_dh_set_params);
-
-/*
- * scsi_dh_handler_exist - Return TRUE(1) if a device handler exists for
- * the given name. FALSE(0) otherwise.
- * @name - name of the device handler.
- */
-int scsi_dh_handler_exist(const char *name)
-{
- return (get_device_handler(name) != NULL);
-}
-EXPORT_SYMBOL_GPL(scsi_dh_handler_exist);
-
-/*
- * scsi_dh_attach - Attach device handler
- * @q - Request queue that is associated with the scsi_device
- * the handler should be attached to
- * @name - name of the handler to attach
- */
-int scsi_dh_attach(struct request_queue *q, const char *name)
-{
- unsigned long flags;
- struct scsi_device *sdev;
- struct scsi_device_handler *scsi_dh;
- int err = 0;
-
- scsi_dh = get_device_handler(name);
- if (!scsi_dh)
- return -EINVAL;
-
- spin_lock_irqsave(q->queue_lock, flags);
- sdev = q->queuedata;
- if (!sdev || !get_device(&sdev->sdev_gendev))
- err = -ENODEV;
- spin_unlock_irqrestore(q->queue_lock, flags);
-
- if (!err) {
- err = scsi_dh_handler_attach(sdev, scsi_dh);
- put_device(&sdev->sdev_gendev);
- }
- return err;
-}
-EXPORT_SYMBOL_GPL(scsi_dh_attach);
-
-/*
- * scsi_dh_detach - Detach device handler
- * @q - Request queue that is associated with the scsi_device
- * the handler should be detached from
- *
- * This function will detach the device handler only
- * if the sdev is not part of the internal list, ie
- * if it has been attached manually.
- */
-void scsi_dh_detach(struct request_queue *q)
-{
- unsigned long flags;
- struct scsi_device *sdev;
- struct scsi_device_handler *scsi_dh = NULL;
-
- spin_lock_irqsave(q->queue_lock, flags);
- sdev = q->queuedata;
- if (!sdev || !get_device(&sdev->sdev_gendev))
- sdev = NULL;
- spin_unlock_irqrestore(q->queue_lock, flags);
-
- if (!sdev)
- return;
-
- if (sdev->scsi_dh_data) {
- scsi_dh = sdev->scsi_dh_data->scsi_dh;
- scsi_dh_handler_detach(sdev, scsi_dh);
- }
- put_device(&sdev->sdev_gendev);
-}
-EXPORT_SYMBOL_GPL(scsi_dh_detach);
-
-/*
- * scsi_dh_attached_handler_name - Get attached device handler's name
- * @q - Request queue that is associated with the scsi_device
- * that may have a device handler attached
- * @gfp - the GFP mask used in the kmalloc() call when allocating memory
- *
- * Returns name of attached handler, NULL if no handler is attached.
- * Caller must take care to free the returned string.
- */
-const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
-{
- unsigned long flags;
- struct scsi_device *sdev;
- const char *handler_name = NULL;
-
- spin_lock_irqsave(q->queue_lock, flags);
- sdev = q->queuedata;
- if (!sdev || !get_device(&sdev->sdev_gendev))
- sdev = NULL;
- spin_unlock_irqrestore(q->queue_lock, flags);
-
- if (!sdev)
- return NULL;
-
- if (sdev->scsi_dh_data)
- handler_name = kstrdup(sdev->scsi_dh_data->scsi_dh->name, gfp);
-
- put_device(&sdev->sdev_gendev);
- return handler_name;
-}
-EXPORT_SYMBOL_GPL(scsi_dh_attached_handler_name);
-
-static struct notifier_block scsi_dh_nb = {
- .notifier_call = scsi_dh_notifier
-};
-
-static int __init scsi_dh_init(void)
-{
- int r;
-
- r = bus_register_notifier(&scsi_bus_type, &scsi_dh_nb);
-
- if (!r)
- bus_for_each_dev(&scsi_bus_type, NULL, NULL,
- scsi_dh_sysfs_attr_add);
-
- return r;
-}
-
-static void __exit scsi_dh_exit(void)
-{
- bus_for_each_dev(&scsi_bus_type, NULL, NULL,
- scsi_dh_sysfs_attr_remove);
- bus_unregister_notifier(&scsi_bus_type, &scsi_dh_nb);
-}
-
-module_init(scsi_dh_init);
-module_exit(scsi_dh_exit);
-
-MODULE_DESCRIPTION("SCSI device handler");
-MODULE_AUTHOR("Chandra Seetharaman <sekharan@us.ibm.com>");
-MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/scsi/device_handler/scsi_dh_alua.c b/kernel/drivers/scsi/device_handler/scsi_dh_alua.c
index 854b568b9..cc2773b5d 100644
--- a/kernel/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/kernel/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -62,7 +62,6 @@
#define ALUA_OPTIMIZE_STPG 1
struct alua_dh_data {
- struct scsi_dh_data dh_data;
int group_id;
int rel_port;
int tpgs;
@@ -86,11 +85,6 @@ struct alua_dh_data {
static char print_alua_state(int);
static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
-static inline struct alua_dh_data *get_alua_data(struct scsi_device *sdev)
-{
- return container_of(sdev->scsi_dh_data, struct alua_dh_data, dh_data);
-}
-
static int realloc_buffer(struct alua_dh_data *h, unsigned len)
{
if (h->buff && h->buff != h->inq)
@@ -708,7 +702,7 @@ out:
*/
static int alua_set_params(struct scsi_device *sdev, const char *params)
{
- struct alua_dh_data *h = get_alua_data(sdev);
+ struct alua_dh_data *h = sdev->handler_data;
unsigned int optimize = 0, argc;
const char *p = params;
int result = SCSI_DH_OK;
@@ -746,7 +740,7 @@ MODULE_PARM_DESC(optimize_stpg, "Allow use of a non-optimized path, rather than
static int alua_activate(struct scsi_device *sdev,
activate_complete fn, void *data)
{
- struct alua_dh_data *h = get_alua_data(sdev);
+ struct alua_dh_data *h = sdev->handler_data;
int err = SCSI_DH_OK;
int stpg = 0;
@@ -804,7 +798,7 @@ out:
*/
static int alua_prep_fn(struct scsi_device *sdev, struct request *req)
{
- struct alua_dh_data *h = get_alua_data(sdev);
+ struct alua_dh_data *h = sdev->handler_data;
int ret = BLKPREP_OK;
if (h->state == TPGS_STATE_TRANSITIONING)
@@ -819,23 +813,18 @@ static int alua_prep_fn(struct scsi_device *sdev, struct request *req)
}
-static bool alua_match(struct scsi_device *sdev)
-{
- return (scsi_device_tpgs(sdev) != 0);
-}
-
/*
* alua_bus_attach - Attach device handler
* @sdev: device to be attached to
*/
-static struct scsi_dh_data *alua_bus_attach(struct scsi_device *sdev)
+static int alua_bus_attach(struct scsi_device *sdev)
{
struct alua_dh_data *h;
int err;
h = kzalloc(sizeof(*h) , GFP_KERNEL);
if (!h)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
h->tpgs = TPGS_MODE_UNINITIALIZED;
h->state = TPGS_STATE_OPTIMIZED;
h->group_id = -1;
@@ -848,11 +837,11 @@ static struct scsi_dh_data *alua_bus_attach(struct scsi_device *sdev)
if (err != SCSI_DH_OK && err != SCSI_DH_DEV_OFFLINED)
goto failed;
- sdev_printk(KERN_NOTICE, sdev, "%s: Attached\n", ALUA_DH_NAME);
- return &h->dh_data;
+ sdev->handler_data = h;
+ return 0;
failed:
kfree(h);
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
}
/*
@@ -861,10 +850,11 @@ failed:
*/
static void alua_bus_detach(struct scsi_device *sdev)
{
- struct alua_dh_data *h = get_alua_data(sdev);
+ struct alua_dh_data *h = sdev->handler_data;
if (h->buff && h->inq != h->buff)
kfree(h->buff);
+ sdev->handler_data = NULL;
kfree(h);
}
@@ -877,7 +867,6 @@ static struct scsi_device_handler alua_dh = {
.check_sense = alua_check_sense,
.activate = alua_activate,
.set_params = alua_set_params,
- .match = alua_match,
};
static int __init alua_init(void)
diff --git a/kernel/drivers/scsi/device_handler/scsi_dh_emc.c b/kernel/drivers/scsi/device_handler/scsi_dh_emc.c
index 6ed1caadb..e6fb97cb1 100644
--- a/kernel/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/kernel/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -72,7 +72,6 @@ static const char * lun_state[] =
};
struct clariion_dh_data {
- struct scsi_dh_data dh_data;
/*
* Flags:
* CLARIION_SHORT_TRESPASS
@@ -114,13 +113,6 @@ struct clariion_dh_data {
int current_sp;
};
-static inline struct clariion_dh_data
- *get_clariion_data(struct scsi_device *sdev)
-{
- return container_of(sdev->scsi_dh_data, struct clariion_dh_data,
- dh_data);
-}
-
/*
* Parse MODE_SELECT cmd reply.
*/
@@ -450,7 +442,7 @@ static int clariion_check_sense(struct scsi_device *sdev,
static int clariion_prep_fn(struct scsi_device *sdev, struct request *req)
{
- struct clariion_dh_data *h = get_clariion_data(sdev);
+ struct clariion_dh_data *h = sdev->handler_data;
int ret = BLKPREP_OK;
if (h->lun_state != CLARIION_LUN_OWNED) {
@@ -533,7 +525,7 @@ retry:
static int clariion_activate(struct scsi_device *sdev,
activate_complete fn, void *data)
{
- struct clariion_dh_data *csdev = get_clariion_data(sdev);
+ struct clariion_dh_data *csdev = sdev->handler_data;
int result;
result = clariion_send_inquiry(sdev, csdev);
@@ -574,7 +566,7 @@ done:
*/
static int clariion_set_params(struct scsi_device *sdev, const char *params)
{
- struct clariion_dh_data *csdev = get_clariion_data(sdev);
+ struct clariion_dh_data *csdev = sdev->handler_data;
unsigned int hr = 0, st = 0, argc;
const char *p = params;
int result = SCSI_DH_OK;
@@ -622,42 +614,14 @@ done:
return result;
}
-static const struct {
- char *vendor;
- char *model;
-} clariion_dev_list[] = {
- {"DGC", "RAID"},
- {"DGC", "DISK"},
- {"DGC", "VRAID"},
- {NULL, NULL},
-};
-
-static bool clariion_match(struct scsi_device *sdev)
-{
- int i;
-
- if (scsi_device_tpgs(sdev))
- return false;
-
- for (i = 0; clariion_dev_list[i].vendor; i++) {
- if (!strncmp(sdev->vendor, clariion_dev_list[i].vendor,
- strlen(clariion_dev_list[i].vendor)) &&
- !strncmp(sdev->model, clariion_dev_list[i].model,
- strlen(clariion_dev_list[i].model))) {
- return true;
- }
- }
- return false;
-}
-
-static struct scsi_dh_data *clariion_bus_attach(struct scsi_device *sdev)
+static int clariion_bus_attach(struct scsi_device *sdev)
{
struct clariion_dh_data *h;
int err;
h = kzalloc(sizeof(*h) , GFP_KERNEL);
if (!h)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
h->lun_state = CLARIION_LUN_UNINITIALIZED;
h->default_sp = CLARIION_UNBOUND_LU;
h->current_sp = CLARIION_UNBOUND_LU;
@@ -675,18 +639,19 @@ static struct scsi_dh_data *clariion_bus_attach(struct scsi_device *sdev)
CLARIION_NAME, h->current_sp + 'A',
h->port, lun_state[h->lun_state],
h->default_sp + 'A');
- return &h->dh_data;
+
+ sdev->handler_data = h;
+ return 0;
failed:
kfree(h);
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
}
static void clariion_bus_detach(struct scsi_device *sdev)
{
- struct clariion_dh_data *h = get_clariion_data(sdev);
-
- kfree(h);
+ kfree(sdev->handler_data);
+ sdev->handler_data = NULL;
}
static struct scsi_device_handler clariion_dh = {
@@ -698,7 +663,6 @@ static struct scsi_device_handler clariion_dh = {
.activate = clariion_activate,
.prep_fn = clariion_prep_fn,
.set_params = clariion_set_params,
- .match = clariion_match,
};
static int __init clariion_init(void)
diff --git a/kernel/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/kernel/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index 485d99544..9406d5f4a 100644
--- a/kernel/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/kernel/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -38,7 +38,6 @@
#define HP_SW_PATH_PASSIVE 1
struct hp_sw_dh_data {
- struct scsi_dh_data dh_data;
unsigned char sense[SCSI_SENSE_BUFFERSIZE];
int path_state;
int retries;
@@ -50,11 +49,6 @@ struct hp_sw_dh_data {
static int hp_sw_start_stop(struct hp_sw_dh_data *);
-static inline struct hp_sw_dh_data *get_hp_sw_data(struct scsi_device *sdev)
-{
- return container_of(sdev->scsi_dh_data, struct hp_sw_dh_data, dh_data);
-}
-
/*
* tur_done - Handle TEST UNIT READY return status
* @sdev: sdev the command has been sent to
@@ -267,7 +261,7 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req)
{
- struct hp_sw_dh_data *h = get_hp_sw_data(sdev);
+ struct hp_sw_dh_data *h = sdev->handler_data;
int ret = BLKPREP_OK;
if (h->path_state != HP_SW_PATH_ACTIVE) {
@@ -292,7 +286,7 @@ static int hp_sw_activate(struct scsi_device *sdev,
activate_complete fn, void *data)
{
int ret = SCSI_DH_OK;
- struct hp_sw_dh_data *h = get_hp_sw_data(sdev);
+ struct hp_sw_dh_data *h = sdev->handler_data;
ret = hp_sw_tur(sdev, h);
@@ -311,43 +305,14 @@ static int hp_sw_activate(struct scsi_device *sdev,
return 0;
}
-static const struct {
- char *vendor;
- char *model;
-} hp_sw_dh_data_list[] = {
- {"COMPAQ", "MSA1000 VOLUME"},
- {"COMPAQ", "HSV110"},
- {"HP", "HSV100"},
- {"DEC", "HSG80"},
- {NULL, NULL},
-};
-
-static bool hp_sw_match(struct scsi_device *sdev)
-{
- int i;
-
- if (scsi_device_tpgs(sdev))
- return false;
-
- for (i = 0; hp_sw_dh_data_list[i].vendor; i++) {
- if (!strncmp(sdev->vendor, hp_sw_dh_data_list[i].vendor,
- strlen(hp_sw_dh_data_list[i].vendor)) &&
- !strncmp(sdev->model, hp_sw_dh_data_list[i].model,
- strlen(hp_sw_dh_data_list[i].model))) {
- return true;
- }
- }
- return false;
-}
-
-static struct scsi_dh_data *hp_sw_bus_attach(struct scsi_device *sdev)
+static int hp_sw_bus_attach(struct scsi_device *sdev)
{
struct hp_sw_dh_data *h;
int ret;
h = kzalloc(sizeof(*h), GFP_KERNEL);
if (!h)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
h->path_state = HP_SW_PATH_UNINITIALIZED;
h->retries = HP_SW_RETRIES;
h->sdev = sdev;
@@ -359,17 +324,18 @@ static struct scsi_dh_data *hp_sw_bus_attach(struct scsi_device *sdev)
sdev_printk(KERN_INFO, sdev, "%s: attached to %s path\n",
HP_SW_NAME, h->path_state == HP_SW_PATH_ACTIVE?
"active":"passive");
- return &h->dh_data;
+
+ sdev->handler_data = h;
+ return 0;
failed:
kfree(h);
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
}
static void hp_sw_bus_detach( struct scsi_device *sdev )
{
- struct hp_sw_dh_data *h = get_hp_sw_data(sdev);
-
- kfree(h);
+ kfree(sdev->handler_data);
+ sdev->handler_data = NULL;
}
static struct scsi_device_handler hp_sw_dh = {
@@ -379,7 +345,6 @@ static struct scsi_device_handler hp_sw_dh = {
.detach = hp_sw_bus_detach,
.activate = hp_sw_activate,
.prep_fn = hp_sw_prep_fn,
- .match = hp_sw_match,
};
static int __init hp_sw_init(void)
diff --git a/kernel/drivers/scsi/device_handler/scsi_dh_rdac.c b/kernel/drivers/scsi/device_handler/scsi_dh_rdac.c
index b46ace3d4..93880ed62 100644
--- a/kernel/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/kernel/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -181,7 +181,6 @@ struct c2_inquiry {
};
struct rdac_dh_data {
- struct scsi_dh_data dh_data;
struct rdac_controller *ctlr;
#define UNINITIALIZED_LUN (1 << 8)
unsigned lun;
@@ -260,11 +259,6 @@ do { \
sdev_printk(KERN_INFO, sdev, RDAC_NAME ": " f "\n", ## arg); \
} while (0);
-static inline struct rdac_dh_data *get_rdac_data(struct scsi_device *sdev)
-{
- return container_of(sdev->scsi_dh_data, struct rdac_dh_data, dh_data);
-}
-
static struct request *get_rdac_req(struct scsi_device *sdev,
void *buffer, unsigned buflen, int rw)
{
@@ -544,7 +538,7 @@ static int mode_select_handle_sense(struct scsi_device *sdev,
{
struct scsi_sense_hdr sense_hdr;
int err = SCSI_DH_IO, ret;
- struct rdac_dh_data *h = get_rdac_data(sdev);
+ struct rdac_dh_data *h = sdev->handler_data;
ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
if (!ret)
@@ -568,7 +562,7 @@ static int mode_select_handle_sense(struct scsi_device *sdev,
/*
* Command Lock contention
*/
- err = SCSI_DH_RETRY;
+ err = SCSI_DH_IMM_RETRY;
break;
default:
break;
@@ -589,7 +583,7 @@ static void send_mode_select(struct work_struct *work)
container_of(work, struct rdac_controller, ms_work);
struct request *rq;
struct scsi_device *sdev = ctlr->ms_sdev;
- struct rdac_dh_data *h = get_rdac_data(sdev);
+ struct rdac_dh_data *h = sdev->handler_data;
struct request_queue *q = sdev->request_queue;
int err, retry_cnt = RDAC_RETRY_COUNT;
struct rdac_queue_data *tmp, *qdata;
@@ -618,6 +612,8 @@ retry:
err = mode_select_handle_sense(sdev, h->sense);
if (err == SCSI_DH_RETRY && retry_cnt--)
goto retry;
+ if (err == SCSI_DH_IMM_RETRY)
+ goto retry;
}
if (err == SCSI_DH_OK) {
h->state = RDAC_STATE_ACTIVE;
@@ -648,7 +644,7 @@ static int queue_mode_select(struct scsi_device *sdev,
if (!qdata)
return SCSI_DH_RETRY;
- qdata->h = get_rdac_data(sdev);
+ qdata->h = sdev->handler_data;
qdata->callback_fn = fn;
qdata->callback_data = data;
@@ -667,7 +663,7 @@ static int queue_mode_select(struct scsi_device *sdev,
static int rdac_activate(struct scsi_device *sdev,
activate_complete fn, void *data)
{
- struct rdac_dh_data *h = get_rdac_data(sdev);
+ struct rdac_dh_data *h = sdev->handler_data;
int err = SCSI_DH_OK;
int act = 0;
@@ -702,7 +698,7 @@ done:
static int rdac_prep_fn(struct scsi_device *sdev, struct request *req)
{
- struct rdac_dh_data *h = get_rdac_data(sdev);
+ struct rdac_dh_data *h = sdev->handler_data;
int ret = BLKPREP_OK;
if (h->state != RDAC_STATE_ACTIVE) {
@@ -716,7 +712,7 @@ static int rdac_prep_fn(struct scsi_device *sdev, struct request *req)
static int rdac_check_sense(struct scsi_device *sdev,
struct scsi_sense_hdr *sense_hdr)
{
- struct rdac_dh_data *h = get_rdac_data(sdev);
+ struct rdac_dh_data *h = sdev->handler_data;
RDAC_LOG(RDAC_LOG_SENSE, sdev, "array %s, ctlr %d, "
"I/O returned with sense %02x/%02x/%02x",
@@ -778,56 +774,7 @@ static int rdac_check_sense(struct scsi_device *sdev,
return SCSI_RETURN_NOT_HANDLED;
}
-static const struct {
- char *vendor;
- char *model;
-} rdac_dev_list[] = {
- {"IBM", "1722"},
- {"IBM", "1724"},
- {"IBM", "1726"},
- {"IBM", "1742"},
- {"IBM", "1745"},
- {"IBM", "1746"},
- {"IBM", "1813"},
- {"IBM", "1814"},
- {"IBM", "1815"},
- {"IBM", "1818"},
- {"IBM", "3526"},
- {"SGI", "TP9"},
- {"SGI", "IS"},
- {"STK", "OPENstorage D280"},
- {"STK", "FLEXLINE 380"},
- {"SUN", "CSM"},
- {"SUN", "LCSM100"},
- {"SUN", "STK6580_6780"},
- {"SUN", "SUN_6180"},
- {"SUN", "ArrayStorage"},
- {"DELL", "MD3"},
- {"NETAPP", "INF-01-00"},
- {"LSI", "INF-01-00"},
- {"ENGENIO", "INF-01-00"},
- {NULL, NULL},
-};
-
-static bool rdac_match(struct scsi_device *sdev)
-{
- int i;
-
- if (scsi_device_tpgs(sdev))
- return false;
-
- for (i = 0; rdac_dev_list[i].vendor; i++) {
- if (!strncmp(sdev->vendor, rdac_dev_list[i].vendor,
- strlen(rdac_dev_list[i].vendor)) &&
- !strncmp(sdev->model, rdac_dev_list[i].model,
- strlen(rdac_dev_list[i].model))) {
- return true;
- }
- }
- return false;
-}
-
-static struct scsi_dh_data *rdac_bus_attach(struct scsi_device *sdev)
+static int rdac_bus_attach(struct scsi_device *sdev)
{
struct rdac_dh_data *h;
int err;
@@ -836,7 +783,7 @@ static struct scsi_dh_data *rdac_bus_attach(struct scsi_device *sdev)
h = kzalloc(sizeof(*h) , GFP_KERNEL);
if (!h)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
h->lun = UNINITIALIZED_LUN;
h->state = RDAC_STATE_ACTIVE;
@@ -861,7 +808,8 @@ static struct scsi_dh_data *rdac_bus_attach(struct scsi_device *sdev)
RDAC_NAME, h->lun, mode[(int)h->mode],
lun_state[(int)h->lun_state]);
- return &h->dh_data;
+ sdev->handler_data = h;
+ return 0;
clean_ctlr:
spin_lock(&list_lock);
@@ -870,12 +818,12 @@ clean_ctlr:
failed:
kfree(h);
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
}
static void rdac_bus_detach( struct scsi_device *sdev )
{
- struct rdac_dh_data *h = get_rdac_data(sdev);
+ struct rdac_dh_data *h = sdev->handler_data;
if (h->ctlr && h->ctlr->ms_queued)
flush_workqueue(kmpath_rdacd);
@@ -884,6 +832,7 @@ static void rdac_bus_detach( struct scsi_device *sdev )
if (h->ctlr)
kref_put(&h->ctlr->kref, release_controller);
spin_unlock(&list_lock);
+ sdev->handler_data = NULL;
kfree(h);
}
@@ -895,7 +844,6 @@ static struct scsi_device_handler rdac_dh = {
.attach = rdac_bus_attach,
.detach = rdac_bus_detach,
.activate = rdac_activate,
- .match = rdac_match,
};
static int __init rdac_init(void)