summaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-09-02 12:22:54 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-02 12:22:54 -0700
commitdf910390e2db07a76c87f258475f6c96253cee6c (patch)
treed522f0f098688c330014c5d78be6b3e74de87b7e /drivers/scsi
parent91a247d7d3694a161092931ea4e0b13c11b8e9a0 (diff)
parent9f55bca2b82a77a3cc3204900db2fc40ab30019e (diff)
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull first round of SCSI updates from James Bottomley: "This includes one new driver: cxlflash plus the usual grab bag of updates for the major drivers: qla2xxx, ipr, storvsc, pm80xx, hptiop, plus a few assorted fixes. There's another tranch coming, but I want to incubate it another few days in the checkers, plus it includes a mpt2sas separated lifetime fix, which Avago won't get done testing until Friday" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (85 commits) aic94xx: set an error code on failure storvsc: Set the error code correctly in failure conditions storvsc: Allow write_same when host is windows 10 storvsc: use storage protocol version to determine storage capabilities storvsc: use correct defaults for values determined by protocol negotiation storvsc: Untangle the storage protocol negotiation from the vmbus protocol negotiation. storvsc: Use a single value to track protocol versions storvsc: Rather than look for sets of specific protocol versions, make decisions based on ranges. cxlflash: Remove unused variable from queuecommand cxlflash: shift wrapping bug in afu_link_reset() cxlflash: off by one bug in cxlflash_show_port_status() cxlflash: Virtual LUN support cxlflash: Superpipe support cxlflash: Base error recovery support qla2xxx: Update driver version to 8.07.00.26-k qla2xxx: Add pci device id 0x2261. qla2xxx: Fix missing device login retries. qla2xxx: do not clear slot in outstanding cmd array qla2xxx: Remove decrement of sp reference count in abort handler. qla2xxx: Add support to show MPI and PEP FW version for ISP27xx. ...
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/Kconfig1
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_init.c1
-rw-r--r--drivers/scsi/bfa/bfad_im.c2
-rw-r--r--drivers/scsi/cxlflash/Kconfig11
-rw-r--r--drivers/scsi/cxlflash/Makefile2
-rw-r--r--drivers/scsi/cxlflash/common.h208
-rw-r--r--drivers/scsi/cxlflash/lunmgt.c266
-rw-r--r--drivers/scsi/cxlflash/main.c2494
-rw-r--r--drivers/scsi/cxlflash/main.h108
-rw-r--r--drivers/scsi/cxlflash/sislite.h472
-rw-r--r--drivers/scsi/cxlflash/superpipe.c2084
-rw-r--r--drivers/scsi/cxlflash/superpipe.h147
-rw-r--r--drivers/scsi/cxlflash/vlun.c1243
-rw-r--r--drivers/scsi/cxlflash/vlun.h86
-rw-r--r--drivers/scsi/hpsa.c301
-rw-r--r--drivers/scsi/hpsa.h16
-rw-r--r--drivers/scsi/hpsa_cmd.h10
-rw-r--r--drivers/scsi/hptiop.c97
-rw-r--r--drivers/scsi/hptiop.h6
-rw-r--r--drivers/scsi/ipr.c15
-rw-r--r--drivers/scsi/ipr.h17
-rw-r--r--drivers/scsi/libfc/fc_fcp.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c2
-rw-r--r--drivers/scsi/megaraid.c140
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c544
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c95
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c16
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_base.c16
-rw-r--r--drivers/scsi/mvsas/mv_init.c5
-rw-r--r--drivers/scsi/pm8001/pm8001_defs.h4
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c4
-rw-r--r--drivers/scsi/pm8001/pm8001_init.c5
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.c19
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.h12
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.c111
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.h5
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c24
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c102
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h15
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c52
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c162
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c132
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c70
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c80
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_mr.c22
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c165
-rw-r--r--drivers/scsi/qla2xxx/qla_nx2.c20
-rw-r--r--drivers/scsi/qla2xxx/qla_nx2.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c41
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c14
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c139
-rw-r--r--drivers/scsi/qla2xxx/qla_tmpl.c27
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h2
-rw-r--r--drivers/scsi/qla2xxx/tcm_qla2xxx.c6
-rw-r--r--drivers/scsi/scsi_error.c9
-rw-r--r--drivers/scsi/scsi_lib.c11
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c11
-rw-r--r--drivers/scsi/st.c83
-rw-r--r--drivers/scsi/storvsc_drv.c224
62 files changed, 8670 insertions, 1325 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 456e1567841c..95f7a76cfafc 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -345,6 +345,7 @@ source "drivers/scsi/cxgbi/Kconfig"
source "drivers/scsi/bnx2i/Kconfig"
source "drivers/scsi/bnx2fc/Kconfig"
source "drivers/scsi/be2iscsi/Kconfig"
+source "drivers/scsi/cxlflash/Kconfig"
config SGIWD93_SCSI
tristate "SGI WD93C93 SCSI Driver"
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 91209e3d27e3..471d08791766 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -102,6 +102,7 @@ obj-$(CONFIG_SCSI_7000FASST) += wd7000.o
obj-$(CONFIG_SCSI_EATA) += eata.o
obj-$(CONFIG_SCSI_DC395x) += dc395x.o
obj-$(CONFIG_SCSI_AM53C974) += esp_scsi.o am53c974.o
+obj-$(CONFIG_CXLFLASH) += cxlflash/
obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
obj-$(CONFIG_MEGARAID_SAS) += megaraid/
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index 4b135cca42a1..31e8576cbaab 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -109,6 +109,7 @@ static int asd_map_memio(struct asd_ha_struct *asd_ha)
if (!io_handle->addr) {
asd_printk("couldn't map MBAR%d of %s\n", i==0?0:1,
pci_name(asd_ha->pcidev));
+ err = -ENOMEM;
goto Err_unreq;
}
}
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 7223b0006740..8367c11d554b 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -851,6 +851,8 @@ bfad_im_module_exit(void)
if (bfad_im_scsi_vport_transport_template)
fc_release_transport(bfad_im_scsi_vport_transport_template);
+
+ idr_destroy(&bfad_im_port_index);
}
void
diff --git a/drivers/scsi/cxlflash/Kconfig b/drivers/scsi/cxlflash/Kconfig
new file mode 100644
index 000000000000..c052104e523e
--- /dev/null
+++ b/drivers/scsi/cxlflash/Kconfig
@@ -0,0 +1,11 @@
+#
+# IBM CXL-attached Flash Accelerator SCSI Driver
+#
+
+config CXLFLASH
+ tristate "Support for IBM CAPI Flash"
+ depends on PCI && SCSI && CXL && EEH
+ default m
+ help
+ Allows CAPI Accelerated IO to Flash
+ If unsure, say N.
diff --git a/drivers/scsi/cxlflash/Makefile b/drivers/scsi/cxlflash/Makefile
new file mode 100644
index 000000000000..9e39866d473b
--- /dev/null
+++ b/drivers/scsi/cxlflash/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CXLFLASH) += cxlflash.o
+cxlflash-y += main.o superpipe.o lunmgt.o vlun.o
diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h
new file mode 100644
index 000000000000..1c56037146e1
--- /dev/null
+++ b/drivers/scsi/cxlflash/common.h
@@ -0,0 +1,208 @@
+/*
+ * CXL Flash Device Driver
+ *
+ * Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
+ * Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
+ *
+ * Copyright (C) 2015 IBM Corporation
+ *
+ * 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.
+ */
+
+#ifndef _CXLFLASH_COMMON_H
+#define _CXLFLASH_COMMON_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_device.h>
+
+
+#define MAX_CONTEXT CXLFLASH_MAX_CONTEXT /* num contexts per afu */
+
+#define CXLFLASH_BLOCK_SIZE 4096 /* 4K blocks */
+#define CXLFLASH_MAX_XFER_SIZE 16777216 /* 16MB transfer */
+#define CXLFLASH_MAX_SECTORS (CXLFLASH_MAX_XFER_SIZE/512) /* SCSI wants
+ max_sectors
+ in units of
+ 512 byte
+ sectors
+ */
+
+#define NUM_RRQ_ENTRY 16 /* for master issued cmds */
+#define MAX_RHT_PER_CONTEXT (PAGE_SIZE / sizeof(struct sisl_rht_entry))
+
+/* AFU command retry limit */
+#define MC_RETRY_CNT 5 /* sufficient for SCSI check and
+ certain AFU errors */
+
+/* Command management definitions */
+#define CXLFLASH_NUM_CMDS (2 * CXLFLASH_MAX_CMDS) /* Must be a pow2 for
+ alignment and more
+ efficient array
+ index derivation
+ */
+
+#define CXLFLASH_MAX_CMDS 16
+#define CXLFLASH_MAX_CMDS_PER_LUN CXLFLASH_MAX_CMDS
+
+
+static inline void check_sizes(void)
+{
+ BUILD_BUG_ON_NOT_POWER_OF_2(CXLFLASH_NUM_CMDS);
+}
+
+/* AFU defines a fixed size of 4K for command buffers (borrow 4K page define) */
+#define CMD_BUFSIZE SIZE_4K
+
+/* flags in IOA status area for host use */
+#define B_DONE 0x01
+#define B_ERROR 0x02 /* set with B_DONE */
+#define B_TIMEOUT 0x04 /* set with B_DONE & B_ERROR */
+
+enum cxlflash_lr_state {
+ LINK_RESET_INVALID,
+ LINK_RESET_REQUIRED,
+ LINK_RESET_COMPLETE
+};
+
+enum cxlflash_init_state {
+ INIT_STATE_NONE,
+ INIT_STATE_PCI,
+ INIT_STATE_AFU,
+ INIT_STATE_SCSI
+};
+
+enum cxlflash_state {
+ STATE_NORMAL, /* Normal running state, everything good */
+ STATE_LIMBO, /* Limbo running state, trying to reset/recover */
+ STATE_FAILTERM /* Failed/terminating state, error out users/threads */
+};
+
+/*
+ * Each context has its own set of resource handles that is visible
+ * only from that context.
+ */
+
+struct cxlflash_cfg {
+ struct afu *afu;
+ struct cxl_context *mcctx;
+
+ struct pci_dev *dev;
+ struct pci_device_id *dev_id;
+ struct Scsi_Host *host;
+
+ ulong cxlflash_regs_pci;
+
+ struct work_struct work_q;
+ enum cxlflash_init_state init_state;
+ enum cxlflash_lr_state lr_state;
+ int lr_port;
+
+ struct cxl_afu *cxl_afu;
+
+ struct pci_pool *cxlflash_cmd_pool;
+ struct pci_dev *parent_dev;
+
+ atomic_t recovery_threads;
+ struct mutex ctx_recovery_mutex;
+ struct mutex ctx_tbl_list_mutex;
+ struct ctx_info *ctx_tbl[MAX_CONTEXT];
+ struct list_head ctx_err_recovery; /* contexts w/ recovery pending */
+ struct file_operations cxl_fops;
+
+ atomic_t num_user_contexts;
+
+ /* Parameters that are LUN table related */
+ int last_lun_index[CXLFLASH_NUM_FC_PORTS];
+ int promote_lun_index;
+ struct list_head lluns; /* list of llun_info structs */
+
+ wait_queue_head_t tmf_waitq;
+ bool tmf_active;
+ wait_queue_head_t limbo_waitq;
+ enum cxlflash_state state;
+};
+
+struct afu_cmd {
+ struct sisl_ioarcb rcb; /* IOARCB (cache line aligned) */
+ struct sisl_ioasa sa; /* IOASA must follow IOARCB */
+ spinlock_t slock;
+ struct completion cevent;
+ char *buf; /* per command buffer */
+ struct afu *parent;
+ int slot;
+ atomic_t free;
+
+ u8 cmd_tmf:1;
+
+ /* As per the SISLITE spec the IOARCB EA has to be 16-byte aligned.
+ * However for performance reasons the IOARCB/IOASA should be
+ * cache line aligned.
+ */
+} __aligned(cache_line_size());
+
+struct afu {
+ /* Stuff requiring alignment go first. */
+
+ u64 rrq_entry[NUM_RRQ_ENTRY]; /* 128B RRQ */
+ /*
+ * Command & data for AFU commands.
+ */
+ struct afu_cmd cmd[CXLFLASH_NUM_CMDS];
+
+ /* Beware of alignment till here. Preferably introduce new
+ * fields after this point
+ */
+
+ /* AFU HW */
+ struct cxl_ioctl_start_work work;
+ struct cxlflash_afu_map *afu_map; /* entire MMIO map */
+ struct sisl_host_map *host_map; /* MC host map */
+ struct sisl_ctrl_map *ctrl_map; /* MC control map */
+
+ ctx_hndl_t ctx_hndl; /* master's context handle */
+ u64 *hrrq_start;
+ u64 *hrrq_end;
+ u64 *hrrq_curr;
+ bool toggle;
+ bool read_room;
+ atomic64_t room;
+ u64 hb;
+ u32 cmd_couts; /* Number of command checkouts */
+ u32 internal_lun; /* User-desired LUN mode for this AFU */
+
+ char version[8];
+ u64 interface_version;
+
+ struct cxlflash_cfg *parent; /* Pointer back to parent cxlflash_cfg */
+
+};
+
+static inline u64 lun_to_lunid(u64 lun)
+{
+ u64 lun_id;
+
+ int_to_scsilun(lun, (struct scsi_lun *)&lun_id);
+ return swab64(lun_id);
+}
+
+int cxlflash_send_cmd(struct afu *, struct afu_cmd *);
+void cxlflash_wait_resp(struct afu *, struct afu_cmd *);
+int cxlflash_afu_reset(struct cxlflash_cfg *);
+struct afu_cmd *cxlflash_cmd_checkout(struct afu *);
+void cxlflash_cmd_checkin(struct afu_cmd *);
+int cxlflash_afu_sync(struct afu *, ctx_hndl_t, res_hndl_t, u8);
+void cxlflash_list_init(void);
+void cxlflash_term_global_luns(void);
+void cxlflash_free_errpage(void);
+int cxlflash_ioctl(struct scsi_device *, int, void __user *);
+void cxlflash_stop_term_user_contexts(struct cxlflash_cfg *);
+int cxlflash_mark_contexts_error(struct cxlflash_cfg *);
+void cxlflash_term_local_luns(struct cxlflash_cfg *);
+void cxlflash_restore_luntable(struct cxlflash_cfg *);
+
+#endif /* ifndef _CXLFLASH_COMMON_H */
diff --git a/drivers/scsi/cxlflash/lunmgt.c b/drivers/scsi/cxlflash/lunmgt.c
new file mode 100644
index 000000000000..d98ad0ff64c1
--- /dev/null
+++ b/drivers/scsi/cxlflash/lunmgt.c
@@ -0,0 +1,266 @@
+/*
+ * CXL Flash Device Driver
+ *
+ * Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
+ * Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
+ *
+ * Copyright (C) 2015 IBM Corporation
+ *
+ * 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.
+ */
+
+#include <misc/cxl.h>
+#include <asm/unaligned.h>
+
+#include <scsi/scsi_host.h>
+#include <uapi/scsi/cxlflash_ioctl.h>
+
+#include "sislite.h"
+#include "common.h"
+#include "vlun.h"
+#include "superpipe.h"
+
+/**
+ * create_local() - allocate and initialize a local LUN information structure
+ * @sdev: SCSI device associated with LUN.
+ * @wwid: World Wide Node Name for LUN.
+ *
+ * Return: Allocated local llun_info structure on success, NULL on failure
+ */
+static struct llun_info *create_local(struct scsi_device *sdev, u8 *wwid)
+{
+ struct llun_info *lli = NULL;
+
+ lli = kzalloc(sizeof(*lli), GFP_KERNEL);
+ if (unlikely(!lli)) {
+ pr_err("%s: could not allocate lli\n", __func__);
+ goto out;
+ }
+
+ lli->sdev = sdev;
+ lli->newly_created = true;
+ lli->host_no = sdev->host->host_no;
+ lli->in_table = false;
+
+ memcpy(lli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN);
+out:
+ return lli;
+}
+
+/**
+ * create_global() - allocate and initialize a global LUN information structure
+ * @sdev: SCSI device associated with LUN.
+ * @wwid: World Wide Node Name for LUN.
+ *
+ * Return: Allocated global glun_info structure on success, NULL on failure
+ */
+static struct glun_info *create_global(struct scsi_device *sdev, u8 *wwid)
+{
+ struct glun_info *gli = NULL;
+
+ gli = kzalloc(sizeof(*gli), GFP_KERNEL);
+ if (unlikely(!gli)) {
+ pr_err("%s: could not allocate gli\n", __func__);
+ goto out;
+ }
+
+ mutex_init(&gli->mutex);
+ memcpy(gli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN);
+out:
+ return gli;
+}
+
+/**
+ * refresh_local() - find and update local LUN information structure by WWID
+ * @cfg: Internal structure associated with the host.
+ * @wwid: WWID associated with LUN.
+ *
+ * When the LUN is found, mark it by updating it's newly_created field.
+ *
+ * Return: Found local lun_info structure on success, NULL on failure
+ * If a LUN with the WWID is found in the list, refresh it's state.
+ */
+static struct llun_info *refresh_local(struct cxlflash_cfg *cfg, u8 *wwid)
+{
+ struct llun_info *lli, *temp;
+
+ list_for_each_entry_safe(lli, temp, &cfg->lluns, list)
+ if (!memcmp(lli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN)) {
+ lli->newly_created = false;
+ return lli;
+ }
+
+ return NULL;
+}
+
+/**
+ * lookup_global() - find a global LUN information structure by WWID
+ * @wwid: WWID associated with LUN.
+ *
+ * Return: Found global lun_info structure on success, NULL on failure
+ */
+static struct glun_info *lookup_global(u8 *wwid)
+{
+ struct glun_info *gli, *temp;
+
+ list_for_each_entry_safe(gli, temp, &global.gluns, list)
+ if (!memcmp(gli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN))
+ return gli;
+
+ return NULL;
+}
+
+/**
+ * find_and_create_lun() - find or create a local LUN information structure
+ * @sdev: SCSI device associated with LUN.
+ * @wwid: WWID associated with LUN.
+ *
+ * The LUN is kept both in a local list (per adapter) and in a global list
+ * (across all adapters). Certain attributes of the LUN are local to the
+ * adapter (such as index, port selection mask etc.).
+ * The block allocation map is shared across all adapters (i.e. associated
+ * wih the global list). Since different attributes are associated with
+ * the per adapter and global entries, allocate two separate structures for each
+ * LUN (one local, one global).
+ *
+ * Keep a pointer back from the local to the global entry.
+ *
+ * Return: Found/Allocated local lun_info structure on success, NULL on failure
+ */
+static struct llun_info *find_and_create_lun(struct scsi_device *sdev, u8 *wwid)
+{
+ struct llun_info *lli = NULL;
+ struct glun_info *gli = NULL;
+ struct Scsi_Host *shost = sdev->host;
+ struct cxlflash_cfg *cfg = shost_priv(shost);
+
+ mutex_lock(&global.mutex);
+ if (unlikely(!wwid))
+ goto out;
+
+ lli = refresh_local(cfg, wwid);
+ if (lli)
+ goto out;
+
+ lli = create_local(sdev, wwid);
+ if (unlikely(!lli))
+ goto out;
+
+ gli = lookup_global(wwid);
+ if (gli) {
+ lli->parent = gli;
+ list_add(&lli->list, &cfg->lluns);
+ goto out;
+ }
+
+ gli = create_global(sdev, wwid);
+ if (unlikely(!gli)) {
+ kfree(lli);
+ lli = NULL;
+ goto out;
+ }
+
+ lli->parent = gli;
+ list_add(&lli->list, &cfg->lluns);
+
+ list_add(&gli->list, &global.gluns);
+
+out:
+ mutex_unlock(&global.mutex);
+ pr_debug("%s: returning %p\n", __func__, lli);
+ return lli;
+}
+
+/**
+ * cxlflash_term_local_luns() - Delete all entries from local LUN list, free.
+ * @cfg: Internal structure associated with the host.
+ */
+void cxlflash_term_local_luns(struct cxlflash_cfg *cfg)
+{
+ struct llun_info *lli, *temp;
+
+ mutex_lock(&global.mutex);
+ list_for_each_entry_safe(lli, temp, &cfg->lluns, list) {
+ list_del(&lli->list);
+ kfree(lli);
+ }
+ mutex_unlock(&global.mutex);
+}
+
+/**
+ * cxlflash_list_init() - initializes the global LUN list
+ */
+void cxlflash_list_init(void)
+{
+ INIT_LIST_HEAD(&global.gluns);
+ mutex_init(&global.mutex);
+ global.err_page = NULL;
+}
+
+/**
+ * cxlflash_term_global_luns() - frees resources associated with global LUN list
+ */
+void cxlflash_term_global_luns(void)
+{
+ struct glun_info *gli, *temp;
+
+ mutex_lock(&global.mutex);
+ list_for_each_entry_safe(gli, temp, &global.gluns, list) {
+ list_del(&gli->list);
+ cxlflash_ba_terminate(&gli->blka.ba_lun);
+ kfree(gli);
+ }
+ mutex_unlock(&global.mutex);
+}
+
+/**
+ * cxlflash_manage_lun() - handles LUN management activities
+ * @sdev: SCSI device associated with LUN.
+ * @manage: Manage ioctl data structure.
+ *
+ * This routine is used to notify the driver about a LUN's WWID and associate
+ * SCSI devices (sdev) with a global LUN instance. Additionally it serves to
+ * change a LUN's operating mode: legacy or superpipe.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+int cxlflash_manage_lun(struct scsi_device *sdev,
+ struct dk_cxlflash_manage_lun *manage)
+{
+ int rc = 0;
+ struct llun_info *lli = NULL;
+ u64 flags = manage->hdr.flags;
+ u32 chan = sdev->channel;
+
+ lli = find_and_create_lun(sdev, manage->wwid);
+ pr_debug("%s: ENTER: WWID = %016llX%016llX, flags = %016llX li = %p\n",
+ __func__, get_unaligned_le64(&manage->wwid[0]),
+ get_unaligned_le64(&manage->wwid[8]),
+ manage->hdr.flags, lli);
+ if (unlikely(!lli)) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ if (flags & DK_CXLFLASH_MANAGE_LUN_ENABLE_SUPERPIPE) {
+ if (lli->newly_created)
+ lli->port_sel = CHAN2PORT(chan);
+ else
+ lli->port_sel = BOTH_PORTS;
+ /* Store off lun in unpacked, AFU-friendly format */
+ lli->lun_id[chan] = lun_to_lunid(sdev->lun);
+ sdev->hostdata = lli;
+ } else if (flags & DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE) {
+ if (lli->parent->mode != MODE_NONE)
+ rc = -EBUSY;
+ else
+ sdev->hostdata = NULL;
+ }
+
+out:
+ pr_debug("%s: returning rc=%d\n", __func__, rc);
+ return rc;
+}
diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c
new file mode 100644
index 000000000000..3e3ccf16e7c2
--- /dev/null
+++ b/drivers/scsi/cxlflash/main.c
@@ -0,0 +1,2494 @@
+/*
+ * CXL Flash Device Driver
+ *
+ * Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
+ * Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
+ *
+ * Copyright (C) 2015 IBM Corporation
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include <asm/unaligned.h>
+
+#include <misc/cxl.h>
+
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_host.h>
+#include <uapi/scsi/cxlflash_ioctl.h>
+
+#include "main.h"
+#include "sislite.h"
+#include "common.h"
+
+MODULE_DESCRIPTION(CXLFLASH_ADAPTER_NAME);
+MODULE_AUTHOR("Manoj N. Kumar <manoj@linux.vnet.ibm.com>");
+MODULE_AUTHOR("Matthew R. Ochs <mrochs@linux.vnet.ibm.com>");
+MODULE_LICENSE("GPL");
+
+
+/**
+ * cxlflash_cmd_checkout() - checks out an AFU com