Re: [PATCH 9/9] scsi_dh: Add NetApp hardware handler

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



One question: If a lun goes to the passive state, how does it get back
to active ? There is no code to set the state back.

On Tue, 2008-06-24 at 12:05 +0200, Hannes Reinecke wrote:
> NetApp specific hardware handler to filter out vendor-specific
> sense code.
> 
> Signed-off-by: Martin George <marting@xxxxxxxxxx>
> Signed-off-by: Hannes Reinecke <hare@xxxxxxx>
> ---
>  drivers/scsi/device_handler/Kconfig         |    6 +
>  drivers/scsi/device_handler/Makefile        |    1 +
>  drivers/scsi/device_handler/scsi_dh_ontap.c |  157 +++++++++++++++++++++++++++
>  3 files changed, 164 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/scsi/device_handler/scsi_dh_ontap.c
> 
> diff --git a/drivers/scsi/device_handler/Kconfig b/drivers/scsi/device_handler/Kconfig
> index 6707025..841e0e4 100644
> --- a/drivers/scsi/device_handler/Kconfig
> +++ b/drivers/scsi/device_handler/Kconfig
> @@ -31,6 +31,12 @@ config SCSI_DH_EMC
>  	help
>  	If you have a EMC CLARiiON select y. Otherwise, say N.
> 
> +config SCSI_DH_ONTAP
> +	tristate "NetApp Device Handler"
> +	depends on SCSI_DH
> +	help
> +	If you have a NetApp controller select y. Otherwise, say N.
> +
>  config SCSI_DH_ALUA
>  	tristate "SPC-3 ALUA Device Handler (EXPERIMENTAL)"
>  	depends on SCSI_DH && EXPERIMENTAL
> diff --git a/drivers/scsi/device_handler/Makefile b/drivers/scsi/device_handler/Makefile
> index e1d2ea0..abfb9db 100644
> --- a/drivers/scsi/device_handler/Makefile
> +++ b/drivers/scsi/device_handler/Makefile
> @@ -5,4 +5,5 @@ 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
> +obj-$(CONFIG_SCSI_DH_ONTAP)	+= scsi_dh_ontap.o
>  obj-$(CONFIG_SCSI_DH_ALUA)	+= scsi_dh_alua.o
> diff --git a/drivers/scsi/device_handler/scsi_dh_ontap.c b/drivers/scsi/device_handler/scsi_dh_ontap.c
> new file mode 100644
> index 0000000..175d657
> --- /dev/null
> +++ b/drivers/scsi/device_handler/scsi_dh_ontap.c
> @@ -0,0 +1,157 @@
> +/*
> + * Copyright 2008 NetApp, Inc., All Rights Reserved
> + * Author:  Martin George available at marting@xxxxxxxxxx
> + *
> + * This file is released under the GPL.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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 v2 for more details.
> + */
> +
> +#include <scsi/scsi.h>
> +#include <scsi/scsi_eh.h>
> +#include <scsi/scsi_dh.h>
> +
> +#define ONTAP_NAME			"ontap"
> +
> +#define ONTAP_STATE_ACTIVE		0
> +#define ONTAP_STATE_PASSIVE		1
> +
> +struct ontap_dh_data {
> +	/* To add more members here later */
> +	unsigned char			state;
> +};
> +
> +static inline struct ontap_dh_data *get_ontap_data(struct scsi_device *sdev)
> +{
> +	struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data;
> +
> +	BUG_ON(scsi_dh_data == NULL);
> +	return ((struct ontap_dh_data *) scsi_dh_data->buf);
> +}
> +
> +static int ontap_prep_fn(struct scsi_device *sdev, struct request *req)
> +{
> +	struct ontap_dh_data *h = get_ontap_data(sdev);
> +	int ret = BLKPREP_OK;
> +
> +	if (h->state != ONTAP_STATE_ACTIVE) {
> +		ret = BLKPREP_KILL;
> +		req->cmd_flags |= REQ_QUIET;
> +	}
> +	return ret;
> +}
> +
> +static int ontap_check_sense(struct scsi_device *sdev,
> +				struct scsi_sense_hdr *sense_hdr)
> +{
> +	struct ontap_dh_data *h = get_ontap_data(sdev);
> +
> +	switch (sense_hdr->sense_key) {
> +	case HARDWARE_ERROR:
> +		if (sense_hdr->asc == 0x5D && sense_hdr->ascq == 0x12) {
> +			/* Failed write on NetApp controller
> +                         * Fail the IO */
> +			h->state = ONTAP_STATE_PASSIVE;
> +			return FAILED;
> +		}
> +		break;
> +	}
> +
> +	/* Do not care what scsi-ml does */
> +	return SCSI_RETURN_NOT_HANDLED;
> +}
> +
> +const struct scsi_dh_devlist ontap_dev_list[] = {
> +	{"NETAPP", "LUN"},
> +	{NULL, NULL},
> +};
> +
> +static int ontap_bus_attach(struct scsi_device *sdev);
> +static void ontap_bus_detach(struct scsi_device *sdev);
> +
> +static struct scsi_device_handler ontap_dh = {
> +	.name		= ONTAP_NAME,
> +	.module		= THIS_MODULE,
> +	.devlist	= ontap_dev_list,
> +	.attach		= ontap_bus_attach,
> +	.detach		= ontap_bus_detach,
> +	.check_sense	= ontap_check_sense,
> +	.prep_fn	= ontap_prep_fn,
> +};
> +
> +static int ontap_bus_attach(struct scsi_device *sdev)
> +{
> +	struct scsi_dh_data *scsi_dh_data;
> +	struct ontap_dh_data *h;
> +	unsigned long flags;
> +	int i, found = 0;
> +
> +	scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *)
> +			       + sizeof(*h) , GFP_KERNEL);
> +	if (!scsi_dh_data) {
> +		sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n",
> +			    ONTAP_NAME);
> +		return -ENOMEM;
> +	}
> +
> +	scsi_dh_data->scsi_dh = &ontap_dh;
> +	h = (struct ontap_dh_data *) scsi_dh_data->buf;
> +	h->state = ONTAP_STATE_ACTIVE;
> +
> +	spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
> +	sdev->scsi_dh_data = scsi_dh_data;
> +	spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
> +
> +	sdev_printk(KERN_NOTICE, sdev, "Attached %s.\n", ONTAP_NAME);
> +
> +	try_module_get(THIS_MODULE);
> +
> +	return 0;
> +}
> +
> +static void ontap_bus_detach(struct scsi_device *sdev)
> +{
> +	struct scsi_dh_data *scsi_dh_data;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
> +	scsi_dh_data = sdev->scsi_dh_data;
> +	sdev->scsi_dh_data = NULL;
> +	spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
> +
> +	sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n",
> +		    ONTAP_NAME);
> +
> +	kfree(scsi_dh_data);
> +	module_put(THIS_MODULE);
> +}
> +
> +static int __init ontap_init(void)
> +{
> +	int r;
> +
> +	r = scsi_register_device_handler(&ontap_dh);
> +	if (r != 0)
> +		printk(KERN_ERR "%s: Failed to register scsi device handler.",
> +			ONTAP_NAME);
> +	return r;
> +}
> +
> +static void __exit ontap_exit(void)
> +{
> +	scsi_unregister_device_handler(&ontap_dh);
> +}
> +
> +module_init(ontap_init);
> +module_exit(ontap_exit);
> +
> +MODULE_DESCRIPTION("NetApp controller driver");
> +MODULE_AUTHOR("Martin George <marting@xxxxxxxxxx>");
> +MODULE_LICENSE("GPL");

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux