staging: unisys: remove virthba driver for rewrite
authorBenjamin Romer <benjamin.romer@unisys.com>
Tue, 14 Apr 2015 01:16:49 +0000 (21:16 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Apr 2015 14:36:50 +0000 (16:36 +0200)
The virthba driver is being rewritten and will be renamed to visorhba, so delete
the old driver from the source tree.

Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Reviewed-by: Don Zickus <dzickus@redhat.com>
Reviewed-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/unisys/Kconfig
drivers/staging/unisys/Makefile
drivers/staging/unisys/virthba/Kconfig [deleted file]
drivers/staging/unisys/virthba/Makefile [deleted file]
drivers/staging/unisys/virthba/virthba.c [deleted file]
drivers/staging/unisys/virthba/virthba.h [deleted file]

index 19fcb34655093a4c2ea5f202267c7f9af3abff5d..906cd589048d8a2b9d35785640f999082250ec4a 100644 (file)
@@ -14,6 +14,5 @@ source "drivers/staging/unisys/visorchannel/Kconfig"
 source "drivers/staging/unisys/visorchipset/Kconfig"
 source "drivers/staging/unisys/uislib/Kconfig"
 source "drivers/staging/unisys/virtpci/Kconfig"
-source "drivers/staging/unisys/virthba/Kconfig"
 
 endif # UNISYSSPAR
index 68b9925e7d5eb3cf4a8936a849245a13d070a4bb..3283a013d0c687a5aa5d60b2bfdd1b628aca8977 100644 (file)
@@ -6,4 +6,3 @@ obj-$(CONFIG_UNISYS_VISORCHANNEL)       += visorchannel/
 obj-$(CONFIG_UNISYS_VISORCHIPSET)      += visorchipset/
 obj-$(CONFIG_UNISYS_UISLIB)            += uislib/
 obj-$(CONFIG_UNISYS_VIRTPCI)           += virtpci/
-obj-$(CONFIG_UNISYS_VIRTHBA)           += virthba/
diff --git a/drivers/staging/unisys/virthba/Kconfig b/drivers/staging/unisys/virthba/Kconfig
deleted file mode 100644 (file)
index dfadfc4..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Unisys virthba configuration
-#
-
-config UNISYS_VIRTHBA
-       tristate "Unisys virthba driver"
-       depends on SCSI
-       select UNISYS_VISORCHIPSET
-       select UNISYS_UISLIB
-       select UNISYS_VIRTPCI
-       ---help---
-       If you say Y here, you will enable the Unisys virthba driver.
-
diff --git a/drivers/staging/unisys/virthba/Makefile b/drivers/staging/unisys/virthba/Makefile
deleted file mode 100644 (file)
index a4e4037..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for Unisys virthba
-#
-
-obj-$(CONFIG_UNISYS_VIRTHBA)   += virthba.o
-
-ccflags-y += -Idrivers/staging/unisys/include
-ccflags-y += -Idrivers/staging/unisys/uislib
-ccflags-y += -Idrivers/staging/unisys/visorchipset
-ccflags-y += -Idrivers/staging/unisys/virtpci
-ccflags-y += -Idrivers/staging/unisys/common-spar/include
-ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels
diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c
deleted file mode 100644 (file)
index d9001cc..0000000
+++ /dev/null
@@ -1,1572 +0,0 @@
-/* virthba.c
- *
- * Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- */
-
-#define EXPORT_SYMTAB
-
-/* if you want to turn on some debugging of write device data or read
- * device data, define these two undefs.  You will probably want to
- * customize the code which is here since it was written assuming
- * reading and writing a specific data file df.64M.txt which is a
- * 64Megabyte file created by Art Nilson using a scritp I wrote called
- * cr_test_data.pl.  The data file consists of 256 byte lines of text
- * which start with an 8 digit sequence number, a colon, and then
- * letters after that */
-
-#include <linux/kernel.h>
-#ifdef CONFIG_MODVERSIONS
-#include <config/modversions.h>
-#endif
-
-#include "diagnostics/appos_subsystems.h"
-#include "uisutils.h"
-#include "uisqueue.h"
-#include "uisthread.h"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <asm/param.h>
-#include <linux/debugfs.h>
-#include <linux/types.h>
-
-#include "virthba.h"
-#include "virtpci.h"
-#include "visorchipset.h"
-#include "version.h"
-#include "guestlinuxdebug.h"
-/* this is shorter than using __FILE__ (full path name) in
- * debug/info/error messages
- */
-#define CURRENT_FILE_PC VIRT_HBA_PC_virthba_c
-#define __MYFILE__ "virthba.c"
-
-/* NOTE:  L1_CACHE_BYTES >=128 */
-#define DEVICE_ATTRIBUTE struct device_attribute
-
- /* MAX_BUF = 6 lines x 10 MAXVHBA x 80 characters
- *         = 4800 bytes ~ 2^13 = 8192 bytes
- */
-#define MAX_BUF 8192
-
-/*****************************************************/
-/* Forward declarations                              */
-/*****************************************************/
-static int virthba_probe(struct virtpci_dev *dev,
-                        const struct pci_device_id *id);
-static void virthba_remove(struct virtpci_dev *dev);
-static int virthba_abort_handler(struct scsi_cmnd *scsicmd);
-static int virthba_bus_reset_handler(struct scsi_cmnd *scsicmd);
-static int virthba_device_reset_handler(struct scsi_cmnd *scsicmd);
-static int virthba_host_reset_handler(struct scsi_cmnd *scsicmd);
-static const char *virthba_get_info(struct Scsi_Host *shp);
-static int virthba_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
-static int virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
-                                    void (*virthba_cmnd_done)
-                                          (struct scsi_cmnd *));
-
-static const struct x86_cpu_id unisys_spar_ids[] = {
-       { X86_VENDOR_INTEL, 6, 62, X86_FEATURE_ANY },
-       {}
-};
-
-/* Autoload */
-MODULE_DEVICE_TABLE(x86cpu, unisys_spar_ids);
-
-#ifdef DEF_SCSI_QCMD
-static DEF_SCSI_QCMD(virthba_queue_command)
-#else
-#define virthba_queue_command virthba_queue_command_lck
-#endif
-
-static int virthba_slave_alloc(struct scsi_device *scsidev);
-static int virthba_slave_configure(struct scsi_device *scsidev);
-static void virthba_slave_destroy(struct scsi_device *scsidev);
-static int process_incoming_rsps(void *);
-static int virthba_serverup(struct virtpci_dev *virtpcidev);
-static int virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state);
-static void do_disk_add_remove(struct work_struct *work);
-static void virthba_serverdown_complete(struct work_struct *work);
-static ssize_t info_debugfs_read(struct file *file, char __user *buf,
-                                size_t len, loff_t *offset);
-static ssize_t enable_ints_write(struct file *file,
-                                const char __user *buffer, size_t count,
-                                loff_t *ppos);
-
-/*****************************************************/
-/* Globals                                           */
-/*****************************************************/
-
-static int rsltq_wait_usecs = 4000;    /* Default 4ms */
-static unsigned int max_buff_len;
-
-/* Module options */
-static char *virthba_options = "NONE";
-
-static const struct pci_device_id virthba_id_table[] = {
-       {PCI_DEVICE(PCI_VENDOR_ID_UNISYS, PCI_DEVICE_ID_VIRTHBA)},
-       {0},
-};
-
-/* export virthba_id_table */
-MODULE_DEVICE_TABLE(pci, virthba_id_table);
-
-static struct workqueue_struct *virthba_serverdown_workqueue;
-
-static struct virtpci_driver virthba_driver = {
-       .name = "uisvirthba",
-       .version = VERSION,
-       .vertag = NULL,
-       .id_table = virthba_id_table,
-       .probe = virthba_probe,
-       .remove = virthba_remove,
-       .resume = virthba_serverup,
-       .suspend = virthba_serverdown
-};
-
-/* The Send and Recive Buffers of the IO Queue may both be full */
-#define MAX_PENDING_REQUESTS (MIN_NUMSIGNALS*2)
-#define INTERRUPT_VECTOR_MASK 0x3F
-
-struct scsipending {
-       char cmdtype;           /* Type of pointer that is being stored */
-       void *sent;             /* The Data being tracked */
-       /* struct scsi_cmnd *type for virthba_queue_command */
-       /* struct uiscmdrsp *type for management commands */
-};
-
-#define VIRTHBA_ERROR_COUNT 30
-#define IOS_ERROR_THRESHOLD 1000
-struct virtdisk_info {
-       u32 valid;
-       u32 channel, id, lun;   /* Disk Path */
-       atomic_t ios_threshold;
-       atomic_t error_count;
-       struct virtdisk_info *next;
-};
-
-/* Each Scsi_Host has a host_data area that contains this struct. */
-struct virthba_info {
-       struct Scsi_Host *scsihost;
-       struct virtpci_dev *virtpcidev;
-       struct list_head dev_info_list;
-       struct chaninfo chinfo;
-       struct irq_info intr;           /* use recvInterrupt info to receive
-                                          interrupts when IOs complete */
-       int interrupt_vector;
-       struct scsipending pending[MAX_PENDING_REQUESTS]; /* Tracks the requests
-                                                            that have been */
-       /* forwarded to the IOVM and haven't returned yet */
-       unsigned int nextinsert;        /* Start search for next pending
-                                          free slot here */
-       spinlock_t privlock;
-       bool serverdown;
-       bool serverchangingstate;
-       unsigned long long acquire_failed_cnt;
-       unsigned long long interrupts_rcvd;
-       unsigned long long interrupts_notme;
-       unsigned long long interrupts_disabled;
-       struct work_struct serverdown_completion;
-       u64 __iomem *flags_addr;
-       atomic_t interrupt_rcvd;
-       wait_queue_head_t rsp_queue;
-       struct virtdisk_info head;
-};
-
-/* Work Data for dar_work_queue */
-struct diskaddremove {
-       u8 add;                 /* 0-remove, 1-add */
-       struct Scsi_Host *shost; /* Scsi Host for this virthba instance */
-       u32 channel, id, lun;   /* Disk Path */
-       struct diskaddremove *next;
-};
-
-#define virtpci_dev_to_virthba_virthba_get_info(d) \
-       container_of(d, struct virthba_info, virtpcidev)
-
-static DEVICE_ATTRIBUTE *virthba_shost_attrs[];
-static struct scsi_host_template virthba_driver_template = {
-       .name = "Unisys Virtual HBA",
-       .info = virthba_get_info,
-       .ioctl = virthba_ioctl,
-       .queuecommand = virthba_queue_command,
-       .eh_abort_handler = virthba_abort_handler,
-       .eh_device_reset_handler = virthba_device_reset_handler,
-       .eh_bus_reset_handler = virthba_bus_reset_handler,
-       .eh_host_reset_handler = virthba_host_reset_handler,
-       .shost_attrs = virthba_shost_attrs,
-
-#define VIRTHBA_MAX_CMNDS 128
-       .can_queue = VIRTHBA_MAX_CMNDS,
-       .sg_tablesize = 64,     /* largest number of address/length pairs */
-       .this_id = -1,
-       .slave_alloc = virthba_slave_alloc,
-       .slave_configure = virthba_slave_configure,
-       .slave_destroy = virthba_slave_destroy,
-       .use_clustering = ENABLE_CLUSTERING,
-};
-
-struct virthba_devices_open {
-       struct virthba_info *virthbainfo;
-};
-
-static const struct file_operations debugfs_info_fops = {
-       .read = info_debugfs_read,
-};
-
-static const struct file_operations debugfs_enable_ints_fops = {
-       .write = enable_ints_write,
-};
-
-/*****************************************************/
-/* Structs                                           */
-/*****************************************************/
-
-#define VIRTHBASOPENMAX 1
-/* array of open devices maintained by open() and close(); */
-static struct virthba_devices_open virthbas_open[VIRTHBASOPENMAX];
-static struct dentry *virthba_debugfs_dir;
-
-/*****************************************************/
-/* Local Functions                                  */
-/*****************************************************/
-static int
-add_scsipending_entry(struct virthba_info *vhbainfo, char cmdtype, void *new)
-{
-       unsigned long flags;
-       int insert_location;
-
-       spin_lock_irqsave(&vhbainfo->privlock, flags);
-       insert_location = vhbainfo->nextinsert;
-       while (vhbainfo->pending[insert_location].sent) {
-               insert_location = (insert_location + 1) % MAX_PENDING_REQUESTS;
-               if (insert_location == (int)vhbainfo->nextinsert) {
-                       spin_unlock_irqrestore(&vhbainfo->privlock, flags);
-                       return -1;
-               }
-       }
-
-       vhbainfo->pending[insert_location].cmdtype = cmdtype;
-       vhbainfo->pending[insert_location].sent = new;
-       vhbainfo->nextinsert = (insert_location + 1) % MAX_PENDING_REQUESTS;
-       spin_unlock_irqrestore(&vhbainfo->privlock, flags);
-
-       return insert_location;
-}
-
-static unsigned int
-add_scsipending_entry_with_wait(struct virthba_info *vhbainfo, char cmdtype,
-                               void *new)
-{
-       int insert_location = add_scsipending_entry(vhbainfo, cmdtype, new);
-
-       while (insert_location == -1) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(msecs_to_jiffies(10));
-               insert_location = add_scsipending_entry(vhbainfo, cmdtype, new);
-       }
-
-       return (unsigned int)insert_location;
-}
-
-static void *
-del_scsipending_entry(struct virthba_info *vhbainfo, uintptr_t del)
-{
-       unsigned long flags;
-       void *sent = NULL;
-
-       if (del < MAX_PENDING_REQUESTS) {
-               spin_lock_irqsave(&vhbainfo->privlock, flags);
-               sent = vhbainfo->pending[del].sent;
-
-               vhbainfo->pending[del].cmdtype = 0;
-               vhbainfo->pending[del].sent = NULL;
-               spin_unlock_irqrestore(&vhbainfo->privlock, flags);
-       }
-
-       return sent;
-}
-
-/* dar_work_queue (Disk Add/Remove) */
-static struct work_struct dar_work_queue;
-static struct diskaddremove *dar_work_queue_head;
-static spinlock_t dar_work_queue_lock;
-static unsigned short dar_work_queue_sched;
-#define QUEUE_DISKADDREMOVE(dar) { \
-       spin_lock_irqsave(&dar_work_queue_lock, flags); \
-       if (!dar_work_queue_head) { \
-               dar_work_queue_head = dar; \
-               dar->next = NULL; \
-       } \
-       else { \
-               dar->next = dar_work_queue_head; \
-               dar_work_queue_head = dar; \
-       } \
-       if (!dar_work_queue_sched) { \
-               schedule_work(&dar_work_queue); \
-               dar_work_queue_sched = 1; \
-       } \
-       spin_unlock_irqrestore(&dar_work_queue_lock, flags); \
-}
-
-static inline void
-send_disk_add_remove(struct diskaddremove *dar)
-{
-       struct scsi_device *sdev;
-       int error;
-
-       sdev = scsi_device_lookup(dar->shost, dar->channel, dar->id, dar->lun);
-       if (sdev) {
-               if (!(dar->add))
-                       scsi_remove_device(sdev);
-       } else if (dar->add) {
-               error =
-                   scsi_add_device(dar->shost, dar->channel, dar->id,
-                                   dar->lun);
-       }
-       kfree(dar);
-}
-
-/*****************************************************/
-/* dar_work_queue Handler Thread                     */
-/*****************************************************/
-static void
-do_disk_add_remove(struct work_struct *work)
-{
-       struct diskaddremove *dar;
-       struct diskaddremove *tmphead;
-       int i = 0;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dar_work_queue_lock, flags);
-       tmphead = dar_work_queue_head;
-       dar_work_queue_head = NULL;
-       dar_work_queue_sched = 0;
-       spin_unlock_irqrestore(&dar_work_queue_lock, flags);
-       while (tmphead) {
-               dar = tmphead;
-               tmphead = dar->next;
-               send_disk_add_remove(dar);
-               i++;
-       }
-}
-
-/*****************************************************/
-/* Routine to add entry to dar_work_queue            */
-/*****************************************************/
-static void
-process_disk_notify(struct Scsi_Host *shost, struct uiscmdrsp *cmdrsp)
-{
-       struct diskaddremove *dar;
-       unsigned long flags;
-
-       dar = kzalloc(sizeof(*dar), GFP_ATOMIC);
-       if (dar) {
-               dar->add = cmdrsp->disknotify.add;
-               dar->shost = shost;
-               dar->channel = cmdrsp->disknotify.channel;
-               dar->id = cmdrsp->disknotify.id;
-               dar->lun = cmdrsp->disknotify.lun;
-               QUEUE_DISKADDREMOVE(dar);
-       }
-}
-
-/*****************************************************/
-/* Probe Remove Functions                            */
-/*****************************************************/
-static irqreturn_t
-virthba_isr(int irq, void *dev_id)
-{
-       struct virthba_info *virthbainfo = (struct virthba_info *)dev_id;
-       struct channel_header __iomem *channel_header;
-       struct signal_queue_header __iomem *pqhdr;
-       u64 mask;
-       unsigned long long rc1;
-
-       if (!virthbainfo)
-               return IRQ_NONE;
-       virthbainfo->interrupts_rcvd++;
-       channel_header = virthbainfo->chinfo.queueinfo->chan;
-       if (((readq(&channel_header->features)
-             & ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS) != 0) &&
-            ((readq(&channel_header->features) &
-                ULTRA_IO_DRIVER_DISABLES_INTS) !=
-               0)) {
-               virthbainfo->interrupts_disabled++;
-               mask = ~ULTRA_CHANNEL_ENABLE_INTS;
-               rc1 = uisqueue_interlocked_and(virthbainfo->flags_addr, mask);
-       }
-       if (spar_signalqueue_empty(channel_header, IOCHAN_FROM_IOPART)) {
-               virthbainfo->interrupts_notme++;
-               return IRQ_NONE;
-       }
-       pqhdr = (struct signal_queue_header __iomem *)
-               ((char __iomem *)channel_header +
-                readq(&channel_header->ch_space_offset)) + IOCHAN_FROM_IOPART;
-       writeq(readq(&pqhdr->num_irq_received) + 1,
-              &pqhdr->num_irq_received);
-       atomic_set(&virthbainfo->interrupt_rcvd, 1);
-       wake_up_interruptible(&virthbainfo->rsp_queue);
-       return IRQ_HANDLED;
-}
-
-static int
-virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
-{
-       int error;
-       struct Scsi_Host *scsihost;
-       struct virthba_info *virthbainfo;
-       int rsp;
-       int i;
-       irq_handler_t handler = virthba_isr;
-       struct channel_header __iomem *channel_header;
-       struct signal_queue_header __iomem *pqhdr;
-       u64 mask;
-
-       POSTCODE_LINUX_2(VHBA_PROBE_ENTRY_PC, POSTCODE_SEVERITY_INFO);
-       /* call scsi_host_alloc to register a scsi host adapter
-        * instance - this virthba that has just been created is an
-        * instance of a scsi host adapter. This scsi_host_alloc
-        * function allocates a new Scsi_Host struct & performs basic
-        * initialization.  The host is not published to the scsi
-        * midlayer until scsi_add_host is called.
-        */
-
-       /* arg 2 passed in length of extra space we want allocated
-        * with scsi_host struct for our own use scsi_host_alloc
-        * assign host_no
-        */
-       scsihost = scsi_host_alloc(&virthba_driver_template,
-                                  sizeof(struct virthba_info));
-       if (!scsihost)
-               return -ENODEV;
-
-       scsihost->this_id = UIS_MAGIC_VHBA;
-       /* linux treats max-channel differently than max-id & max-lun.
-        * In the latter cases, those two values result in 0 to max-1
-        * (inclusive) being scanned. But in the case of channels, the
-        * scan is 0 to max (inclusive); so we will subtract one from
-        * the max-channel value.
-        */
-       scsihost->max_channel = (unsigned)virtpcidev->scsi.max.max_channel;
-       scsihost->max_id = (unsigned)virtpcidev->scsi.max.max_id;
-       scsihost->max_lun = (unsigned)virtpcidev->scsi.max.max_lun;
-       scsihost->cmd_per_lun = (unsigned)virtpcidev->scsi.max.cmd_per_lun;
-       scsihost->max_sectors =
-           (unsigned short)(virtpcidev->scsi.max.max_io_size >> 9);
-       scsihost->sg_tablesize =
-           (unsigned short)(virtpcidev->scsi.max.max_io_size / PAGE_SIZE);
-       if (scsihost->sg_tablesize > MAX_PHYS_INFO)
-               scsihost->sg_tablesize = MAX_PHYS_INFO;
-
-       /* this creates "host%d" in sysfs.  If 2nd argument is NULL,
-        * then this generic /sys/devices/platform/host?  device is
-        * created and /sys/scsi_host/host? ->
-        * /sys/devices/platform/host?  If 2nd argument is not NULL,
-        * then this generic /sys/devices/<path>/host? is created and
-        * host? points to that device instead.
-        */
-       error = scsi_add_host(scsihost, &virtpcidev->generic_dev);
-       if (error) {
-               POSTCODE_LINUX_2(VHBA_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR);
-               /* decr refcount on scsihost which was incremented by
-                * scsi_add_host so the scsi_host gets deleted
-                */
-               scsi_host_put(scsihost);
-               return -ENODEV;
-       }
-
-       virthbainfo = (struct virthba_info *)scsihost->hostdata;
-       memset(virthbainfo, 0, sizeof(struct virthba_info));
-       for (i = 0; i < VIRTHBASOPENMAX; i++) {
-               if (!virthbas_open[i].virthbainfo) {
-                       virthbas_open[i].virthbainfo = virthbainfo;
-                       break;
-               }
-       }
-       virthbainfo->interrupt_vector = -1;
-       virthbainfo->chinfo.queueinfo = &virtpcidev->queueinfo;
-       virthbainfo->virtpcidev = virtpcidev;
-       spin_lock_init(&virthbainfo->chinfo.insertlock);
-
-       init_waitqueue_head(&virthbainfo->rsp_queue);
-       spin_lock_init(&virthbainfo->privlock);
-       memset(&virthbainfo->pending, 0, sizeof(virthbainfo->pending));
-       virthbainfo->serverdown = false;
-       virthbainfo->serverchangingstate = false;
-
-       virthbainfo->intr = virtpcidev->intr;
-       /* save of host within virthba_info */
-       virthbainfo->scsihost = scsihost;
-
-       /* save of host within virtpci_dev */
-       virtpcidev->scsi.scsihost = scsihost;
-
-       /* Setup workqueue for serverdown messages */
-       INIT_WORK(&virthbainfo->serverdown_completion,
-                 virthba_serverdown_complete);
-
-       writeq(readq(&virthbainfo->chinfo.queueinfo->chan->features) |
-              ULTRA_IO_CHANNEL_IS_POLLING,
-              &virthbainfo->chinfo.queueinfo->chan->features);
-       /* start thread that will receive scsicmnd responses */
-
-       channel_header = virthbainfo->chinfo.queueinfo->chan;
-       pqhdr = (struct signal_queue_header __iomem *)
-               ((char __iomem *)channel_header +
-                readq(&channel_header->ch_space_offset)) + IOCHAN_FROM_IOPART;
-       virthbainfo->flags_addr = &pqhdr->features;
-
-       if (!uisthread_start(&virthbainfo->chinfo.threadinfo,
-                            process_incoming_rsps,
-                            virthbainfo, "vhba_incoming")) {
-               /* decr refcount on scsihost which was incremented by
-                * scsi_add_host so the scsi_host gets deleted
-                */
-               POSTCODE_LINUX_2(VHBA_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR);
-               scsi_host_put(scsihost);
-               return -ENODEV;
-       }
-       virthbainfo->interrupt_vector =
-           virthbainfo->intr.recv_irq_handle & INTERRUPT_VECTOR_MASK;
-       rsp = request_irq(virthbainfo->interrupt_vector, handler, IRQF_SHARED,
-                         scsihost->hostt->name, virthbainfo);
-       if (rsp != 0) {
-               virthbainfo->interrupt_vector = -1;
-               POSTCODE_LINUX_2(VHBA_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR);
-       } else {
-               u64 __iomem *features_addr =
-                   &virthbainfo->chinfo.queueinfo->chan->features;
-               mask = ~(ULTRA_IO_CHANNEL_IS_POLLING |
-                        ULTRA_IO_DRIVER_DISABLES_INTS);
-               uisqueue_interlocked_and(features_addr, mask);
-               mask = ULTRA_IO_DRIVER_ENABLES_INTS;
-               uisqueue_interlocked_or(features_addr, mask);
-               rsltq_wait_usecs = 4000000;
-       }
-
-       scsi_scan_host(scsihost);
-
-       POSTCODE_LINUX_2(VHBA_PROBE_EXIT_PC, POSTCODE_SEVERITY_INFO);
-       return 0;
-}
-
-static void
-virthba_remove(struct virtpci_dev *virtpcidev)
-{
-       struct virthba_info *virthbainfo;
-       struct Scsi_Host *scsihost =
-           (struct Scsi_Host *)virtpcidev->scsi.scsihost;
-
-       virthbainfo = (struct virthba_info *)scsihost->hostdata;
-       if (virthbainfo->interrupt_vector != -1)
-               free_irq(virthbainfo->interrupt_vector, virthbainfo);
-
-       scsi_remove_host(scsihost);
-
-       uisthread_stop(&virthbainfo->chinfo.threadinfo);
-
-       /* decr refcount on scsihost which was incremented by
-        * scsi_add_host so the scsi_host gets deleted
-        */
-       scsi_host_put(scsihost);
-}
-
-static int
-forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype,
-                         struct Scsi_Host *scsihost,
-                         struct uisscsi_dest *vdest)
-{
-       struct uiscmdrsp *cmdrsp;
-       struct virthba_info *virthbainfo =
-           (struct virthba_info *)scsihost->hostdata;
-       int notifyresult = 0xffff;
-       wait_queue_head_t notifyevent;
-
-       if (virthbainfo->serverdown || virthbainfo->serverchangingstate)
-               return FAILED;
-
-       cmdrsp = kzalloc(SIZEOF_CMDRSP, GFP_ATOMIC);
-       if (!cmdrsp)
-               return FAILED;  /* reject */
-
-       init_waitqueue_head(&notifyevent);
-
-       /* issue VDISK_MGMT_CMD
-        * set type to command - as opposed to task mgmt
-        */
-       cmdrsp->cmdtype = CMD_VDISKMGMT_TYPE;
-       /* specify the event that has to be triggered when this cmd is
-        * complete
-        */
-       cmdrsp->vdiskmgmt.notify = (void *)&notifyevent;
-       cmdrsp->vdiskmgmt.notifyresult = (void *)&notifyresult;
-
-       /* save destination */
-       cmdrsp->vdiskmgmt.vdisktype = vdiskcmdtype;
-       cmdrsp->vdiskmgmt.vdest.channel = vdest->channel;
-       cmdrsp->vdiskmgmt.vdest.id = vdest->id;
-       cmdrsp->vdiskmgmt.vdest.lun = vdest->lun;
-       cmdrsp->vdiskmgmt.scsicmd =
-           (void *)(uintptr_t)
-               add_scsipending_entry_with_wait(virthbainfo, CMD_VDISKMGMT_TYPE,
-                                               (void *)cmdrsp);
-
-       uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
-                                            cmdrsp, IOCHAN_TO_IOPART,
-                                            &virthbainfo->chinfo.insertlock,
-                                            DONT_ISSUE_INTERRUPT, (u64)NULL,
-                                            OK_TO_WAIT, "vhba");
-       wait_event(notifyevent, notifyresult != 0xffff);
-       kfree(cmdrsp);
-       return SUCCESS;
-}
-
-/*****************************************************/
-/* Scsi Host support functions                       */
-/*****************************************************/
-
-static int
-forward_taskmgmt_command(enum task_mgmt_types tasktype,
-                        struct scsi_device *scsidev)
-{
-       struct uiscmdrsp *cmdrsp;
-       struct virthba_info *virthbainfo =
-           (struct virthba_info *)scsidev->host->hostdata;
-       int notifyresult = 0xffff;
-       wait_queue_head_t notifyevent;
-
-       if (virthbainfo->serverdown || virthbainfo->serverchangingstate)
-               return FAILED;
-
-       cmdrsp = kzalloc(SIZEOF_CMDRSP, GFP_ATOMIC);
-       if (!cmdrsp)
-               return FAILED;  /* reject */
-
-       init_waitqueue_head(&notifyevent);
-
-       /* issue TASK_MGMT_ABORT_TASK */
-       /* set type to command - as opposed to task mgmt */
-       cmdrsp->cmdtype = CMD_SCSITASKMGMT_TYPE;
-       /* specify the event that has to be triggered when this */
-       /* cmd is complete */
-       cmdrsp->scsitaskmgmt.notify = (void *)&notifyevent;
-       cmdrsp->scsitaskmgmt.notifyresult = (void *)&notifyresult;
-
-       /* save destination */
-       cmdrsp->scsitaskmgmt.tasktype = tasktype;
-       cmdrsp->scsitaskmgmt.vdest.channel = scsidev->channel;
-       cmdrsp->scsitaskmgmt.vdest.id = scsidev->id;
-       cmdrsp->scsitaskmgmt.vdest.lun = scsidev->lun;
-       cmdrsp->scsitaskmgmt.scsicmd =
-           (void *)(uintptr_t)
-               add_scsipending_entry_with_wait(virthbainfo,
-                                               CMD_SCSITASKMGMT_TYPE,
-                                               (void *)cmdrsp);
-
-       uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
-                                            cmdrsp, IOCHAN_TO_IOPART,
-                                            &virthbainfo->chinfo.insertlock,
-                                            DONT_ISSUE_INTERRUPT, (u64)NULL,
-                                            OK_TO_WAIT, "vhba");
-       wait_event(notifyevent, notifyresult != 0xffff);
-       kfree(cmdrsp);
-       return SUCCESS;
-}
-
-/* The abort handler returns SUCCESS if it has succeeded to make LLDD
- * and all related hardware forget about the scmd.
- */
-static int
-virthba_abort_handler(struct scsi_cmnd *scsicmd)
-{
-       /* issue TASK_MGMT_ABORT_TASK */
-       struct scsi_device *scsidev;
-       struct virtdisk_info *vdisk;
-
-       scsidev = scsicmd->device;
-       for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
-            vdisk->next; vdisk = vdisk->next) {
-               if ((scsidev->channel == vdisk->channel) &&
-                   (scsidev->id == vdisk->id) &&
-                   (scsidev->lun == vdisk->lun)) {
-                       if (atomic_read(&vdisk->error_count) <
-                           VIRTHBA_ERROR_COUNT) {
-                               atomic_inc(&vdisk->error_count);
-                               POSTCODE_LINUX_2(VHBA_COMMAND_HANDLER_PC,
-                                                POSTCODE_SEVERITY_INFO);
-                       } else
-                               atomic_set(&vdisk->ios_threshold,
-                                          IOS_ERROR_THRESHOLD);
-               }
-       }
-       return forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsicmd->device);
-}
-
-static int
-virthba_bus_reset_handler(struct scsi_cmnd *scsicmd)
-{
-       /* issue TASK_MGMT_TARGET_RESET for each target on the bus */
-       struct scsi_device *scsidev;
-       struct virtdisk_info *vdisk;
-
-       scsidev = scsicmd->device;
-       for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
-            vdisk->next; vdisk = vdisk->next) {
-               if ((scsidev->channel == vdisk->channel) &&
-                   (scsidev->id == vdisk->id) &&
-                   (scsidev->lun == vdisk->lun)) {
-                       if (atomic_read(&vdisk->error_count) <
-                           VIRTHBA_ERROR_COUNT) {
-                               atomic_inc(&vdisk->error_count);
-                               POSTCODE_LINUX_2(VHBA_COMMAND_HANDLER_PC,
-                                                POSTCODE_SEVERITY_INFO);
-                       } else
-                               atomic_set(&vdisk->ios_threshold,
-                                          IOS_ERROR_THRESHOLD);
-               }
-       }
-       return forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsicmd->device);
-}
-
-static int
-virthba_device_reset_handler(struct scsi_cmnd *scsicmd)
-{
-       /* issue TASK_MGMT_LUN_RESET */
-       struct scsi_device *scsidev;
-       struct virtdisk_info *vdisk;
-
-       scsidev = scsicmd->device;
-       for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
-            vdisk->next; vdisk = vdisk->next) {
-               if ((scsidev->channel == vdisk->channel) &&
-                   (scsidev->id == vdisk->id) &&
-                   (scsidev->lun == vdisk->lun)) {
-                       if (atomic_read(&vdisk->error_count) <
-                           VIRTHBA_ERROR_COUNT) {
-                               atomic_inc(&vdisk->error_count);
-                               POSTCODE_LINUX_2(VHBA_COMMAND_HANDLER_PC,
-                                                POSTCODE_SEVERITY_INFO);
-                       } else
-                               atomic_set(&vdisk->ios_threshold,
-                                          IOS_ERROR_THRESHOLD);
-               }
-       }
-       return forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsicmd->device);
-}
-
-static int
-virthba_host_reset_handler(struct scsi_cmnd *scsicmd)
-{
-       /* issue TASK_MGMT_TARGET_RESET for each target on each bus for host */
-       return SUCCESS;
-}
-
-static char virthba_get_info_str[256];
-
-static const char *
-virthba_get_info(struct Scsi_Host *shp)
-{
-       /* Return version string */
-       sprintf(virthba_get_info_str, "virthba, version %s\n", VIRTHBA_VERSION);
-       return virthba_get_info_str;
-}
-
-static int
-virthba_ioctl(struct scsi_device *dev, int cmd, void __user *arg)
-{
-       return -EINVAL;
-}
-
-/* This returns SCSI_MLQUEUE_DEVICE_BUSY if the signal queue to IOpart
- * is full.
- */
-static int
-virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
-                         void (*virthba_cmnd_done)(struct scsi_cmnd *))
-{
-       struct scsi_device *scsidev = scsicmd->device;
-       int insert_location;
-       unsigned char op;
-       unsigned char *cdb = scsicmd->cmnd;
-       struct Scsi_Host *scsihost = scsidev->host;
-       struct uiscmdrsp *cmdrsp;
-       unsigned int i;
-       struct virthba_info *virthbainfo =
-           (struct virthba_info *)scsihost->hostdata;
-       struct scatterlist *sg = NULL;
-       struct scatterlist *sgl = NULL;
-       int sg_failed = 0;
-
-       if (virthbainfo->serverdown || virthbainfo->serverchangingstate)
-               return SCSI_MLQUEUE_DEVICE_BUSY;
-       cmdrsp = kzalloc(SIZEOF_CMDRSP, GFP_ATOMIC);
-       if (!cmdrsp)
-               return 1;       /* reject the command */
-
-       /* now saving everything we need from scsi_cmd into cmdrsp
-        * before we queue cmdrsp set type to command - as opposed to
-        * task mgmt
-        */
-       cmdrsp->cmdtype = CMD_SCSI_TYPE;
-       /* save the pending insertion location.  Deletion from pending
-        * will return the scsicmd pointer for completion
-        */
-       insert_location =
-           add_scsipending_entry(virthbainfo, CMD_SCSI_TYPE, (void *)scsicmd);
-       if (insert_location != -1) {
-               cmdrsp->scsi.scsicmd = (void *)(uintptr_t)insert_location;
-       } else {
-               kfree(cmdrsp);
-               return SCSI_MLQUEUE_DEVICE_BUSY;
-       }
-       /* save done function that we have call when cmd is complete */
-       scsicmd->scsi_done = virthba_cmnd_done;
-       /* save destination */
-       cmdrsp->scsi.vdest.channel = scsidev->channel;
-       cmdrsp->scsi.vdest.id = scsidev->id;
-       cmdrsp->scsi.vdest.lun = scsidev->lun;
-       /* save datadir */
-       cmdrsp->scsi.data_dir = scsicmd->sc_data_direction;
-       memcpy(cmdrsp->scsi.cmnd, cdb, MAX_CMND_SIZE);
-
-       cmdrsp->scsi.bufflen = scsi_bufflen(scsicmd);
-
-       /* keep track of the max buffer length so far. */
-       if (cmdrsp->scsi.bufflen > max_buff_len)
-               max_buff_len = cmdrsp->scsi.bufflen;
-
-       if (scsi_sg_count(scsicmd) > MAX_PHYS_INFO) {
-               del_scsipending_entry(virthbainfo, (uintptr_t)insert_location);
-               kfree(cmdrsp);
-               return 1;       /* reject the command */
-       }
-
-       /* This is what we USED to do when we assumed we were running */
-       /* uissd & virthba on the same Linux system. */
-       /* cmdrsp->scsi.buffer = scsicmd->request_buffer; */
-       /* The following code does NOT make that assumption. */
-       /* convert buffer to phys information */
-       if (scsi_sg_count(scsicmd) == 0) {
-               if (scsi_bufflen(scsicmd) > 0) {
-                       BUG_ON(scsi_sg_count(scsicmd) == 0);
-               }
-       } else {
-               /* buffer is scatterlist - copy it out */
-               sgl = scsi_sglist(scsicmd);
-
-               for_each_sg(sgl, sg, scsi_sg_count(scsicmd), i) {
-                       cmdrsp->scsi.gpi_list[i].address = sg_phys(sg);
-                       cmdrsp->scsi.gpi_list[i].length = sg->length;
-               }
-
-               if (sg_failed) {
-                       /* BUG(); ***** For now, let it fail in uissd
-                        * if it is a problem, as it might just
-                        * work
-                        */
-               }
-
-               cmdrsp->scsi.guest_phys_entries = scsi_sg_count(scsicmd);
-       }
-
-       op = cdb[0];
-       i = uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
-                                                cmdrsp, IOCHAN_TO_IOPART,
-                                                &virthbainfo->chinfo.
-                                                insertlock,
-                                                DONT_ISSUE_INTERRUPT,
-                                                (u64)NULL, DONT_WAIT, "vhba");
-       if (i == 0) {
-               /* queue must be full - and we said don't wait - return busy */
-               kfree(cmdrsp);
-               del_scsipending_entry(virthbainfo, (uintptr_t)insert_location);
-               return SCSI_MLQUEUE_DEVICE_BUSY;
-       }
-
-       /* we're done with cmdrsp space - data from it has been copied
-        * into channel - free it now.
-        */
-       kfree(cmdrsp);
-       return 0;               /* non-zero implies host/device is busy */
-}
-
-static int
-virthba_slave_alloc(struct scsi_device *scsidev)
-{
-       /* this called by the midlayer before scan for new devices -
-        * LLD can alloc any struct & do init if needed.
-        */
-       struct virtdisk_info *vdisk;
-       struct virtdisk_info *tmpvdisk;
-       struct virthba_info *virthbainfo;
-       struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
-
-       virthbainfo = (struct virthba_info *)scsihost->hostdata;
-       if (!virthbainfo)
-               return 0;       /* even though we errored, treat as success */
-
-       for (vdisk = &virthbainfo->head; vdisk->next; vdisk = vdisk->next) {
-               if (vdisk->next->valid &&
-                   (vdisk->next->channel == scsidev->channel) &&
-                   (vdisk->next->id == scsidev->id) &&
-                   (vdisk->next->lun == scsidev->lun))
-                       return 0;
-       }
-       tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC);
-       if (!tmpvdisk)
-               return 0;
-
-       tmpvdisk->channel = scsidev->channel;
-       tmpvdisk->id = scsidev->id;
-       tmpvdisk->lun = scsidev->lun;
-       tmpvdisk->valid = 1;
-       vdisk->next = tmpvdisk;
-       return 0;               /* success */
-}
-
-static int
-virthba_slave_configure(struct scsi_device *scsidev)
-{
-       return 0;               /* success */
-}
-
-static void
-virthba_slave_destroy(struct scsi_device *scsidev)
-{
-       /* midlevel calls this after device has been quiesced and
-        * before it is to be deleted.
-        */
-       struct virtdisk_info *vdisk, *delvdisk;
-       struct virthba_info *virthbainfo;
-       struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
-
-       virthbainfo = (struct virthba_info *)scsihost->hostdata;
-       for (vdisk = &virthbainfo->head; vdisk->next; vdisk = vdisk->next) {
-               if (vdisk->next->valid &&
-                   (vdisk->next->channel == scsidev->channel) &&
-                   (vdisk->next->id == scsidev->id) &&
-                   (vdisk->next->lun == scsidev->lun)) {
-                       delvdisk = vdisk->next;
-                       vdisk->next = vdisk->next->next;
-                       kfree(delvdisk);
-                       return;
-               }
-       }
-}
-
-/*****************************************************/
-/* Scsi Cmnd support thread                          */
-/*****************************************************/
-
-static void
-do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
-{
-       struct virtdisk_info *vdisk;
-       struct scsi_device *scsidev;
-       struct sense_data *sd;
-
-       scsidev = scsicmd->device;
-       memcpy(scsicmd->sense_buffer, cmdrsp->scsi.sensebuf, MAX_SENSE_SIZE);
-       sd = (struct sense_data *)scsicmd->sense_buffer;
-
-       /* Do not log errors for disk-not-present inquiries */
-       if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
-           (host_byte(cmdrsp->scsi.linuxstat) == DID_NO_CONNECT) &&
-           (cmdrsp->scsi.addlstat == ADDL_SEL_TIMEOUT))
-               return;
-
-       /* Okay see what our error_count is here.... */
-       for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
-            vdisk->next; vdisk = vdisk->next) {
-               if ((scsidev->channel != vdisk->channel) ||
-                   (scsidev->id != vdisk->id) ||
-                   (scsidev->lun != vdisk->lun))
-                       continue;
-
-               if (atomic_read(&vdisk->error_count) < VIRTHBA_ERROR_COUNT) {
-                       atomic_inc(&vdisk->error_count);
-                       atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
-               }
-       }
-}
-
-static void
-do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
-{
-       struct scsi_device *scsidev;
-       unsigned char buf[36];
-       struct scatterlist *sg;
-       unsigned int i;
-       char *thispage;
-       char *thispage_orig;
-       int bufind = 0;
-       struct virtdisk_info *vdisk;
-
-       scsidev = scsicmd->device;
-       if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
-           (cmdrsp->scsi.bufflen >= MIN_INQUIRY_RESULT_LEN)) {
-               if (cmdrsp->scsi.no_disk_result == 0)
-                       return;
-
-               /* Linux scsi code is weird; it wants
-                * a device at Lun 0 to issue report
-                * luns, but we don't want a disk
-                * there so we'll present a processor
-                * there. */
-               SET_NO_DISK_INQUIRY_RESULT(buf, cmdrsp->scsi.bufflen,
-                                          scsidev->lun,
-                                          DEV_DISK_CAPABLE_NOT_PRESENT,
-                                          DEV_NOT_CAPABLE);
-
-               if (scsi_sg_count(scsicmd) == 0) {
-                       if (scsi_bufflen(scsicmd) > 0) {
-                               BUG_ON(scsi_sg_count(scsicmd) ==
-                                      0);
-                       }
-                       memcpy(scsi_sglist(scsicmd), buf,
-                              cmdrsp->scsi.bufflen);
-                       return;
-               }
-
-               sg = scsi_sglist(scsicmd);
-               for (i = 0; i < scsi_sg_count(scsicmd); i++) {
-                       thispage_orig = kmap_atomic(sg_page(sg + i));
-                       thispage = (void *)((unsigned long)thispage_orig |
-                                            sg[i].offset);
-                       memcpy(thispage, buf + bufind, sg[i].length);
-                       kunmap_atomic(thispage_orig);
-                       bufind += sg[i].length;
-               }
-       } else {
-               vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
-               for ( ; vdisk->next; vdisk = vdisk->next) {
-                       if ((scsidev->channel != vdisk->channel) ||
-                           (scsidev->id != vdisk->id) ||
-                           (scsidev->lun != vdisk->lun))
-                               continue;
-
-                       if (atomic_read(&vdisk->ios_threshold) > 0) {
-                               atomic_dec(&vdisk->ios_threshold);
-                               if (atomic_read(&vdisk->ios_threshold) == 0) {
-                                       atomic_set(&vdisk->error_count, 0);
-                               }
-                       }
-               }
-       }
-}
-
-static void
-complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
-{
-       /* take what we need out of cmdrsp and complete the scsicmd */
-       scsicmd->result = cmdrsp->scsi.linuxstat;
-       if (cmdrsp->scsi.linuxstat)
-               do_scsi_linuxstat(cmdrsp, scsicmd);
-       else
-               do_scsi_nolinuxstat(cmdrsp, scsicmd);
-
-       if (scsicmd->scsi_done)
-               scsicmd->scsi_done(scsicmd);
-}
-
-static inline void
-complete_vdiskmgmt_command(struct uiscmdrsp *cmdrsp)
-{
-       /* copy the result of the taskmgmt and */
-       /* wake up the error handler that is waiting for this */
-       *(int *)cmdrsp->vdiskmgmt.notifyresult = cmdrsp->vdiskmgmt.result;
-       wake_up_all((wait_queue_head_t *)cmdrsp->vdiskmgmt.notify);
-}
-
-static inline void
-complete_taskmgmt_command(struct uiscmdrsp *cmdrsp)
-{
-       /* copy the result of the taskmgmt and */
-       /* wake up the error handler that is waiting for this */
-       *(int *)cmdrsp->scsitaskmgmt.notifyresult =
-           cmdrsp->scsitaskmgmt.result;
-       wake_up_all((wait_queue_head_t *)cmdrsp->scsitaskmgmt.notify);
-}
-
-static void
-drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc,
-           struct uiscmdrsp *cmdrsp)
-{
-       unsigned long flags;
-       int qrslt = 0;
-       struct scsi_cmnd *scsicmd;
-       struct Scsi_Host *shost = virthbainfo->scsihost;
-
-       while (1) {
-               spin_lock_irqsave(&virthbainfo->chinfo.insertlock, flags);
-               if (!spar_channel_client_acquire_os(dc->queueinfo->chan,
-                                                   "vhba")) {
-                       spin_unlock_irqrestore(&virthbainfo->chinfo.insertlock,
-                                              flags);
-                       virthbainfo->acquire_failed_cnt++;
-                       break;
-               }
-               qrslt = uisqueue_get_cmdrsp(dc->queueinfo, cmdrsp,
-                                           IOCHAN_FROM_IOPART);
-               spar_channel_client_release_os(dc->queueinfo->chan, "vhba");
-               spin_unlock_irqrestore(&virthbainfo->chinfo.insertlock, flags);
-               if (qrslt == 0)
-                       break;
-               if (cmdrsp->cmdtype == CMD_SCSI_TYPE) {
-                       /* scsicmd location is returned by the
-                        * deletion
-                        */
-                       scsicmd = del_scsipending_entry(virthbainfo,
-                                                       (uintptr_t)
-                                                        cmdrsp->scsi.scsicmd);
-                       if (!scsicmd)
-                               break;
-                       /* complete the orig cmd */
-                       complete_scsi_command(cmdrsp, scsicmd);
-               } else if (cmdrsp->cmdtype == CMD_SCSITASKMGMT_TYPE) {
-                       if (!del_scsipending_entry(virthbainfo,
-                                  (uintptr_t)cmdrsp->scsitaskmgmt.scsicmd))
-                               break;
-                       complete_taskmgmt_command(cmdrsp);
-               } else if (cmdrsp->cmdtype == CMD_NOTIFYGUEST_TYPE) {
-                       /* The vHba pointer has no meaning in
-                        * a Client/Guest Partition. Let's be
-                        * safe and set it to NULL now.  Do
-                        * not use it here! */
-                       cmdrsp->disknotify.v_hba = NULL;
-                       process_disk_notify(shost, cmdrsp);
-               } else if (cmdrsp->cmdtype == CMD_VDISKMGMT_TYPE) {
-                       if (!del_scsipending_entry(virthbainfo,
-                                                  (uintptr_t)
-                                                   cmdrsp->vdiskmgmt.scsicmd))
-                               break;
-                       complete_vdiskmgmt_command(cmdrsp);
-               }
-               /* cmdrsp is now available for reuse */
-       }
-}
-
-/* main function for the thread that waits for scsi commands to arrive
- * in a specified queue
- */
-static int
-process_incoming_rsps(void *v)
-{
-       struct virthba_info *virthbainfo = v;
-       struct chaninfo *dc = &virthbainfo->chinfo;
-       struct uiscmdrsp *cmdrsp = NULL;
-       const int SZ = sizeof(struct uiscmdrsp);
-       u64 mask;
-       unsigned long long rc1;
-
-       UIS_DAEMONIZE("vhba_incoming");
-       /* alloc once and reuse */
-       cmdrsp = kmalloc(SZ, GFP_ATOMIC);
-       if (!cmdrsp) {
-               complete_and_exit(&dc->threadinfo.has_stopped, 0);
-               return 0;
-       }
-       mask = ULTRA_CHANNEL_ENABLE_INTS;
-       while (1) {
-               if (kthread_should_stop())
-                       break;
-               wait_event_interruptible_timeout(virthbainfo->rsp_queue,
-                        (atomic_read(&virthbainfo->interrupt_rcvd) == 1),
-                                     usecs_to_jiffies(rsltq_wait_usecs));
-               atomic_set(&virthbainfo->interrupt_rcvd, 0);
-               /* drain queue */
-               drain_queue(virthbainfo, dc, cmdrsp);
-               rc1 = uisqueue_interlocked_or(virthbainfo->flags_addr, mask);
-       }
-
-       kfree(cmdrsp);
-
-       complete_and_exit(&dc->threadinfo.has_stopped, 0);
-}
-
-/*****************************************************/
-/* Debugfs filesystem functions                      */
-/*****************************************************/
-
-static ssize_t info_debugfs_read(struct file *file,
-                                char __user *buf, size_t len, loff_t *offset)
-{
-       ssize_t bytes_read = 0;
-       int str_pos = 0;
-       u64 phys_flags_addr;
-       int i;
-       struct virthba_info *virthbainfo;
-       char *vbuf;
-
-       if (len > MAX_BUF)
-               len = MAX_BUF;
-       vbuf = kzalloc(len, GFP_KERNEL);
-       if (!vbuf)
-               return -ENOMEM;
-
-       for (i = 0; i < VIRTHBASOPENMAX; i++) {
-               if (!virthbas_open[i].virthbainfo)
-                       continue;
-
-               virthbainfo = virthbas_open[i].virthbainfo;
-
-               str_pos += scnprintf(vbuf + str_pos,
-                               len - str_pos, "max_buff_len:%u\n",
-                               max_buff_len);
-
-               str_pos += scnprintf(vbuf + str_pos, len - str_pos,
-                               "\nvirthba result queue poll wait:%d usecs.\n",
-                               rsltq_wait_usecs);
-               str_pos += scnprintf(vbuf + str_pos, len - str_pos,
-                               "\ninterrupts_rcvd = %llu, interrupts_disabled = %llu\n",
-                               virthbainfo->interrupts_rcvd,
-                               virthbainfo->interrupts_disabled);
-               str_pos += scnprintf(vbuf + str_pos,
-                               len - str_pos, "\ninterrupts_notme = %llu,\n",
-                               virthbainfo->interrupts_notme);
-               phys_flags_addr = virt_to_phys((__force  void *)
-                                              virthbainfo->flags_addr);
-               str_pos += scnprintf(vbuf + str_pos, len - str_pos,
-                               "flags_addr = %p, phys_flags_addr=0x%016llx, FeatureFlags=%llu\n",
-                               virthbainfo->flags_addr, phys_flags_addr,
-                               (__le64)readq(virthbainfo->flags_addr));
-               str_pos += scnprintf(vbuf + str_pos,
-                       len - str_pos, "acquire_failed_cnt:%llu\n",
-                       virthbainfo->acquire_failed_cnt);
-               str_pos += scnprintf(vbuf + str_pos, len - str_pos, "\n");
-       }
-
-       bytes_read = simple_read_from_buffer(buf, len, offset, vbuf, str_pos);
-       kfree(vbuf);
-       return bytes_read;
-}
-
-static ssize_t enable_ints_write(struct file *file, const char __user *buffer,
-                                size_t count, loff_t *ppos)
-{
-       char buf[4];
-       int i, new_value;
-       struct virthba_info *virthbainfo;
-
-       u64 __iomem *features_addr;
-       u64 mask;
-
-       if (count >= ARRAY_SIZE(buf))
-               return -EINVAL;
-
-       buf[count] = '\0';
-       if (copy_from_user(buf, buffer, count))
-               return -EFAULT;
-
-       i = kstrtoint(buf, 10, &new_value);
-
-       if (i != 0)
-               return -EFAULT;
-
-       /* set all counts to new_value usually 0 */
-       for (i = 0; i < VIRTHBASOPENMAX; i++) {
-               if (virthbas_open[i].virthbainfo) {
-                       virthbainfo = virthbas_open[i].virthbainfo;
-                       features_addr =
-                               &virthbainfo->chinfo.queueinfo->chan->features;
-                       if (new_value == 1) {
-                               mask = ~(ULTRA_IO_CHANNEL_IS_POLLING |
-                                        ULTRA_IO_DRIVER_DISABLES_INTS);
-                               uisqueue_interlocked_and(features_addr, mask);
-                               mask = ULTRA_IO_DRIVER_ENABLES_INTS;
-                               uisqueue_interlocked_or(features_addr, mask);
-                               rsltq_wait_usecs = 4000000;
-                       } else {
-                               mask = ~(ULTRA_IO_DRIVER_ENABLES_INTS |
-                                        ULTRA_IO_DRIVER_DISABLES_INTS);
-                               uisqueue_interlocked_and(features_addr, mask);
-                               mask = ULTRA_IO_CHANNEL_IS_POLLING;
-                               uisqueue_interlocked_or(features_addr, mask);
-                               rsltq_wait_usecs = 4000;
-                       }
-               }
-       }
-       return count;
-}
-
-/* As per VirtpciFunc returns 1 for success and 0 for failure */
-static int
-virthba_serverup(struct virtpci_dev *virtpcidev)
-{
-       struct virthba_info *virthbainfo =
-           (struct virthba_info *)((struct Scsi_Host *)virtpcidev->scsi.
-                                    scsihost)->hostdata;
-
-       if (!virthbainfo->serverdown)
-               return 1;
-
-       if (virthbainfo->serverchangingstate)
-               return 0;
-
-       virthbainfo->serverchangingstate = true;
-       /* Must transition channel to ATTACHED state BEFORE we
-        * can start using the device again
-        */
-       SPAR_CHANNEL_CLIENT_TRANSITION(virthbainfo->chinfo.queueinfo->chan,
-                                      dev_name(&virtpcidev->generic_dev),
-                                      CHANNELCLI_ATTACHED, NULL);
-
-       /* Start Processing the IOVM Response Queue Again */
-       if (!uisthread_start(&virthbainfo->chinfo.threadinfo,
-                            process_incoming_rsps,
-                            virthbainfo, "vhba_incoming")) {
-               return 0;
-       }
-       virthbainfo->serverdown = false;
-       virthbainfo->serverchangingstate = false;
-
-       return 1;
-}
-
-static void
-virthba_serverdown_complete(struct work_struct *work)
-{
-       struct virthba_info *virthbainfo;
-       struct virtpci_dev *virtpcidev;
-       int i;
-       struct scsipending *pendingdel = NULL;
-       struct scsi_cmnd *scsicmd = NULL;
-       struct uiscmdrsp *cmdrsp;
-       unsigned long flags;
-
-       virthbainfo = container_of(work, struct virthba_info,
-                                  serverdown_completion);
-
-       /* Stop Using the IOVM Response Queue (queue should be drained
-        * by the end)
-        */
-       uisthread_stop(&virthbainfo->chinfo.threadinfo);
-
-       /* Fail Commands that weren't completed */
-       spin_lock_irqsave(&virthbainfo->privlock, flags);
-       for (i = 0; i < MAX_PENDING_REQUESTS; i++) {
-               pendingdel = &virthbainfo->pending[i];
-               switch (pendingdel->cmdtype) {
-               case CMD_SCSI_TYPE:
-                       scsicmd = (struct scsi_cmnd *)pendingdel->sent;
-                       scsicmd->result = DID_RESET << 16;
-                       if (scsicmd->scsi_done)
-                               scsicmd->scsi_done(scsicmd);
-                       break;
-               case CMD_SCSITASKMGMT_TYPE:
-                       cmdrsp = (struct uiscmdrsp *)pendingdel->sent;
-                       wake_up_all((wait_queue_head_t *)
-                                   cmdrsp->scsitaskmgmt.notify);
-                       *(int *)cmdrsp->scsitaskmgmt.notifyresult =
-                               TASK_MGMT_FAILED;
-                       break;
-               case CMD_VDISKMGMT_TYPE:
-                       cmdrsp = (struct uiscmdrsp *)pendingdel->sent;
-                       *(int *)cmdrsp->vdiskmgmt.notifyresult =
-                           VDISK_MGMT_FAILED;
-                       wake_up_all((wait_queue_head_t *)
-                                   cmdrsp->vdiskmgmt.notify);
-                       break;
-               default:
-                       break;
-               }
-               pendingdel->cmdtype = 0;
-               pendingdel->sent = NULL;
-       }
-       spin_unlock_irqrestore(&virthbainfo->privlock, flags);
-
-       virtpcidev = virthbainfo->virtpcidev;
-
-       virthbainfo->serverdown = true;
-       virthbainfo->serverchangingstate = false;
-       /* Return the ServerDown response to Command */
-       visorchipset_device_pause_response(virtpcidev->bus_no,
-                                          virtpcidev->device_no, 0);
-}
-
-/* As per VirtpciFunc returns 1 for success and 0 for failure */
-static int
-virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state)
-{
-       int stat = 1;
-
-       struct virthba_info *virthbainfo =
-           (struct virthba_info *)((struct Scsi_Host *)virtpcidev->scsi.
-                                    scsihost)->hostdata;
-
-       if (!virthbainfo->serverdown && !virthbainfo->serverchangingstate) {
-               virthbainfo->serverchangingstate = true;
-               queue_work(virthba_serverdown_workqueue,
-                          &virthbainfo->serverdown_completion);
-       } else if (virthbainfo->serverchangingstate) {
-               stat = 0;
-       }
-
-       return stat;
-}
-
-/*****************************************************/
-/* Module Init & Exit functions                      */
-/*****************************************************/
-
-static int __init
-virthba_parse_line(char *str)
-{
-       return 1;
-}
-
-static void __init
-virthba_parse_options(char *line)
-{
-       char *next = line;
-
-       POSTCODE_LINUX_2(VHBA_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO);
-       if (!line || !*line)
-               return;
-       while ((line = next)) {
-               next = strchr(line, ' ');
-               if (next)
-                       *next++ = 0;
-               virthba_parse_line(line);
-       }
-
-       POSTCODE_LINUX_2(VHBA_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO);
-}
-
-static int __init
-virthba_mod_init(void)
-{
-       int error;
-       int i;
-
-       if (!unisys_spar_platform)
-               return -ENODEV;
-
-       POSTCODE_LINUX_2(VHBA_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO);
-       virthba_parse_options(virthba_options);
-
-       error = virtpci_register_driver(&virthba_driver);
-       if (error < 0) {
-               POSTCODE_LINUX_3(VHBA_CREATE_FAILURE_PC, error,
-                                POSTCODE_SEVERITY_ERR);
-       } else {
-               /* create the debugfs directories and entries */
-               virthba_debugfs_dir = debugfs_create_dir("virthba", NULL);
-               debugfs_create_file("info", S_IRUSR, virthba_debugfs_dir,
-                                   NULL, &debugfs_info_fops);
-               debugfs_create_u32("rqwait_usecs", S_IRUSR | S_IWUSR,
-                                  virthba_debugfs_dir, &rsltq_wait_usecs);
-               debugfs_create_file("enable_ints", S_IWUSR,
-                                   virthba_debugfs_dir, NULL,
-                                   &debugfs_enable_ints_fops);
-               /* Initialize dar_work_queue */
-               INIT_WORK(&dar_work_queue, do_disk_add_remove);
-               spin_lock_init(&dar_work_queue_lock);
-
-               /* clear out array */
-               for (i = 0; i < VIRTHBASOPENMAX; i++)
-                       virthbas_open[i].virthbainfo = NULL;
-               /* Initialize the serverdown workqueue */
-               virthba_serverdown_workqueue =
-                   create_singlethread_workqueue("virthba_serverdown");
-               if (!virthba_serverdown_workqueue) {
-                       POSTCODE_LINUX_2(VHBA_CREATE_FAILURE_PC,
-                                        POSTCODE_SEVERITY_ERR);
-                       error = -1;
-               }
-       }
-
-       POSTCODE_LINUX_2(VHBA_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO);
-       return error;
-}
-
-static ssize_t
-virthba_acquire_lun(struct device *cdev, struct device_attribute *attr,
-                   const char *buf, size_t count)
-{
-       struct uisscsi_dest vdest;
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       int i;
-
-       i = sscanf(buf, "%d-%d-%d", &vdest.channel, &vdest.id, &vdest.lun);
-       if (i != 3)
-               return i;
-
-       return forward_vdiskmgmt_command(VDISK_MGMT_ACQUIRE, shost, &vdest);
-}
-
-static ssize_t
-virthba_release_lun(struct device *cdev, struct device_attribute *attr,
-                   const char *buf, size_t count)
-{
-       struct uisscsi_dest vdest;
-       struct Scsi_Host *shost = class_to_shost(cdev);
-       int i;
-
-       i = sscanf(buf, "%d-%d-%d", &vdest.channel, &vdest.id, &vdest.lun);
-       if (i != 3)
-               return i;
-
-       return forward_vdiskmgmt_command(VDISK_MGMT_RELEASE, shost, &vdest);
-}
-
-#define CLASS_DEVICE_ATTR(_name, _mode, _show, _store)      \
-       struct device_attribute class_device_attr_##_name =   \
-               __ATTR(_name, _mode, _show, _store)
-
-static CLASS_DEVICE_ATTR(acquire_lun, S_IWUSR, NULL, virthba_acquire_lun);
-static CLASS_DEVICE_ATTR(release_lun, S_IWUSR, NULL, virthba_release_lun);
-
-static DEVICE_ATTRIBUTE *virthba_shost_attrs[] = {
-       &class_device_attr_acquire_lun,
-       &class_device_attr_release_lun,
-       NULL
-};
-
-static void __exit
-virthba_mod_exit(void)
-{
-       virtpci_unregister_driver(&virthba_driver);
-       /* unregister is going to call virthba_remove */
-       /* destroy serverdown completion workqueue */
-       if (virthba_serverdown_workqueue) {
-               destroy_workqueue(virthba_serverdown_workqueue);
-               virthba_serverdown_workqueue = NULL;
-       }
-
-       debugfs_remove_recursive(virthba_debugfs_dir);
-}
-
-/* specify function to be run at module insertion time */
-module_init(virthba_mod_init);
-
-/* specify function to be run when module is removed */
-module_exit(virthba_mod_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Usha Srinivasan");
-MODULE_ALIAS("uisvirthba");
-       /* this is extracted during depmod and kept in modules.dep */
-/* module parameter */
-module_param(virthba_options, charp, S_IRUGO);
diff --git a/drivers/staging/unisys/virthba/virthba.h b/drivers/staging/unisys/virthba/virthba.h
deleted file mode 100644 (file)
index 5990166..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* virthba.h
- *
- * Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- */
-
-/*
- * Unisys Virtual HBA driver header
- */
-
-#ifndef __VIRTHBA_H__
-#define __VIRTHBA_H__
-
-#define VIRTHBA_VERSION "01.00"
-
-#endif /* __VIRTHBA_H__ */