Merge branch '5.19/scsi-fixes' into 5.20/scsi-staging
authorMartin K. Petersen <martin.petersen@oracle.com>
Thu, 7 Jul 2022 21:20:43 +0000 (17:20 -0400)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 7 Jul 2022 21:20:43 +0000 (17:20 -0400)
Bring in fixes to resolve a merge conflict in the lpfc driver update.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
103 files changed:
Documentation/devicetree/bindings/ufs/renesas,ufs.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
Documentation/userspace-api/ioctl/ioctl-number.rst
MAINTAINERS
block/bsg.c
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/message/fusion/mptspi.c
drivers/scsi/BusLogic.c
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/a2091.c
drivers/scsi/a3000.c
drivers/scsi/aacraid/aachba.c
drivers/scsi/aic94xx/aic94xx_dev.c
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/bnx2i/bnx2i_iscsi.c
drivers/scsi/cxgbi/libcxgbi.c
drivers/scsi/dpt/dpti_i2o.h [deleted file]
drivers/scsi/dpt/dpti_ioctl.h [deleted file]
drivers/scsi/dpt/dptsig.h [deleted file]
drivers/scsi/dpt/osd_defs.h [deleted file]
drivers/scsi/dpt/osd_util.h [deleted file]
drivers/scsi/dpt/sys_info.h [deleted file]
drivers/scsi/dpt_i2o.c [deleted file]
drivers/scsi/dpti.h [deleted file]
drivers/scsi/fcoe/fcoe.c
drivers/scsi/gvp11.c
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
drivers/scsi/hosts.c
drivers/scsi/iscsi_tcp.c
drivers/scsi/iscsi_tcp.h
drivers/scsi/libiscsi.c
drivers/scsi/libiscsi_tcp.c
drivers/scsi/libsas/sas_expander.c
drivers/scsi/libsas/sas_internal.h
drivers/scsi/lpfc/lpfc_nvmet.c
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/mpi3mr/mpi3mr.h
drivers/scsi/mpi3mr/mpi3mr_os.c
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/scsi/mpt3sas/mpt3sas_scsih.c
drivers/scsi/pm8001/pm8001_hwi.c
drivers/scsi/pm8001/pm8001_init.c
drivers/scsi/pm8001/pm8001_sas.c
drivers/scsi/pm8001/pm8001_sas.h
drivers/scsi/pm8001/pm80xx_hwi.c
drivers/scsi/qedi/qedi_main.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_bsg.c
drivers/scsi/qla2xxx/qla_bsg.h
drivers/scsi/qla2xxx/qla_dbg.h
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_edif.c
drivers/scsi/qla2xxx/qla_edif.h
drivers/scsi/qla2xxx/qla_edif_bsg.h
drivers/scsi/qla2xxx/qla_fw.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_mid.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_target.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/sd.c
drivers/scsi/sd.h
drivers/scsi/snic/snic_fwint.h
drivers/scsi/sym53c8xx_2/sym_hipd.c
drivers/target/iscsi/iscsi_target_configfs.c
drivers/target/iscsi/iscsi_target_nego.c
drivers/target/iscsi/iscsi_target_nodeattrib.c
drivers/target/iscsi/iscsi_target_tpg.c
drivers/target/target_core_alua.c
drivers/target/target_core_configfs.c
drivers/target/target_core_device.c
drivers/target/target_core_file.c
drivers/target/target_core_iblock.c
drivers/ufs/core/ufshcd-priv.h
drivers/ufs/core/ufshcd.c
drivers/ufs/host/Kconfig
drivers/ufs/host/Makefile
drivers/ufs/host/ufs-exynos.c
drivers/ufs/host/ufs-exynos.h
drivers/ufs/host/ufs-mediatek.c
drivers/ufs/host/ufs-mediatek.h
drivers/ufs/host/ufs-qcom.c
drivers/ufs/host/ufs-renesas.c [new file with mode: 0644]
drivers/ufs/host/ufshcd-pltfrm.c
drivers/ufs/host/ufshcd-pltfrm.h
include/scsi/libiscsi.h
include/scsi/libsas.h
include/scsi/sas.h
include/scsi/scsi_transport_iscsi.h
include/target/iscsi/iscsi_target_core.h
include/target/target_core_backend.h
include/trace/events/scsi.h
include/ufs/ufshcd.h
include/ufs/unipro.h

diff --git a/Documentation/devicetree/bindings/ufs/renesas,ufs.yaml b/Documentation/devicetree/bindings/ufs/renesas,ufs.yaml
new file mode 100644 (file)
index 0000000..f04f9f6
--- /dev/null
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ufs/renesas,ufs.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas R-Car UFS Host Controller
+
+maintainers:
+  - Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+allOf:
+  - $ref: ufs-common.yaml
+
+properties:
+  compatible:
+    const: renesas,r8a779f0-ufs
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: fck
+      - const: ref_clk
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - power-domains
+  - resets
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/r8a779f0-cpg-mssr.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/r8a779f0-sysc.h>
+
+    ufs: ufs@e686000 {
+            compatible = "renesas,r8a779f0-ufs";
+            reg = <0xe6860000 0x100>;
+            interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cpg CPG_MOD 1514>, <&ufs30_clk>;
+            clock-names = "fck", "ref_clk";
+            freq-table-hz = <200000000 200000000>, <38400000 38400000>;
+            power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
+            resets = <&cpg 1514>;
+    };
index c949eb6..2c715ee 100644 (file)
@@ -21,6 +21,7 @@ properties:
       - samsung,exynos7-ufs
       - samsung,exynosautov9-ufs
       - samsung,exynosautov9-ufs-vh
+      - tesla,fsd-ufs
 
   reg:
     items:
index fcab013..3b985b1 100644 (file)
@@ -120,7 +120,7 @@ Code  Seq#    Include File                                           Comments
 'C'   01-2F  linux/capi.h                                            conflict!
 'C'   F0-FF  drivers/net/wan/cosa.h                                  conflict!
 'D'   all    arch/s390/include/asm/dasd.h
-'D'   40-5F  drivers/scsi/dpt/dtpi_ioctl.h
+'D'   40-5F  drivers/scsi/dpt/dtpi_ioctl.h                           Dead since 2022
 'D'   05     drivers/scsi/pmcraid.h
 'E'   all    linux/input.h                                           conflict!
 'E'   00-0F  xen/evtchn.h                                            conflict!
index a6d3bd9..1283c82 100644 (file)
@@ -5354,7 +5354,7 @@ W:        http://www.chelsio.com
 F:     drivers/net/ethernet/chelsio/cxgb3/
 
 CXGB3 ISCSI DRIVER (CXGB3I)
-M:     Karen Xie <kxie@chelsio.com>
+M:     Varun Prakash <varun@chelsio.com>
 L:     linux-scsi@vger.kernel.org
 S:     Supported
 W:     http://www.chelsio.com
@@ -5386,7 +5386,7 @@ W:        http://www.chelsio.com
 F:     drivers/net/ethernet/chelsio/cxgb4/
 
 CXGB4 ISCSI DRIVER (CXGB4I)
-M:     Karen Xie <kxie@chelsio.com>
+M:     Varun Prakash <varun@chelsio.com>
 L:     linux-scsi@vger.kernel.org
 S:     Supported
 W:     http://www.chelsio.com
@@ -6116,14 +6116,6 @@ F:       Documentation/networking/device_drivers/ethernet/freescale/dpaa2/switch-drive
 F:     drivers/net/ethernet/freescale/dpaa2/dpaa2-switch*
 F:     drivers/net/ethernet/freescale/dpaa2/dpsw*
 
-DPT_I2O SCSI RAID DRIVER
-M:     Adaptec OEM Raid Solutions <aacraid@microsemi.com>
-L:     linux-scsi@vger.kernel.org
-S:     Maintained
-W:     http://www.adaptec.com/
-F:     drivers/scsi/dpt*
-F:     drivers/scsi/dpt/
-
 DRBD DRIVER
 M:     Philipp Reisner <philipp.reisner@linbit.com>
 M:     Lars Ellenberg <lars.ellenberg@linbit.com>
@@ -20435,6 +20427,13 @@ L:     linux-mediatek@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     drivers/ufs/host/ufs-mediatek*
 
+UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER RENESAS HOOKS
+M:     Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+L:     linux-renesas-soc@vger.kernel.org
+L:     linux-scsi@vger.kernel.org
+S:     Maintained
+F:     drivers/ufs/host/ufs-renesas.c
+
 UNSORTED BLOCK IMAGES (UBI)
 M:     Richard Weinberger <richard@nod.at>
 L:     linux-mtd@lists.infradead.org
index 882f56b..2ab1351 100644 (file)
@@ -169,7 +169,7 @@ static void bsg_device_release(struct device *dev)
 {
        struct bsg_device *bd = container_of(dev, struct bsg_device, device);
 
-       ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt));
+       ida_free(&bsg_minor_ida, MINOR(bd->device.devt));
        kfree(bd);
 }
 
@@ -196,7 +196,7 @@ struct bsg_device *bsg_register_queue(struct request_queue *q,
        bd->queue = q;
        bd->sg_io_fn = sg_io_fn;
 
-       ret = ida_simple_get(&bsg_minor_ida, 0, BSG_MAX_DEVS, GFP_KERNEL);
+       ret = ida_alloc_max(&bsg_minor_ida, BSG_MAX_DEVS - 1, GFP_KERNEL);
        if (ret < 0) {
                if (ret == -ENOSPC)
                        dev_err(parent, "bsg: too many bsg devices\n");
index 321949a..620ae5b 100644 (file)
@@ -568,7 +568,7 @@ static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
        struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
 
        iscsi_session_teardown(cls_session);
-       iscsi_host_remove(shost);
+       iscsi_host_remove(shost, false);
        iscsi_host_free(shost);
 }
 
@@ -685,7 +685,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
        return cls_session;
 
 remove_host:
-       iscsi_host_remove(shost);
+       iscsi_host_remove(shost, false);
 free_host:
        iscsi_host_free(shost);
        return NULL;
index 388675c..62089a8 100644 (file)
@@ -101,7 +101,7 @@ static u8   mptspiInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for interna
  *     @target: per target private data
  *     @sdev: SCSI device
  *
- *     Update the target negotiation parameters based on the the Inquiry
+ *     Update the target negotiation parameters based on the Inquiry
  *     data, adapter capabilities, and NVRAM settings.
  **/
 static void
index a897c8f..f2abffc 100644 (file)
@@ -2515,12 +2515,26 @@ static int blogic_resultcode(struct blogic_adapter *adapter,
        return (hoststatus << 16) | tgt_status;
 }
 
+/*
+ * turn the dma address from an inbox into a ccb pointer
+ * This is rather inefficient.
+ */
+static struct blogic_ccb *
+blogic_inbox_to_ccb(struct blogic_adapter *adapter, struct blogic_inbox *inbox)
+{
+       struct blogic_ccb *ccb;
+
+       for (ccb = adapter->all_ccbs; ccb; ccb = ccb->next_all)
+               if (inbox->ccb == ccb->dma_handle)
+                       break;
+
+       return ccb;
+}
 
 /*
   blogic_scan_inbox scans the Incoming Mailboxes saving any
   Incoming Mailbox entries for completion processing.
 */
-
 static void blogic_scan_inbox(struct blogic_adapter *adapter)
 {
        /*
@@ -2540,17 +2554,14 @@ static void blogic_scan_inbox(struct blogic_adapter *adapter)
        enum blogic_cmplt_code comp_code;
 
        while ((comp_code = next_inbox->comp_code) != BLOGIC_INBOX_FREE) {
-               /*
-                  We are only allowed to do this because we limit our
-                  architectures we run on to machines where bus_to_virt(
-                  actually works.  There *needs* to be a dma_addr_to_virt()
-                  in the new PCI DMA mapping interface to replace
-                  bus_to_virt() or else this code is going to become very
-                  innefficient.
-                */
-               struct blogic_ccb *ccb =
-                       (struct blogic_ccb *) bus_to_virt(next_inbox->ccb);
-               if (comp_code != BLOGIC_CMD_NOTFOUND) {
+               struct blogic_ccb *ccb = blogic_inbox_to_ccb(adapter, next_inbox);
+               if (!ccb) {
+                       /*
+                        * This should never happen, unless the CCB list is
+                        * corrupted in memory.
+                        */
+                       blogic_warn("Could not find CCB for dma address %x\n", adapter, next_inbox->ccb);
+               } else if (comp_code != BLOGIC_CMD_NOTFOUND) {
                        if (ccb->status == BLOGIC_CCB_ACTIVE ||
                                        ccb->status == BLOGIC_CCB_RESET) {
                                /*
index a9fe515..955cb69 100644 (file)
@@ -458,17 +458,6 @@ config SCSI_MVUMI
          To compile this driver as a module, choose M here: the
          module will be called mvumi.
 
-config SCSI_DPT_I2O
-       tristate "Adaptec I2O RAID support "
-       depends on SCSI && PCI && VIRT_TO_BUS
-       help
-         This driver supports all of Adaptec's I2O based RAID controllers as 
-         well as the DPT SmartRaid V cards.  This is an Adaptec maintained
-         driver by Deanna Bonds.  See <file:Documentation/scsi/dpti.rst>.
-
-         To compile this driver as a module, choose M here: the
-         module will be called dpt_i2o.
-
 config SCSI_ADVANSYS
        tristate "AdvanSys SCSI support"
        depends on SCSI
@@ -513,7 +502,7 @@ config SCSI_HPTIOP
 
 config SCSI_BUSLOGIC
        tristate "BusLogic SCSI support"
-       depends on PCI && SCSI && VIRT_TO_BUS
+       depends on PCI && SCSI
        help
          This is support for BusLogic MultiMaster and FlashPoint SCSI Host
          Adapters. Consult the SCSI-HOWTO, available from
index 2ad3bc0..f055bfd 100644 (file)
@@ -63,7 +63,6 @@ obj-$(CONFIG_BVME6000_SCSI)   += 53c700.o     bvme6000_scsi.o
 obj-$(CONFIG_SCSI_SIM710)      += 53c700.o     sim710.o
 obj-$(CONFIG_SCSI_ADVANSYS)    += advansys.o
 obj-$(CONFIG_SCSI_BUSLOGIC)    += BusLogic.o
-obj-$(CONFIG_SCSI_DPT_I2O)     += dpt_i2o.o
 obj-$(CONFIG_SCSI_ARCMSR)      += arcmsr/
 obj-$(CONFIG_SCSI_AHA152X)     += aha152x.o
 obj-$(CONFIG_SCSI_AHA1542)     += aha1542.o
index cf703a1..7431240 100644 (file)
 struct a2091_hostdata {
        struct WD33C93_hostdata wh;
        struct a2091_scsiregs *regs;
+       struct device *dev;
 };
 
+#define DMA_DIR(d)   ((d == DATA_OUT_DIR) ? DMA_TO_DEVICE : DMA_FROM_DEVICE)
+
 static irqreturn_t a2091_intr(int irq, void *data)
 {
        struct Scsi_Host *instance = data;
@@ -45,15 +48,31 @@ static irqreturn_t a2091_intr(int irq, void *data)
 static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
 {
        struct scsi_pointer *scsi_pointer = WD33C93_scsi_pointer(cmd);
+       unsigned long len = scsi_pointer->this_residual;
        struct Scsi_Host *instance = cmd->device->host;
        struct a2091_hostdata *hdata = shost_priv(instance);
        struct WD33C93_hostdata *wh = &hdata->wh;
        struct a2091_scsiregs *regs = hdata->regs;
        unsigned short cntr = CNTR_PDMD | CNTR_INTEN;
-       unsigned long addr = virt_to_bus(scsi_pointer->ptr);
+       dma_addr_t addr;
+
+       addr = dma_map_single(hdata->dev, scsi_pointer->ptr,
+                             len, DMA_DIR(dir_in));
+       if (dma_mapping_error(hdata->dev, addr)) {
+               dev_warn(hdata->dev, "cannot map SCSI data block %p\n",
+                        scsi_pointer->ptr);
+               return 1;
+       }
+       scsi_pointer->dma_handle = addr;
 
        /* don't allow DMA if the physical address is bad */
        if (addr & A2091_XFER_MASK) {
+               /* drop useless mapping */
+               dma_unmap_single(hdata->dev, scsi_pointer->dma_handle,
+                                scsi_pointer->this_residual,
+                                DMA_DIR(dir_in));
+               scsi_pointer->dma_handle = (dma_addr_t) NULL;
+
                wh->dma_bounce_len = (scsi_pointer->this_residual + 511) & ~0x1ff;
                wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len,
                                                GFP_KERNEL);
@@ -64,8 +83,21 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
                        return 1;
                }
 
-               /* get the physical address of the bounce buffer */
-               addr = virt_to_bus(wh->dma_bounce_buffer);
+               if (!dir_in) {
+                       /* copy to bounce buffer for a write */
+                       memcpy(wh->dma_bounce_buffer, scsi_pointer->ptr,
+                              scsi_pointer->this_residual);
+               }
+
+               /* will flush/invalidate cache for us */
+               addr = dma_map_single(hdata->dev, wh->dma_bounce_buffer,
+                                     wh->dma_bounce_len, DMA_DIR(dir_in));
+               /* can't map buffer; use PIO */
+               if (dma_mapping_error(hdata->dev, addr)) {
+                       dev_warn(hdata->dev, "cannot map bounce buffer %p\n",
+                                wh->dma_bounce_buffer);
+                       return 1;
+               }
 
                /* the bounce buffer may not be in the first 16M of physmem */
                if (addr & A2091_XFER_MASK) {
@@ -76,11 +108,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
                        return 1;
                }
 
-               if (!dir_in) {
-                       /* copy to bounce buffer for a write */
-                       memcpy(wh->dma_bounce_buffer, scsi_pointer->ptr,
-                              scsi_pointer->this_residual);
-               }
+               scsi_pointer->dma_handle = addr;
        }
 
        /* setup dma direction */
@@ -95,13 +123,8 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
        /* setup DMA *physical* address */
        regs->ACR = addr;
 
-       if (dir_in) {
-               /* invalidate any cache */
-               cache_clear(addr, scsi_pointer->this_residual);
-       } else {
-               /* push any dirty cache */
-               cache_push(addr, scsi_pointer->this_residual);
-       }
+       /* no more cache flush here - dma_map_single() takes care */
+
        /* start DMA */
        regs->ST_DMA = 1;
 
@@ -142,6 +165,10 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
        /* restore the CONTROL bits (minus the direction flag) */
        regs->CNTR = CNTR_PDMD | CNTR_INTEN;
 
+       dma_unmap_single(hdata->dev, scsi_pointer->dma_handle,
+                        scsi_pointer->this_residual,
+                        DMA_DIR(wh->dma_dir));
+
        /* copy from a bounce buffer, if necessary */
        if (status && wh->dma_bounce_buffer) {
                if (wh->dma_dir)
@@ -178,6 +205,11 @@ static int a2091_probe(struct zorro_dev *z, const struct zorro_device_id *ent)
        wd33c93_regs wdregs;
        struct a2091_hostdata *hdata;
 
+       if (dma_set_mask_and_coherent(&z->dev, DMA_BIT_MASK(24))) {
+               dev_warn(&z->dev, "cannot use 24 bit DMA\n");
+               return -ENODEV;
+       }
+
        if (!request_mem_region(z->resource.start, 256, "wd33c93"))
                return -EBUSY;
 
@@ -198,6 +230,7 @@ static int a2091_probe(struct zorro_dev *z, const struct zorro_device_id *ent)
        wdregs.SCMD = &regs->SCMD;
 
        hdata = shost_priv(instance);
+       hdata->dev = &z->dev;
        hdata->wh.no_sync = 0xff;
        hdata->wh.fast = 0;
        hdata->wh.dma_mode = CTRL_DMA;
index dd16188..2c5cb1a 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/module.h>
 
 #include <asm/page.h>
 struct a3000_hostdata {
        struct WD33C93_hostdata wh;
        struct a3000_scsiregs *regs;
+       struct device *dev;
 };
 
+#define DMA_DIR(d)   ((d == DATA_OUT_DIR) ? DMA_TO_DEVICE : DMA_FROM_DEVICE)
+
 static irqreturn_t a3000_intr(int irq, void *data)
 {
        struct Scsi_Host *instance = data;
@@ -49,20 +53,38 @@ static irqreturn_t a3000_intr(int irq, void *data)
 static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
 {
        struct scsi_pointer *scsi_pointer = WD33C93_scsi_pointer(cmd);
+       unsigned long len = scsi_pointer->this_residual;
        struct Scsi_Host *instance = cmd->device->host;
        struct a3000_hostdata *hdata = shost_priv(instance);
        struct WD33C93_hostdata *wh = &hdata->wh;
        struct a3000_scsiregs *regs = hdata->regs;
        unsigned short cntr = CNTR_PDMD | CNTR_INTEN;
-       unsigned long addr = virt_to_bus(scsi_pointer->ptr);
+       dma_addr_t addr;
+
+       addr = dma_map_single(hdata->dev, scsi_pointer->ptr,
+                             len, DMA_DIR(dir_in));
+       if (dma_mapping_error(hdata->dev, addr)) {
+               dev_warn(hdata->dev, "cannot map SCSI data block %p\n",
+                        scsi_pointer->ptr);
+               return 1;
+       }
+       scsi_pointer->dma_handle = addr;
 
        /*
         * if the physical address has the wrong alignment, or if
         * physical address is bad, or if it is a write and at the
         * end of a physical memory chunk, then allocate a bounce
         * buffer
+        * MSch 20220629 - only wrong alignment tested - bounce
+        * buffer returned by kmalloc is guaranteed to be aligned
         */
        if (addr & A3000_XFER_MASK) {
+               WARN_ONCE(1, "Invalid alignment for DMA!");
+               /* drop useless mapping */
+               dma_unmap_single(hdata->dev, scsi_pointer->dma_handle,
+                                scsi_pointer->this_residual,
+                                DMA_DIR(dir_in));
+
                wh->dma_bounce_len = (scsi_pointer->this_residual + 511) & ~0x1ff;
                wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len,
                                                GFP_KERNEL);
@@ -70,6 +92,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
                /* can't allocate memory; use PIO */
                if (!wh->dma_bounce_buffer) {
                        wh->dma_bounce_len = 0;
+                       scsi_pointer->dma_handle = (dma_addr_t) NULL;
                        return 1;
                }
 
@@ -79,7 +102,15 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
                               scsi_pointer->this_residual);
                }
 
-               addr = virt_to_bus(wh->dma_bounce_buffer);
+               addr = dma_map_single(hdata->dev, scsi_pointer->ptr,
+                                     len, DMA_DIR(dir_in));
+               if (dma_mapping_error(hdata->dev, addr)) {
+                       dev_warn(hdata->dev,
+                                "cannot map SCSI data block %p\n",
+                                scsi_pointer->ptr);
+                       return 1;
+               }
+               scsi_pointer->dma_handle = addr;
        }
 
        /* setup dma direction */
@@ -94,13 +125,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
        /* setup DMA *physical* address */
        regs->ACR = addr;
 
-       if (dir_in) {
-               /* invalidate any cache */
-               cache_clear(addr, scsi_pointer->this_residual);
-       } else {
-               /* push any dirty cache */
-               cache_push(addr, scsi_pointer->this_residual);
-       }
+       /* no more cache flush here - dma_map_single() takes care */
 
        /* start DMA */
        mb();                   /* make sure setup is completed */
@@ -151,6 +176,10 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
        regs->CNTR = CNTR_PDMD | CNTR_INTEN;
        mb();                   /* make sure CNTR is updated before next IO */
 
+       dma_unmap_single(hdata->dev, scsi_pointer->dma_handle,
+                        scsi_pointer->this_residual,
+                        DMA_DIR(wh->dma_dir));
+
        /* copy from a bounce buffer, if necessary */
        if (status && wh->dma_bounce_buffer) {
                if (SCpnt) {
@@ -193,6 +222,11 @@ static int __init amiga_a3000_scsi_probe(struct platform_device *pdev)
        wd33c93_regs wdregs;
        struct a3000_hostdata *hdata;
 
+       if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
+               dev_warn(&pdev->dev, "cannot use 32 bit DMA\n");
+               return -ENODEV;
+       }
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res)
                return -ENODEV;
@@ -216,6 +250,7 @@ static int __init amiga_a3000_scsi_probe(struct platform_device *pdev)
        wdregs.SCMD = &regs->SCMD;
 
        hdata = shost_priv(instance);
+       hdata->dev = &pdev->dev;
        hdata->wh.no_sync = 0xff;
        hdata->wh.fast = 0;
        hdata->wh.dma_mode = CTRL_DMA;
index 81462f4..4d4cb47 100644 (file)
@@ -1050,7 +1050,7 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
                                vpdpage83data.type1.productid));
 
                        /* Convert to ascii based serial number.
-                        * The LSB is the the end.
+                        * The LSB is the end.
                         */
                        for (i = 0; i < 8; i++) {
                                u8 temp =
index 73506a4..91d196f 100644 (file)
@@ -159,7 +159,7 @@ static int asd_init_target_ddb(struct domain_device *dev)
                flags |= OPEN_REQUIRED;
                if ((dev->dev_type == SAS_SATA_DEV) ||
                    (dev->tproto & SAS_PROTOCOL_STP)) {
-                       struct smp_resp *rps_resp = &dev->sata_dev.rps_resp;
+                       struct smp_rps_resp *rps_resp = &dev->sata_dev.rps_resp;
                        if (rps_resp->frame_type == SMP_RESPONSE &&
                            rps_resp->function == SMP_REPORT_PHY_SATA &&
                            rps_resp->result == SMP_RESP_FUNC_ACC) {
index 3bb0ade..50a577a 100644 (file)
@@ -231,6 +231,7 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
        cls_session = starget_to_session(scsi_target(sc->device));
        session = cls_session->dd_data;
 
+completion_check:
        /* check if we raced, task just got cleaned up under us */
        spin_lock_bh(&session->back_lock);
        if (!abrt_task || !abrt_task->sc) {
@@ -238,7 +239,13 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
                return SUCCESS;
        }
        /* get a task ref till FW processes the req for the ICD used */
-       __iscsi_get_task(abrt_task);
+       if (!iscsi_get_task(abrt_task)) {
+               spin_unlock(&session->back_lock);
+               /* We are just about to call iscsi_free_task so wait for it. */
+               udelay(5);
+               goto completion_check;
+       }
+
        abrt_io_task = abrt_task->dd_data;
        conn = abrt_task->conn;
        beiscsi_conn = conn->dd_data;
@@ -323,7 +330,15 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
                }
 
                /* get a task ref till FW processes the req for the ICD used */
-               __iscsi_get_task(task);
+               if (!iscsi_get_task(task)) {
+                       /*
+                        * The task has completed in the driver and is
+                        * completing in libiscsi. Just ignore it here. When we
+                        * call iscsi_eh_device_reset, it will wait for us.
+                        */
+                       continue;
+               }
+
                io_task = task->dd_data;
                /* mark WRB invalid which have been not processed by FW yet */
                if (is_chip_be2_be3r(phba)) {
@@ -5745,7 +5760,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
        cancel_work_sync(&phba->sess_work);
 
        beiscsi_iface_destroy_default(phba);
-       iscsi_host_remove(phba->shost);
+       iscsi_host_remove(phba->shost, false);
        beiscsi_disable_port(phba, 1);
 
        /* after cancelling boot_work */
index 15fbd09..a3c800e 100644 (file)
@@ -909,7 +909,7 @@ void bnx2i_free_hba(struct bnx2i_hba *hba)
 {
        struct Scsi_Host *shost = hba->shost;
 
-       iscsi_host_remove(shost);
+       iscsi_host_remove(shost, false);
        INIT_LIST_HEAD(&hba->ep_ofld_list);
        INIT_LIST_HEAD(&hba->ep_active_list);
        INIT_LIST_HEAD(&hba->ep_destroy_list);
index 4365d52..af281e2 100644 (file)
@@ -328,7 +328,7 @@ void cxgbi_hbas_remove(struct cxgbi_device *cdev)
                chba = cdev->hbas[i];
                if (chba) {
                        cdev->hbas[i] = NULL;
-                       iscsi_host_remove(chba->shost);
+                       iscsi_host_remove(chba->shost, false);
                        pci_dev_put(cdev->pdev);
                        iscsi_host_free(chba->shost);
                }
@@ -1455,7 +1455,7 @@ void cxgbi_conn_tx_open(struct cxgbi_sock *csk)
        if (conn) {
                log_debug(1 << CXGBI_DBG_SOCK,
                        "csk 0x%p, cid %d.\n", csk, conn->id);
-               iscsi_conn_queue_work(conn);
+               iscsi_conn_queue_xmit(conn);
        }
 }
 EXPORT_SYMBOL_GPL(cxgbi_conn_tx_open);
diff --git a/drivers/scsi/dpt/dpti_i2o.h b/drivers/scsi/dpt/dpti_i2o.h
deleted file mode 100644 (file)
index e1fbbf5..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _SCSI_I2O_H
-#define _SCSI_I2O_H
-
-/* I2O kernel space accessible structures/APIs
- *
- * (c) Copyright 1999, 2000 Red Hat Software
- *
- *************************************************************************
- *
- * This header file defined the I2O APIs/structures for use by
- * the I2O kernel modules.
- */
-
-#ifdef __KERNEL__       /* This file to be included by kernel only */
-
-#include <linux/i2o-dev.h>
-
-#include <linux/notifier.h>
-#include <linux/atomic.h>
-
-
-/*
- *     Tunable parameters first
- */
-
-/* How many different OSM's are we allowing */
-#define MAX_I2O_MODULES                64
-
-#define I2O_EVT_CAPABILITY_OTHER               0x01
-#define I2O_EVT_CAPABILITY_CHANGED             0x02
-
-#define I2O_EVT_SENSOR_STATE_CHANGED           0x01
-
-//#ifdef __KERNEL__   /* ioctl stuff only thing exported to users */
-
-#define I2O_MAX_MANAGERS       4
-
-/*
- *     I2O Interface Objects
- */
-
-#include <linux/wait.h>
-typedef wait_queue_head_t adpt_wait_queue_head_t;
-#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait)
-typedef wait_queue_entry_t adpt_wait_queue_entry_t;
-
-/*
- * message structures
- */
-
-struct i2o_message
-{
-       u8      version_offset;
-       u8      flags;
-       u16     size;
-       u32     target_tid:12;
-       u32     init_tid:12;
-       u32     function:8;
-       u32     initiator_context;
-       /* List follows */
-};
-
-struct adpt_device;
-struct _adpt_hba;
-struct i2o_device
-{
-       struct i2o_device *next;        /* Chain */
-       struct i2o_device *prev;
-
-       char dev_name[8];               /* linux /dev name if available */
-       i2o_lct_entry lct_data;/* Device LCT information */
-       u32 flags;
-       struct proc_dir_entry* proc_entry;      /* /proc dir */
-       struct adpt_device *owner;
-       struct _adpt_hba *controller;   /* Controlling IOP */
-};
-
-/*
- *     Each I2O controller has one of these objects
- */
-
-struct i2o_controller
-{
-       char name[16];
-       int unit;
-       int type;
-       int enabled;
-
-       struct notifier_block *event_notifer;   /* Events */
-       atomic_t users;
-       struct i2o_device *devices;             /* I2O device chain */
-       struct i2o_controller *next;            /* Controller chain */
-
-};
-
-/*
- * I2O System table entry
- */
-struct i2o_sys_tbl_entry
-{
-       u16     org_id;
-       u16     reserved1;
-       u32     iop_id:12;
-       u32     reserved2:20;
-       u16     seg_num:12;
-       u16     i2o_version:4;
-       u8      iop_state;
-       u8      msg_type;
-       u16     frame_size;
-       u16     reserved3;
-       u32     last_changed;
-       u32     iop_capabilities;
-       u32     inbound_low;
-       u32     inbound_high;
-};
-
-struct i2o_sys_tbl
-{
-       u8      num_entries;
-       u8      version;
-       u16     reserved1;
-       u32     change_ind;
-       u32     reserved2;
-       u32     reserved3;
-       struct i2o_sys_tbl_entry iops[];
-};
-
-/*
- *     I2O classes / subclasses
- */
-
-/*  Class ID and Code Assignments
- *  (LCT.ClassID.Version field)
- */
-#define    I2O_CLASS_VERSION_10                        0x00
-#define    I2O_CLASS_VERSION_11                        0x01
-
-/*  Class code names
- *  (from v1.5 Table 6-1 Class Code Assignments.)
- */
-
-#define    I2O_CLASS_EXECUTIVE                         0x000
-#define    I2O_CLASS_DDM                               0x001
-#define    I2O_CLASS_RANDOM_BLOCK_STORAGE              0x010
-#define    I2O_CLASS_SEQUENTIAL_STORAGE                0x011
-#define    I2O_CLASS_LAN                               0x020
-#define    I2O_CLASS_WAN                               0x030
-#define    I2O_CLASS_FIBRE_CHANNEL_PORT                0x040
-#define    I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL          0x041
-#define    I2O_CLASS_SCSI_PERIPHERAL                   0x051
-#define    I2O_CLASS_ATE_PORT                          0x060
-#define    I2O_CLASS_ATE_PERIPHERAL                    0x061
-#define    I2O_CLASS_FLOPPY_CONTROLLER                 0x070
-#define    I2O_CLASS_FLOPPY_DEVICE                     0x071
-#define    I2O_CLASS_BUS_ADAPTER_PORT                  0x080
-#define    I2O_CLASS_PEER_TRANSPORT_AGENT              0x090
-#define    I2O_CLASS_PEER_TRANSPORT                    0x091
-
-/*  Rest of 0x092 - 0x09f reserved for peer-to-peer classes
- */
-
-#define    I2O_CLASS_MATCH_ANYCLASS                    0xffffffff
-
-/*  Subclasses
- */
-
-#define    I2O_SUBCLASS_i960                           0x001
-#define    I2O_SUBCLASS_HDM                            0x020
-#define    I2O_SUBCLASS_ISM                            0x021
-
-/* Operation functions */
-
-#define I2O_PARAMS_FIELD_GET   0x0001
-#define I2O_PARAMS_LIST_GET    0x0002
-#define I2O_PARAMS_MORE_GET    0x0003
-#define I2O_PARAMS_SIZE_GET    0x0004
-#define I2O_PARAMS_TABLE_GET   0x0005
-#define I2O_PARAMS_FIELD_SET   0x0006
-#define I2O_PARAMS_LIST_SET    0x0007
-#define I2O_PARAMS_ROW_ADD     0x0008
-#define I2O_PARAMS_ROW_DELETE  0x0009
-#define I2O_PARAMS_TABLE_CLEAR 0x000A
-
-/*
- *     I2O serial number conventions / formats
- *     (circa v1.5)
- */
-
-#define    I2O_SNFORMAT_UNKNOWN                        0
-#define    I2O_SNFORMAT_BINARY                         1
-#define    I2O_SNFORMAT_ASCII                          2
-#define    I2O_SNFORMAT_UNICODE                        3
-#define    I2O_SNFORMAT_LAN48_MAC                      4
-#define    I2O_SNFORMAT_WAN                            5
-
-/* Plus new in v2.0 (Yellowstone pdf doc)
- */
-
-#define    I2O_SNFORMAT_LAN64_MAC                      6
-#define    I2O_SNFORMAT_DDM                            7
-#define    I2O_SNFORMAT_IEEE_REG64                     8
-#define    I2O_SNFORMAT_IEEE_REG128                    9
-#define    I2O_SNFORMAT_UNKNOWN2                       0xff
-
-/* Transaction Reply Lists (TRL) Control Word structure */
-
-#define TRL_SINGLE_FIXED_LENGTH                0x00
-#define TRL_SINGLE_VARIABLE_LENGTH     0x40
-#define TRL_MULTIPLE_FIXED_LENGTH      0x80
-
-/*
- *     Messaging API values
- */
-
-#define        I2O_CMD_ADAPTER_ASSIGN          0xB3
-#define        I2O_CMD_ADAPTER_READ            0xB2
-#define        I2O_CMD_ADAPTER_RELEASE         0xB5
-#define        I2O_CMD_BIOS_INFO_SET           0xA5
-#define        I2O_CMD_BOOT_DEVICE_SET         0xA7
-#define        I2O_CMD_CONFIG_VALIDATE         0xBB
-#define        I2O_CMD_CONN_SETUP              0xCA
-#define        I2O_CMD_DDM_DESTROY             0xB1
-#define        I2O_CMD_DDM_ENABLE              0xD5
-#define        I2O_CMD_DDM_QUIESCE             0xC7
-#define        I2O_CMD_DDM_RESET               0xD9
-#define        I2O_CMD_DDM_SUSPEND             0xAF
-#define        I2O_CMD_DEVICE_ASSIGN           0xB7
-#define        I2O_CMD_DEVICE_RELEASE          0xB9
-#define        I2O_CMD_HRT_GET                 0xA8
-#define        I2O_CMD_ADAPTER_CLEAR           0xBE
-#define        I2O_CMD_ADAPTER_CONNECT         0xC9
-#define        I2O_CMD_ADAPTER_RESET           0xBD
-#define        I2O_CMD_LCT_NOTIFY              0xA2
-#define        I2O_CMD_OUTBOUND_INIT           0xA1
-#define        I2O_CMD_PATH_ENABLE             0xD3
-#define        I2O_CMD_PATH_QUIESCE            0xC5
-#define        I2O_CMD_PATH_RESET              0xD7
-#define        I2O_CMD_STATIC_MF_CREATE        0xDD
-#define        I2O_CMD_STATIC_MF_RELEASE       0xDF
-#define        I2O_CMD_STATUS_GET              0xA0
-#define        I2O_CMD_SW_DOWNLOAD             0xA9
-#define        I2O_CMD_SW_UPLOAD               0xAB
-#define        I2O_CMD_SW_REMOVE               0xAD
-#define        I2O_CMD_SYS_ENABLE              0xD1
-#define        I2O_CMD_SYS_MODIFY              0xC1
-#define        I2O_CMD_SYS_QUIESCE             0xC3
-#define        I2O_CMD_SYS_TAB_SET             0xA3
-
-#define I2O_CMD_UTIL_NOP               0x00
-#define I2O_CMD_UTIL_ABORT             0x01
-#define I2O_CMD_UTIL_CLAIM             0x09
-#define I2O_CMD_UTIL_RELEASE           0x0B
-#define I2O_CMD_UTIL_PARAMS_GET                0x06
-#define I2O_CMD_UTIL_PARAMS_SET                0x05
-#define I2O_CMD_UTIL_EVT_REGISTER      0x13
-#define I2O_CMD_UTIL_EVT_ACK           0x14
-#define I2O_CMD_UTIL_CONFIG_DIALOG     0x10
-#define I2O_CMD_UTIL_DEVICE_RESERVE    0x0D
-#define I2O_CMD_UTIL_DEVICE_RELEASE    0x0F
-#define I2O_CMD_UTIL_LOCK              0x17
-#define I2O_CMD_UTIL_LOCK_RELEASE      0x19
-#define I2O_CMD_UTIL_REPLY_FAULT_NOTIFY        0x15
-
-#define I2O_CMD_SCSI_EXEC              0x81
-#define I2O_CMD_SCSI_ABORT             0x83
-#define I2O_CMD_SCSI_BUSRESET          0x27
-
-#define I2O_CMD_BLOCK_READ             0x30
-#define I2O_CMD_BLOCK_WRITE            0x31
-#define I2O_CMD_BLOCK_CFLUSH           0x37
-#define I2O_CMD_BLOCK_MLOCK            0x49
-#define I2O_CMD_BLOCK_MUNLOCK          0x4B
-#define I2O_CMD_BLOCK_MMOUNT           0x41
-#define I2O_CMD_BLOCK_MEJECT           0x43
-
-#define I2O_PRIVATE_MSG                        0xFF
-
-/*
- *     Init Outbound Q status
- */
-
-#define I2O_CMD_OUTBOUND_INIT_IN_PROGRESS      0x01
-#define I2O_CMD_OUTBOUND_INIT_REJECTED         0x02
-#define I2O_CMD_OUTBOUND_INIT_FAILED           0x03
-#define I2O_CMD_OUTBOUND_INIT_COMPLETE         0x04
-
-/*
- *     I2O Get Status State values
- */
-
-#define        ADAPTER_STATE_INITIALIZING              0x01
-#define        ADAPTER_STATE_RESET                     0x02
-#define        ADAPTER_STATE_HOLD                      0x04
-#define ADAPTER_STATE_READY                    0x05
-#define        ADAPTER_STATE_OPERATIONAL               0x08
-#define        ADAPTER_STATE_FAILED                    0x10
-#define        ADAPTER_STATE_FAULTED                   0x11
-
-/* I2O API function return values */
-
-#define I2O_RTN_NO_ERROR                       0
-#define I2O_RTN_NOT_INIT                       1
-#define I2O_RTN_FREE_Q_EMPTY                   2
-#define I2O_RTN_TCB_ERROR                      3
-#define I2O_RTN_TRANSACTION_ERROR              4
-#define I2O_RTN_ADAPTER_ALREADY_INIT           5
-#define I2O_RTN_MALLOC_ERROR                   6
-#define I2O_RTN_ADPTR_NOT_REGISTERED           7
-#define I2O_RTN_MSG_REPLY_TIMEOUT              8
-#define I2O_RTN_NO_STATUS                      9
-#define I2O_RTN_NO_FIRM_VER                    10
-#define        I2O_RTN_NO_LINK_SPEED                   11
-
-/* Reply message status defines for all messages */
-
-#define I2O_REPLY_STATUS_SUCCESS                       0x00
-#define I2O_REPLY_STATUS_ABORT_DIRTY                   0x01
-#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER                0x02
-#define        I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER         0x03
-#define        I2O_REPLY_STATUS_ERROR_DIRTY                    0x04
-#define        I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER         0x05
-#define        I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER         0x06
-#define        I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY            0x08
-#define        I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER 0x09
-#define        I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER 0x0A
-#define        I2O_REPLY_STATUS_TRANSACTION_ERROR              0x0B
-#define        I2O_REPLY_STATUS_PROGRESS_REPORT                0x80
-
-/* Status codes and Error Information for Parameter functions */
-
-#define I2O_PARAMS_STATUS_SUCCESS              0x00
-#define I2O_PARAMS_STATUS_BAD_KEY_ABORT                0x01
-#define I2O_PARAMS_STATUS_BAD_KEY_CONTINUE     0x02
-#define I2O_PARAMS_STATUS_BUFFER_FULL          0x03
-#define I2O_PARAMS_STATUS_BUFFER_TOO_SMALL     0x04
-#define I2O_PARAMS_STATUS_FIELD_UNREADABLE     0x05
-#define I2O_PARAMS_STATUS_FIELD_UNWRITEABLE    0x06
-#define I2O_PARAMS_STATUS_INSUFFICIENT_FIELDS  0x07
-#define I2O_PARAMS_STATUS_INVALID_GROUP_ID     0x08
-#define I2O_PARAMS_STATUS_INVALID_OPERATION    0x09
-#define I2O_PARAMS_STATUS_NO_KEY_FIELD         0x0A
-#define I2O_PARAMS_STATUS_NO_SUCH_FIELD                0x0B
-#define I2O_PARAMS_STATUS_NON_DYNAMIC_GROUP    0x0C
-#define I2O_PARAMS_STATUS_OPERATION_ERROR      0x0D
-#define I2O_PARAMS_STATUS_SCALAR_ERROR         0x0E
-#define I2O_PARAMS_STATUS_TABLE_ERROR          0x0F
-#define I2O_PARAMS_STATUS_WRONG_GROUP_TYPE     0x10
-
-/* DetailedStatusCode defines for Executive, DDM, Util and Transaction error
- * messages: Table 3-2 Detailed Status Codes.*/
-
-#define I2O_DSC_SUCCESS                        0x0000
-#define I2O_DSC_BAD_KEY                        0x0002
-#define I2O_DSC_TCL_ERROR                      0x0003
-#define I2O_DSC_REPLY_BUFFER_FULL              0x0004
-#define I2O_DSC_NO_SUCH_PAGE                   0x0005
-#define I2O_DSC_INSUFFICIENT_RESOURCE_SOFT     0x0006
-#define I2O_DSC_INSUFFICIENT_RESOURCE_HARD     0x0007
-#define I2O_DSC_CHAIN_BUFFER_TOO_LARGE         0x0009
-#define I2O_DSC_UNSUPPORTED_FUNCTION           0x000A
-#define I2O_DSC_DEVICE_LOCKED                  0x000B
-#define I2O_DSC_DEVICE_RESET                   0x000C
-#define I2O_DSC_INAPPROPRIATE_FUNCTION         0x000D
-#define I2O_DSC_INVALID_INITIATOR_ADDRESS      0x000E
-#define I2O_DSC_INVALID_MESSAGE_FLAGS          0x000F
-#define I2O_DSC_INVALID_OFFSET                 0x0010
-#define I2O_DSC_INVALID_PARAMETER              0x0011
-#define I2O_DSC_INVALID_REQUEST                0x0012
-#define I2O_DSC_INVALID_TARGET_ADDRESS         0x0013
-#define I2O_DSC_MESSAGE_TOO_LARGE              0x0014
-#define I2O_DSC_MESSAGE_TOO_SMALL              0x0015
-#define I2O_DSC_MISSING_PARAMETER              0x0016
-#define I2O_DSC_TIMEOUT                        0x0017
-#define I2O_DSC_UNKNOWN_ERROR                  0x0018
-#define I2O_DSC_UNKNOWN_FUNCTION               0x0019
-#define I2O_DSC_UNSUPPORTED_VERSION            0x001A
-#define I2O_DSC_DEVICE_BUSY                    0x001B
-#define I2O_DSC_DEVICE_NOT_AVAILABLE           0x001C
-
-/* Device Claim Types */
-#define        I2O_CLAIM_PRIMARY                                       0x01000000
-#define        I2O_CLAIM_MANAGEMENT                                    0x02000000
-#define        I2O_CLAIM_AUTHORIZED                                    0x03000000
-#define        I2O_CLAIM_SECONDARY                                     0x04000000
-
-/* Message header defines for VersionOffset */
-#define I2OVER15       0x0001
-#define I2OVER20       0x0002
-/* Default is 1.5, FIXME: Need support for both 1.5 and 2.0 */
-#define I2OVERSION     I2OVER15
-#define SGL_OFFSET_0    I2OVERSION
-#define SGL_OFFSET_4    (0x0040 | I2OVERSION)
-#define SGL_OFFSET_5    (0x0050 | I2OVERSION)
-#define SGL_OFFSET_6    (0x0060 | I2OVERSION)
-#define SGL_OFFSET_7    (0x0070 | I2OVERSION)
-#define SGL_OFFSET_8    (0x0080 | I2OVERSION)
-#define SGL_OFFSET_9    (0x0090 | I2OVERSION)
-#define SGL_OFFSET_10   (0x00A0 | I2OVERSION)
-#define SGL_OFFSET_12   (0x00C0 | I2OVERSION)
-
-#define TRL_OFFSET_5    (0x0050 | I2OVERSION)
-#define TRL_OFFSET_6    (0x0060 | I2OVERSION)
-
- /* msg header defines for MsgFlags */
-#define MSG_STATIC     0x0100
-#define MSG_64BIT_CNTXT        0x0200
-#define MSG_MULTI_TRANS        0x1000
-#define MSG_FAIL       0x2000
-#define MSG_LAST       0x4000
-#define MSG_REPLY      0x8000
-
- /* minimum size msg */
-#define THREE_WORD_MSG_SIZE    0x00030000
-#define FOUR_WORD_MSG_SIZE     0x00040000
-#define FIVE_WORD_MSG_SIZE     0x00050000
-#define SIX_WORD_MSG_SIZE      0x00060000
-#define SEVEN_WORD_MSG_SIZE    0x00070000
-#define EIGHT_WORD_MSG_SIZE    0x00080000
-#define NINE_WORD_MSG_SIZE     0x00090000
-#define TEN_WORD_MSG_SIZE      0x000A0000
-#define I2O_MESSAGE_SIZE(x)    ((x)<<16)
-
-
-/* Special TID Assignments */
-
-#define ADAPTER_TID            0
-#define HOST_TID               1
-
-#define MSG_FRAME_SIZE         128
-#define NMBR_MSG_FRAMES                128
-
-#define MSG_POOL_SIZE          16384
-
-#define I2O_POST_WAIT_OK       0
-#define I2O_POST_WAIT_TIMEOUT  -ETIMEDOUT
-
-
-#endif /* __KERNEL__ */
-
-#endif /* _SCSI_I2O_H */
diff --git a/drivers/scsi/dpt/dpti_ioctl.h b/drivers/scsi/dpt/dpti_ioctl.h
deleted file mode 100644 (file)
index 25e9251..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/***************************************************************************
-                          dpti_ioctl.h  -  description
-                             -------------------
-    begin                : Thu Sep 7 2000
-    copyright            : (C) 2001 by Adaptec
-
-    See Documentation/scsi/dpti.rst for history, notes, license info
-    and credits
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *                                                                         *
- ***************************************************************************/
-
-/***************************************************************************
- * This file is generated from  osd_unix.h                                 *
- * *************************************************************************/
-
-#ifndef _dpti_ioctl_h
-#define _dpti_ioctl_h
-
-// IOCTL interface commands
-
-#ifndef _IOWR
-# define _IOWR(x,y,z)  (((x)<<8)|y)
-#endif
-#ifndef _IOW
-# define _IOW(x,y,z)   (((x)<<8)|y)
-#endif
-#ifndef _IOR
-# define _IOR(x,y,z)   (((x)<<8)|y)
-#endif
-#ifndef _IO
-# define _IO(x,y)      (((x)<<8)|y)
-#endif
-/* EATA PassThrough Command    */
-#define EATAUSRCMD      _IOWR('D',65,EATA_CP)
-/* Set Debug Level If Enabled  */
-#define DPT_DEBUG       _IOW('D',66,int)
-/* Get Signature Structure     */
-#define DPT_SIGNATURE   _IOR('D',67,dpt_sig_S)
-#if defined __bsdi__
-#define DPT_SIGNATURE_PACKED   _IOR('D',67,dpt_sig_S_Packed)
-#endif
-/* Get Number Of DPT Adapters  */
-#define DPT_NUMCTRLS    _IOR('D',68,int)
-/* Get Adapter Info Structure  */
-#define DPT_CTRLINFO    _IOR('D',69,CtrlInfo)
-/* Get Statistics If Enabled   */
-#define DPT_STATINFO    _IO('D',70)
-/* Clear Stats If Enabled      */
-#define DPT_CLRSTAT     _IO('D',71)
-/* Get System Info Structure   */
-#define DPT_SYSINFO     _IOR('D',72,sysInfo_S)
-/* Set Timeout Value           */
-#define DPT_TIMEOUT     _IO('D',73)
-/* Get config Data             */
-#define DPT_CONFIG      _IO('D',74)
-/* Get Blink LED Code          */
-#define DPT_BLINKLED    _IOR('D',75,int)
-/* Get Statistical information (if available) */
-#define DPT_STATS_INFO        _IOR('D',80,STATS_DATA)
-/* Clear the statistical information          */
-#define DPT_STATS_CLEAR       _IO('D',81)
-/* Get Performance metrics */
-#define DPT_PERF_INFO        _IOR('D',82,dpt_perf_t)
-/* Send an I2O command */
-#define I2OUSRCMD      _IO('D',76)
-/* Inform driver to re-acquire LCT information */
-#define I2ORESCANCMD   _IO('D',77)
-/* Inform driver to reset adapter */
-#define I2ORESETCMD    _IO('D',78)
-/* See if the target is mounted */
-#define DPT_TARGET_BUSY        _IOR('D',79, TARGET_BUSY_T)
-
-
-  /* Structure Returned From Get Controller Info                             */
-
-typedef struct {
-       uCHAR    state;            /* Operational state               */
-       uCHAR    id;               /* Host adapter SCSI id            */
-       int      vect;             /* Interrupt vector number         */
-       int      base;             /* Base I/O address                */
-       int      njobs;            /* # of jobs sent to HA            */
-       int      qdepth;           /* Controller queue depth.         */
-       int      wakebase;         /* mpx wakeup base index.          */
-       uINT     SGsize;           /* Scatter/Gather list size.       */
-       unsigned heads;            /* heads for drives on cntlr.      */
-       unsigned sectors;          /* sectors for drives on cntlr.    */
-       uCHAR    do_drive32;       /* Flag for Above 16 MB Ability    */
-       uCHAR    BusQuiet;         /* SCSI Bus Quiet Flag             */
-       char     idPAL[4];         /* 4 Bytes Of The ID Pal           */
-       uCHAR    primary;          /* 1 For Primary, 0 For Secondary  */
-       uCHAR    eataVersion;      /* EATA Version                    */
-       uINT     cpLength;         /* EATA Command Packet Length      */
-       uINT     spLength;         /* EATA Status Packet Length       */
-       uCHAR    drqNum;           /* DRQ Index (0,5,6,7)             */
-       uCHAR    flag1;            /* EATA Flags 1 (Byte 9)           */
-       uCHAR    flag2;            /* EATA Flags 2 (Byte 30)          */
-} CtrlInfo;
-
-typedef struct {
-       uSHORT length;          // Remaining length of this
-       uSHORT drvrHBAnum;      // Relative HBA # used by the driver
-       uINT baseAddr;          // Base I/O address
-       uSHORT blinkState;      // Blink LED state (0=Not in blink LED)
-       uCHAR pciBusNum;        // PCI Bus # (Optional)
-       uCHAR pciDeviceNum;     // PCI Device # (Optional)
-       uSHORT hbaFlags;        // Miscellaneous HBA flags
-       uSHORT Interrupt;       // Interrupt set for this device.
-#   if (defined(_DPT_ARC))
-       uINT baseLength;
-       ADAPTER_OBJECT *AdapterObject;
-       LARGE_INTEGER DmaLogicalAddress;
-       PVOID DmaVirtualAddress;
-       LARGE_INTEGER ReplyLogicalAddress;
-       PVOID ReplyVirtualAddress;
-#   else
-       uINT reserved1;         // Reserved for future expansion
-       uINT reserved2;         // Reserved for future expansion
-       uINT reserved3;         // Reserved for future expansion
-#   endif
-} drvrHBAinfo_S;
-
-typedef struct TARGET_BUSY
-{
-  uLONG channel;
-  uLONG id;
-  uLONG lun;
-  uLONG isBusy;
-} TARGET_BUSY_T;
-
-#endif
-
diff --git a/drivers/scsi/dpt/dptsig.h b/drivers/scsi/dpt/dptsig.h
deleted file mode 100644 (file)
index a6644b3..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/*     BSDI dptsig.h,v 1.7 1998/06/03 19:15:00 karels Exp      */
-
-/*
- * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
- * All rights reserved.
- *
- * Redistribution and use in source form, with or without modification, are
- * permitted provided that redistributions of source code must retain the
- * above copyright notice, this list of conditions and the following disclaimer.
- *
- * This software is provided `as is' by Distributed Processing Technology and
- * any express or implied warranties, including, but not limited to, the
- * implied warranties of merchantability and fitness for a particular purpose,
- * are disclaimed. In no event shall Distributed Processing Technology be
- * liable for any direct, indirect, incidental, special, exemplary or
- * consequential damages (including, but not limited to, procurement of
- * substitute goods or services; loss of use, data, or profits; or business
- * interruptions) however caused and on any theory of liability, whether in
- * contract, strict liability, or tort (including negligence or otherwise)
- * arising in any way out of the use of this driver software, even if advised
- * of the possibility of such damage.
- *
- */
-
-#ifndef __DPTSIG_H_
-#define __DPTSIG_H_
-#ifdef _SINIX_ADDON
-#include "dpt.h"
-#endif
-/* DPT SIGNATURE SPEC AND HEADER FILE                           */
-/* Signature Version 1 (sorry no 'A')                           */
-
-/* to make sure we are talking the same size under all OS's     */
-typedef unsigned char sigBYTE;
-typedef unsigned short sigWORD;
-typedef unsigned int sigINT;
-
-/*
- * use sigWORDLittleEndian for:
- *  dsCapabilities
- *  dsDeviceSupp
- *  dsAdapterSupp
- *  dsApplication
- * use sigLONGLittleEndian for:
- *      dsOS
- * so that the sig can be standardised to Little Endian
- */
-#if (defined(_DPT_BIG_ENDIAN))
-# define sigWORDLittleEndian(x) ((((x)&0xFF)<<8)|(((x)>>8)&0xFF))
-# define sigLONGLittleEndian(x) \
-        ((((x)&0xFF)<<24) |             \
-         (((x)&0xFF00)<<8) |    \
-         (((x)&0xFF0000L)>>8) | \
-         (((x)&0xFF000000L)>>24))
-#else
-# define sigWORDLittleEndian(x) (x)
-# define sigLONGLittleEndian(x) (x)
-#endif
-
-/* must make sure the structure is not word or double-word aligned      */
-/* ---------------------------------------------------------------      */
-/* Borland will ignore the following pragma:                            */
-/* Word alignment is OFF by default.  If in the, IDE make               */
-/* sure that Options | Compiler | Code Generation | Word Alignment      */
-/* is not checked.  If using BCC, do not use the -a option.             */
-
-#ifndef NO_PACK
-#if defined (_DPT_AIX)
-#pragma options align=packed
-#else
-#pragma pack(1)
-#endif  /* aix */
-#endif
-/* For the Macintosh */
-#ifdef STRUCTALIGNMENTSUPPORTED
-#pragma options align=mac68k
-#endif
-
-
-/* Current Signature Version - sigBYTE dsSigVersion; */
-/* ------------------------------------------------------------------ */
-#define SIG_VERSION 1
-
-/* Processor Family - sigBYTE dsProcessorFamily;  DISTINCT VALUES */
-/* ------------------------------------------------------------------ */
-/* What type of processor the file is meant to run on. */
-/* This will let us know whether to read sigWORDs as high/low or low/high. */
-#define PROC_INTEL      0x00    /* Intel 80x86/ia64 */
-#define PROC_MOTOROLA   0x01    /* Motorola 68K */
-#define PROC_MIPS4000   0x02    /* MIPS RISC 4000 */
-#define PROC_ALPHA      0x03    /* DEC Alpha */
-#define PROC_POWERPC    0x04    /* IBM Power PC */
-#define PROC_i960       0x05    /* Intel i960 */
-#define PROC_ULTRASPARC 0x06    /* SPARC processor */
-
-/* Specific Minimim Processor - sigBYTE dsProcessor;    FLAG BITS */
-/* ------------------------------------------------------------------ */
-/* Different bit definitions dependent on processor_family */
-
-/* PROC_INTEL: */
-#define PROC_8086       0x01    /* Intel 8086 */
-#define PROC_286        0x02    /* Intel 80286 */
-#define PROC_386        0x04    /* Intel 80386 */
-#define PROC_486        0x08    /* Intel 80486 */
-#define PROC_PENTIUM    0x10    /* Intel 586 aka P5 aka Pentium */
-#define PROC_SEXIUM    0x20    /* Intel 686 aka P6 aka Pentium Pro or MMX */
-#define PROC_IA64      0x40    /* Intel IA64 processor */
-
-/* PROC_i960: */
-#define PROC_960RX      0x01    /* Intel 80960RC/RD */
-#define PROC_960HX      0x02    /* Intel 80960HA/HD/HT */
-
-/* PROC_MOTOROLA: */
-#define PROC_68000      0x01    /* Motorola 68000 */
-#define PROC_68010     0x02    /* Motorola 68010 */
-#define PROC_68020      0x04    /* Motorola 68020 */
-#define PROC_68030      0x08    /* Motorola 68030 */
-#define PROC_68040      0x10    /* Motorola 68040 */
-
-/* PROC_POWERPC */
-#define PROC_PPC601            0x01    /* PowerPC 601 */
-#define PROC_PPC603            0x02    /* PowerPC 603 */
-#define PROC_PPC604            0x04    /* PowerPC 604 */
-
-/* PROC_MIPS4000: */
-#define PROC_R4000      0x01    /* MIPS R4000 */
-
-/* Filetype - sigBYTE dsFiletype;       DISTINCT VALUES */
-/* ------------------------------------------------------------------ */
-#define FT_EXECUTABLE   0       /* Executable Program */
-#define FT_SCRIPT       1       /* Script/Batch File??? */
-#define FT_HBADRVR      2       /* HBA Driver */
-#define FT_OTHERDRVR    3       /* Other Driver */
-#define FT_IFS          4       /* Installable Filesystem Driver */
-#define FT_ENGINE       5       /* DPT Engine */
-#define FT_COMPDRVR     6       /* Compressed Driver Disk */
-#define FT_LANGUAGE     7       /* Foreign Language file */
-#define FT_FIRMWARE     8       /* Downloadable or actual Firmware */
-#define FT_COMMMODL     9       /* Communications Module */
-#define FT_INT13        10      /* INT 13 style HBA Driver */
-#define FT_HELPFILE     11      /* Help file */
-#define FT_LOGGER       12      /* Event Logger */
-#define FT_INSTALL      13      /* An Install Program */
-#define FT_LIBRARY      14      /* Storage Manager Real-Mode Calls */
-#define FT_RESOURCE    15      /* Storage Manager Resource File */
-#define FT_MODEM_DB    16      /* Storage Manager Modem Database */
-
-/* Filetype flags - sigBYTE dsFiletypeFlags;    FLAG BITS */
-/* ------------------------------------------------------------------ */
-#define FTF_DLL         0x01    /* Dynamic Link Library */
-#define FTF_NLM         0x02    /* Netware Loadable Module */
-#define FTF_OVERLAYS    0x04    /* Uses overlays */
-#define FTF_DEBUG       0x08    /* Debug version */
-#define FTF_TSR         0x10    /* TSR */
-#define FTF_SYS         0x20    /* DOS Loadable driver */
-#define FTF_PROTECTED   0x40    /* Runs in protected mode */
-#define FTF_APP_SPEC    0x80    /* Application Specific */
-#define FTF_ROM                (FTF_SYS|FTF_TSR)       /* Special Case */
-
-/* OEM - sigBYTE dsOEM;         DISTINCT VALUES */
-/* ------------------------------------------------------------------ */
-#define OEM_DPT         0       /* DPT */
-#define OEM_ATT         1       /* ATT */
-#define OEM_NEC         2       /* NEC */
-#define OEM_ALPHA       3       /* Alphatronix */
-#define OEM_AST         4       /* AST */
-#define OEM_OLIVETTI    5       /* Olivetti */
-#define OEM_SNI         6       /* Siemens/Nixdorf */
-#define OEM_SUN         7       /* SUN Microsystems */
-
-/* Operating System  - sigLONG dsOS;    FLAG BITS */
-/* ------------------------------------------------------------------ */
-#define OS_DOS          0x00000001 /* PC/MS-DOS                                */
-#define OS_WINDOWS      0x00000002 /* Microsoft Windows 3.x            */
-#define OS_WINDOWS_NT   0x00000004 /* Microsoft Windows NT             */
-#define OS_OS2M         0x00000008 /* OS/2 1.2.x,MS 1.3.0,IBM 1.3.x - Monolithic */
-#define OS_OS2L         0x00000010 /* Microsoft OS/2 1.301 - LADDR     */
-#define OS_OS22x        0x00000020 /* IBM OS/2 2.x                     */
-#define OS_NW286        0x00000040 /* Novell NetWare 286               */
-#define OS_NW386        0x00000080 /* Novell NetWare 386               */
-#define OS_GEN_UNIX     0x00000100 /* Generic Unix                     */
-#define OS_SCO_UNIX     0x00000200 /* SCO Unix                         */
-#define OS_ATT_UNIX     0x00000400 /* ATT Unix                         */
-#define OS_UNIXWARE     0x00000800 /* USL Unix                         */
-#define OS_INT_UNIX     0x00001000 /* Interactive Unix                 */
-#define OS_SOLARIS      0x00002000 /* SunSoft Solaris                  */
-#define OS_QNX          0x00004000 /* QNX for Tom Moch                 */
-#define OS_NEXTSTEP     0x00008000 /* NeXTSTEP/OPENSTEP/MACH           */
-#define OS_BANYAN       0x00010000 /* Banyan Vines                     */
-#define OS_OLIVETTI_UNIX 0x00020000/* Olivetti Unix                    */
-#define OS_MAC_OS      0x00040000 /* Mac OS                            */
-#define OS_WINDOWS_95  0x00080000 /* Microsoft Windows '95             */
-#define OS_NW4x                0x00100000 /* Novell Netware 4.x                */
-#define OS_BSDI_UNIX   0x00200000 /* BSDi Unix BSD/OS 2.0 and up       */
-#define OS_AIX_UNIX     0x00400000 /* AIX Unix                         */
-#define OS_FREE_BSD    0x00800000 /* FreeBSD Unix                      */
-#define OS_LINUX       0x01000000 /* Linux                             */
-#define OS_DGUX_UNIX   0x02000000 /* Data General Unix                 */
-#define OS_SINIX_N      0x04000000 /* SNI SINIX-N                      */
-#define OS_PLAN9       0x08000000 /* ATT Plan 9                        */
-#define OS_TSX         0x10000000 /* SNH TSX-32                        */
-
-#define OS_OTHER        0x80000000 /* Other                            */
-
-/* Capabilities - sigWORD dsCapabilities;        FLAG BITS */
-/* ------------------------------------------------------------------ */
-#define CAP_RAID0       0x0001  /* RAID-0 */
-#define CAP_RAID1       0x0002  /* RAID-1 */
-#define CAP_RAID3       0x0004  /* RAID-3 */
-#define CAP_RAID5       0x0008  /* RAID-5 */
-#define CAP_SPAN        0x0010  /* Spanning */
-#define CAP_PASS        0x0020  /* Provides passthrough */
-#define CAP_OVERLAP     0x0040  /* Passthrough supports overlapped commands */
-#define CAP_ASPI        0x0080  /* Supports ASPI Command Requests */
-#define CAP_ABOVE16MB   0x0100  /* ISA Driver supports greater than 16MB */
-#define CAP_EXTEND      0x8000  /* Extended info appears after description */
-#ifdef SNI_MIPS
-#define CAP_CACHEMODE   0x1000  /* dpt_force_cache is set in driver */
-#endif
-
-/* Devices Supported - sigWORD dsDeviceSupp;    FLAG BITS */
-/* ------------------------------------------------------------------ */
-#define DEV_DASD        0x0001  /* DASD (hard drives) */
-#define DEV_TAPE        0x0002  /* Tape drives */
-#define DEV_PRINTER     0x0004  /* Printers */
-#define DEV_PROC        0x0008  /* Processors */
-#define DEV_WORM        0x0010  /* WORM drives */
-#define DEV_CDROM       0x0020  /* CD-ROM drives */
-#define DEV_SCANNER     0x0040  /* Scanners */
-#define DEV_OPTICAL     0x0080  /* Optical Drives */
-#define DEV_JUKEBOX     0x0100  /* Jukebox */
-#define DEV_COMM        0x0200  /* Communications Devices */
-#define DEV_OTHER       0x0400  /* Other Devices */
-#define DEV_ALL         0xFFFF  /* All SCSI Devices */
-
-/* Adapters Families Supported - sigWORD dsAdapterSupp; FLAG BITS */
-/* ------------------------------------------------------------------ */
-#define ADF_2001        0x0001  /* PM2001           */
-#define ADF_2012A       0x0002  /* PM2012A          */
-#define ADF_PLUS_ISA    0x0004  /* PM2011,PM2021    */
-#define ADF_PLUS_EISA   0x0008  /* PM2012B,PM2022   */
-#define ADF_SC3_ISA    0x0010  /* PM2021           */
-#define ADF_SC3_EISA   0x0020  /* PM2022,PM2122, etc */
-#define ADF_SC3_PCI    0x0040  /* SmartCache III PCI */
-#define ADF_SC4_ISA    0x0080  /* SmartCache IV ISA */
-#define ADF_SC4_EISA   0x0100  /* SmartCache IV EISA */
-#define ADF_SC4_PCI    0x0200  /* SmartCache IV PCI */
-#define ADF_SC5_PCI    0x0400  /* Fifth Generation I2O products */
-/*
- *     Combinations of products
- */
-#define ADF_ALL_2000   (ADF_2001|ADF_2012A)
-#define ADF_ALL_PLUS   (ADF_PLUS_ISA|ADF_PLUS_EISA)
-#define ADF_ALL_SC3    (ADF_SC3_ISA|ADF_SC3_EISA|ADF_SC3_PCI)
-#define ADF_ALL_SC4    (ADF_SC4_ISA|ADF_SC4_EISA|ADF_SC4_PCI)
-#define ADF_ALL_SC5    (ADF_SC5_PCI)
-/* All EATA Cacheing Products */
-#define ADF_ALL_CACHE  (ADF_ALL_PLUS|ADF_ALL_SC3|ADF_ALL_SC4)
-/* All EATA Bus Mastering Products */
-#define ADF_ALL_MASTER (ADF_2012A|ADF_ALL_CACHE)
-/* All EATA Adapter Products */
-#define ADF_ALL_EATA   (ADF_2001|ADF_ALL_MASTER)
-#define ADF_ALL                ADF_ALL_EATA
-
-/* Application - sigWORD dsApplication;         FLAG BITS */
-/* ------------------------------------------------------------------ */
-#define APP_DPTMGR      0x0001  /* DPT Storage Manager */
-#define APP_ENGINE      0x0002  /* DPT Engine */
-#define APP_SYTOS       0x0004  /* Sytron Sytos Plus */
-#define APP_CHEYENNE    0x0008  /* Cheyenne ARCServe + ARCSolo */
-#define APP_MSCDEX      0x0010  /* Microsoft CD-ROM extensions */
-#define APP_NOVABACK    0x0020  /* NovaStor Novaback */
-#define APP_AIM         0x0040  /* Archive Information Manager */
-
-/* Requirements - sigBYTE dsRequirements;         FLAG BITS             */
-/* ------------------------------------------------------------------   */
-#define REQ_SMARTROM    0x01    /* Requires SmartROM to be present      */
-#define REQ_DPTDDL      0x02    /* Requires DPTDDL.SYS to be loaded     */
-#define REQ_HBA_DRIVER  0x04    /* Requires an HBA driver to be loaded  */
-#define REQ_ASPI_TRAN   0x08    /* Requires an ASPI Transport Modules   */
-#define REQ_ENGINE      0x10    /* Requires a DPT Engine to be loaded   */
-#define REQ_COMM_ENG    0x20    /* Requires a DPT Communications Engine */
-
-/*
- * You may adjust dsDescription_size with an override to a value less than
- * 50 so that the structure allocates less real space.
- */
-#if (!defined(dsDescription_size))
-# define dsDescription_size 50
-#endif
-
-typedef struct dpt_sig {
-    char    dsSignature[6];      /* ALWAYS "dPtSiG" */
-    sigBYTE dsSigVersion;        /* signature version (currently 1) */
-    sigBYTE dsProcessorFamily;   /* what type of processor */
-    sigBYTE dsProcessor;         /* precise processor */
-    sigBYTE dsFiletype;          /* type of file */
-    sigBYTE dsFiletypeFlags;     /* flags to specify load type, etc. */
-    sigBYTE dsOEM;               /* OEM file was created for */
-    sigINT  dsOS;                /* which Operating systems */
-    sigWORD dsCapabilities;      /* RAID levels, etc. */
-    sigWORD dsDeviceSupp;        /* Types of SCSI devices supported */
-    sigWORD dsAdapterSupp;       /* DPT adapter families supported */
-    sigWORD dsApplication;       /* applications file is for */
-    sigBYTE dsRequirements;      /* Other driver dependencies */
-    sigBYTE dsVersion;           /* 1 */
-    sigBYTE dsRevision;          /* 'J' */
-    sigBYTE dsSubRevision;       /* '9'   ' ' if N/A */
-    sigBYTE dsMonth;             /* creation month */
-    sigBYTE dsDay;               /* creation day */
-    sigBYTE dsYear;              /* creation year since 1980 (1993=13) */
-    /* description (NULL terminated) */
-    char  dsDescription[dsDescription_size];
-} dpt_sig_S;
-/* 32 bytes minimum - with no description.  Put NULL at description[0] */
-/* 81 bytes maximum - with 49 character description plus NULL. */
-
-/* This line added at Roycroft's request */
-/* Microsoft's NT compiler gets confused if you do a pack and don't */
-/* restore it. */
-
-#ifndef NO_UNPACK
-#if defined (_DPT_AIX)
-#pragma options align=reset
-#elif defined (UNPACK_FOUR)
-#pragma pack(4)
-#else
-#pragma pack()
-#endif  /* aix */
-#endif
-/* For the Macintosh */
-#ifdef STRUCTALIGNMENTSUPPORTED
-#pragma options align=reset
-#endif
-
-#endif
diff --git a/drivers/scsi/dpt/osd_defs.h b/drivers/scsi/dpt/osd_defs.h
deleted file mode 100644 (file)
index de3ae57..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*     BSDI osd_defs.h,v 1.4 1998/06/03 19:14:58 karels Exp    */
-/*
- * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
- * All rights reserved.
- *
- * Redistribution and use in source form, with or without modification, are
- * permitted provided that redistributions of source code must retain the
- * above copyright notice, this list of conditions and the following disclaimer.
- *
- * This software is provided `as is' by Distributed Processing Technology and
- * any express or implied warranties, including, but not limited to, the
- * implied warranties of merchantability and fitness for a particular purpose,
- * are disclaimed. In no event shall Distributed Processing Technology be
- * liable for any direct, indirect, incidental, special, exemplary or
- * consequential damages (including, but not limited to, procurement of
- * substitute goods or services; loss of use, data, or profits; or business
- * interruptions) however caused and on any theory of liability, whether in
- * contract, strict liability, or tort (including negligence or otherwise)
- * arising in any way out of the use of this driver software, even if advised
- * of the possibility of such damage.
- *
- */
-
-#ifndef                _OSD_DEFS_H
-#define                _OSD_DEFS_H
-
-/*File - OSD_DEFS.H
- ****************************************************************************
- *
- *Description:
- *
- *     This file contains the OS dependent defines.  This file is included
- *in osd_util.h and provides the OS specific defines for that file.
- *
- *Copyright Distributed Processing Technology, Corp.
- *       140 Candace Dr.
- *       Maitland, Fl. 32751   USA
- *       Phone: (407) 830-5522  Fax: (407) 260-5366
- *       All Rights Reserved
- *
- *Author:      Doug Anderson
- *Date:                1/31/94
- *
- *Editors:
- *
- *Remarks:
- *
- *
- *****************************************************************************/
-
-
-/*Definitions - Defines & Constants ----------------------------------------- */
-
-  /* Define the operating system */
-#if (defined(__linux__))
-# define _DPT_LINUX
-#elif (defined(__bsdi__))
-# define _DPT_BSDI
-#elif (defined(__FreeBSD__))
-# define _DPT_FREE_BSD
-#else
-# define _DPT_SCO
-#endif
-
-#if defined (ZIL_CURSES)
-#define                _DPT_CURSES
-#else
-#define         _DPT_MOTIF
-#endif
-
-  /* Redefine 'far' to nothing - no far pointer type required in UNIX */
-#define                far
-
-  /* Define the mutually exclusive semaphore type */
-#define                SEMAPHORE_T     unsigned int *
-  /* Define a handle to a DLL */
-#define                DLL_HANDLE_T    unsigned int *
-
-#endif
diff --git a/drivers/scsi/dpt/osd_util.h b/drivers/scsi/dpt/osd_util.h
deleted file mode 100644 (file)
index b2613c2..0000000
+++ /dev/null
@@ -1,358 +0,0 @@
-/*     BSDI osd_util.h,v 1.8 1998/06/03 19:14:58 karels Exp    */
-
-/*
- * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
- * All rights reserved.
- *
- * Redistribution and use in source form, with or without modification, are
- * permitted provided that redistributions of source code must retain the
- * above copyright notice, this list of conditions and the following disclaimer.
- *
- * This software is provided `as is' by Distributed Processing Technology and
- * any express or implied warranties, including, but not limited to, the
- * implied warranties of merchantability and fitness for a particular purpose,
- * are disclaimed. In no event shall Distributed Processing Technology be
- * liable for any direct, indirect, incidental, special, exemplary or
- * consequential damages (including, but not limited to, procurement of
- * substitute goods or services; loss of use, data, or profits; or business
- * interruptions) however caused and on any theory of liability, whether in
- * contract, strict liability, or tort (including negligence or otherwise)
- * arising in any way out of the use of this driver software, even if advised
- * of the possibility of such damage.
- *
- */
-
-#ifndef         __OSD_UTIL_H
-#define         __OSD_UTIL_H
-
-/*File - OSD_UTIL.H
- ****************************************************************************
- *
- *Description:
- *
- *      This file contains defines and function prototypes that are
- *operating system dependent.  The resources defined in this file
- *are not specific to any particular application.
- *
- *Copyright Distributed Processing Technology, Corp.
- *        140 Candace Dr.
- *        Maitland, Fl. 32751   USA
- *        Phone: (407) 830-5522  Fax: (407) 260-5366
- *        All Rights Reserved
- *
- *Author:       Doug Anderson
- *Date:         1/7/94
- *
- *Editors:
- *
- *Remarks:
- *
- *
- *****************************************************************************/
-
-
-/*Definitions - Defines & Constants ----------------------------------------- */
-
-/*----------------------------- */
-/* Operating system selections: */
-/*----------------------------- */
-
-/*#define               _DPT_MSDOS      */
-/*#define               _DPT_WIN_3X     */
-/*#define               _DPT_WIN_4X     */
-/*#define               _DPT_WIN_NT     */
-/*#define               _DPT_NETWARE    */
-/*#define               _DPT_OS2        */
-/*#define               _DPT_SCO        */
-/*#define               _DPT_UNIXWARE   */
-/*#define               _DPT_SOLARIS    */
-/*#define               _DPT_NEXTSTEP   */
-/*#define               _DPT_BANYAN     */
-
-/*-------------------------------- */
-/* Include the OS specific defines */
-/*-------------------------------- */
-
-/*#define       OS_SELECTION    From Above List */
-/*#define       SEMAPHORE_T     ??? */
-/*#define       DLL_HANDLE_T    ??? */
-
-#if (defined(KERNEL) && (defined(__FreeBSD__) || defined(__bsdi__)))
-# include        "i386/isa/dpt_osd_defs.h"
-#else
-# include        "osd_defs.h"
-#endif
-
-#ifndef DPT_UNALIGNED
-   #define      DPT_UNALIGNED
-#endif
-
-#ifndef DPT_EXPORT
-   #define      DPT_EXPORT
-#endif
-
-#ifndef DPT_IMPORT
-   #define      DPT_IMPORT
-#endif
-
-#ifndef DPT_RUNTIME_IMPORT
-   #define      DPT_RUNTIME_IMPORT  DPT_IMPORT
-#endif
-
-/*--------------------- */
-/* OS dependent defines */
-/*--------------------- */
-
-#if defined (_DPT_MSDOS) || defined (_DPT_WIN_3X)
-   #define      _DPT_16_BIT
-#else
-   #define      _DPT_32_BIT
-#endif
-
-#if defined (_DPT_SCO) || defined (_DPT_UNIXWARE) || defined (_DPT_SOLARIS) || defined (_DPT_AIX) || defined (SNI_MIPS) || defined (_DPT_BSDI) || defined (_DPT_FREE_BSD) || defined(_DPT_LINUX)
-   #define      _DPT_UNIX
-#endif
-
-#if defined (_DPT_WIN_3x) || defined (_DPT_WIN_4X) || defined (_DPT_WIN_NT) \
-           || defined (_DPT_OS2)
-   #define      _DPT_DLL_SUPPORT
-#endif
-
-#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X) && !defined (_DPT_NETWARE)
-   #define      _DPT_PREEMPTIVE
-#endif
-
-#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X)
-   #define      _DPT_MULTI_THREADED
-#endif
-
-#if !defined (_DPT_MSDOS)
-   #define      _DPT_MULTI_TASKING
-#endif
-
-  /* These exist for platforms that   */
-  /* chunk when accessing mis-aligned */
-  /* data                             */
-#if defined (SNI_MIPS) || defined (_DPT_SOLARIS)
-   #if defined (_DPT_BIG_ENDIAN)
-       #if !defined (_DPT_STRICT_ALIGN)
-            #define _DPT_STRICT_ALIGN
-       #endif
-   #endif
-#endif
-
-  /* Determine if in C or C++ mode */
-#ifdef  __cplusplus
-   #define      _DPT_CPP
-#else
-   #define      _DPT_C
-#endif
-
-/*-------------------------------------------------------------------*/
-/* Under Solaris the compiler refuses to accept code like:           */
-/*   { {"DPT"}, 0, NULL .... },                                      */
-/* and complains about the {"DPT"} part by saying "cannot use { }    */
-/* to initialize char*".                                             */
-/*                                                                   */
-/* By defining these ugly macros we can get around this and also     */
-/* not have to copy and #ifdef large sections of code.  I know that  */
-/* these macros are *really* ugly, but they should help reduce       */
-/* maintenance in the long run.                                      */
-/*                                                                   */
-/*-------------------------------------------------------------------*/
-#if !defined (DPTSQO)
-   #if defined (_DPT_SOLARIS)
-      #define DPTSQO
-      #define DPTSQC
-   #else
-      #define DPTSQO {
-      #define DPTSQC }
-   #endif  /* solaris */
-#endif  /* DPTSQO */
-
-
-/*---------------------- */
-/* OS dependent typedefs */
-/*---------------------- */
-
-#if defined (_DPT_MSDOS) || defined (_DPT_SCO)
-   #define BYTE unsigned char
-   #define WORD unsigned short
-#endif
-
-#ifndef _DPT_TYPEDEFS
-   #define _DPT_TYPEDEFS
-   typedef unsigned char   uCHAR;
-   typedef unsigned short  uSHORT;
-   typedef unsigned int    uINT;
-   typedef unsigned long   uLONG;
-
-   typedef union {
-        uCHAR        u8[4];
-        uSHORT       u16[2];
-        uLONG        u32;
-   } access_U;
-#endif
-
-#if !defined (NULL)
-   #define      NULL    0
-#endif
-
-
-/*Prototypes - function ----------------------------------------------------- */
-
-#ifdef  __cplusplus
-   extern "C" {         /* Declare all these functions as "C" functions */
-#endif
-
-/*------------------------ */
-/* Byte reversal functions */
-/*------------------------ */
-
-  /* Reverses the byte ordering of a 2 byte variable */
-#if (!defined(osdSwap2))
- uSHORT       osdSwap2(DPT_UNALIGNED uSHORT *);
-#endif  // !osdSwap2
-
-  /* Reverses the byte ordering of a 4 byte variable and shifts left 8 bits */
-#if (!defined(osdSwap3))
- uLONG        osdSwap3(DPT_UNALIGNED uLONG *);
-#endif  // !osdSwap3
-
-
-#ifdef  _DPT_NETWARE
-   #include "novpass.h" /* For DPT_Bswapl() prototype */
-       /* Inline the byte swap */
-   #ifdef __cplusplus
-        inline uLONG osdSwap4(uLONG *inLong) {
-        return *inLong = DPT_Bswapl(*inLong);
-        }
-   #else
-        #define osdSwap4(inLong)       DPT_Bswapl(inLong)
-   #endif  // cplusplus
-#else
-       /* Reverses the byte ordering of a 4 byte variable */
-# if (!defined(osdSwap4))
-   uLONG        osdSwap4(DPT_UNALIGNED uLONG *);
-# endif  // !osdSwap4
-
-  /* The following functions ALWAYS swap regardless of the *
-   * presence of DPT_BIG_ENDIAN                            */
-
-   uSHORT       trueSwap2(DPT_UNALIGNED uSHORT *);
-   uLONG        trueSwap4(DPT_UNALIGNED uLONG *);
-
-#endif  // netware
-
-
-/*-------------------------------------*
- * Network order swap functions        *
- *                                     *
- * These functions/macros will be used *
- * by the structure insert()/extract() *
- * functions.                          *
- *
- * We will enclose all structure       *
- * portability modifications inside    *
- * #ifdefs.  When we are ready, we     *
- * will #define DPT_PORTABLE to begin  *
- * using the modifications.            *
- *-------------------------------------*/
-uLONG  netSwap4(uLONG val);
-
-#if defined (_DPT_BIG_ENDIAN)
-
-// for big-endian we need to swap
-
-#ifndef NET_SWAP_2
-#define NET_SWAP_2(x) (((x) >> 8) | ((x) << 8))
-#endif  // NET_SWAP_2
-
-#ifndef NET_SWAP_4
-#define NET_SWAP_4(x) netSwap4((x))
-#endif  // NET_SWAP_4
-
-#else
-
-// for little-endian we don't need to do anything
-
-#ifndef NET_SWAP_2
-#define NET_SWAP_2(x) (x)
-#endif  // NET_SWAP_2
-
-#ifndef NET_SWAP_4
-#define NET_SWAP_4(x) (x)
-#endif  // NET_SWAP_4
-
-#endif  // big endian
-
-
-
-/*----------------------------------- */
-/* Run-time loadable module functions */
-/*----------------------------------- */
-
-  /* Loads the specified run-time loadable DLL */
-DLL_HANDLE_T    osdLoadModule(uCHAR *);
-  /* Unloads the specified run-time loadable DLL */
-uSHORT          osdUnloadModule(DLL_HANDLE_T);
-  /* Returns a pointer to a function inside a run-time loadable DLL */
-void *          osdGetFnAddr(DLL_HANDLE_T,uCHAR *);
-
-/*--------------------------------------- */
-/* Mutually exclusive semaphore functions */
-/*--------------------------------------- */
-
-  /* Create a named semaphore */
-SEMAPHORE_T     osdCreateNamedSemaphore(char *);
-  /* Create a mutually exlusive semaphore */
-SEMAPHORE_T     osdCreateSemaphore(void);
-       /* create an event semaphore */
-SEMAPHORE_T              osdCreateEventSemaphore(void);
-       /* create a named event semaphore */
-SEMAPHORE_T             osdCreateNamedEventSemaphore(char *);
-
-  /* Destroy the specified mutually exclusive semaphore object */
-uSHORT          osdDestroySemaphore(SEMAPHORE_T);
-  /* Request access to the specified mutually exclusive semaphore */
-uLONG           osdRequestSemaphore(SEMAPHORE_T,uLONG);
-  /* Release access to the specified mutually exclusive semaphore */
-uSHORT          osdReleaseSemaphore(SEMAPHORE_T);
-       /* wait for a event to happen */
-uLONG                            osdWaitForEventSemaphore(SEMAPHORE_T, uLONG);
-       /* signal an event */
-uLONG                            osdSignalEventSemaphore(SEMAPHORE_T);
-       /* reset the event */
-uLONG                            osdResetEventSemaphore(SEMAPHORE_T);
-
-/*----------------- */
-/* Thread functions */
-/*----------------- */
-
-  /* Releases control to the task switcher in non-preemptive */
-  /* multitasking operating systems. */
-void            osdSwitchThreads(void);
-
-  /* Starts a thread function */
-uLONG   osdStartThread(void *,void *);
-
-/* what is my thread id */
-uLONG osdGetThreadID(void);
-
-/* wakes up the specifed thread */
-void osdWakeThread(uLONG);
-
-/* osd sleep for x milliseconds */
-void osdSleep(uLONG);
-
-#define DPT_THREAD_PRIORITY_LOWEST 0x00
-#define DPT_THREAD_PRIORITY_NORMAL 0x01
-#define DPT_THREAD_PRIORITY_HIGHEST 0x02
-
-uCHAR osdSetThreadPriority(uLONG tid, uCHAR priority);
-
-#ifdef __cplusplus
-   }    /* end the xtern "C" declaration */
-#endif
-
-#endif  /* osd_util_h */
diff --git a/drivers/scsi/dpt/sys_info.h b/drivers/scsi/dpt/sys_info.h
deleted file mode 100644 (file)
index a4aa1c3..0000000
+++ /dev/null
@@ -1,417 +0,0 @@
-/*     BSDI sys_info.h,v 1.6 1998/06/03 19:14:59 karels Exp    */
-
-/*
- * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
- * All rights reserved.
- *
- * Redistribution and use in source form, with or without modification, are
- * permitted provided that redistributions of source code must retain the
- * above copyright notice, this list of conditions and the following disclaimer.
- *
- * This software is provided `as is' by Distributed Processing Technology and
- * any express or implied warranties, including, but not limited to, the
- * implied warranties of merchantability and fitness for a particular purpose,
- * are disclaimed. In no event shall Distributed Processing Technology be
- * liable for any direct, indirect, incidental, special, exemplary or
- * consequential damages (including, but not limited to, procurement of
- * substitute goods or services; loss of use, data, or profits; or business
- * interruptions) however caused and on any theory of liability, whether in
- * contract, strict liability, or tort (including negligence or otherwise)
- * arising in any way out of the use of this driver software, even if advised
- * of the possibility of such damage.
- *
- */
-
-#ifndef         __SYS_INFO_H
-#define         __SYS_INFO_H
-
-/*File - SYS_INFO.H
- ****************************************************************************
- *
- *Description:
- *
- *      This file contains structure definitions for the OS dependent
- *layer system information buffers.
- *
- *Copyright Distributed Processing Technology, Corp.
- *        140 Candace Dr.
- *        Maitland, Fl. 32751   USA
- *        Phone: (407) 830-5522  Fax: (407) 260-5366
- *        All Rights Reserved
- *
- *Author:       Don Kemper
- *Date:         5/10/94
- *
- *Editors:
- *
- *Remarks:
- *
- *
- *****************************************************************************/
-
-
-/*Include Files ------------------------------------------------------------- */
-
-#include        "osd_util.h"
-
-#ifndef NO_PACK
-#if defined (_DPT_AIX)
-#pragma options align=packed
-#else
-#pragma pack(1)
-#endif  /* aix */
-#endif  // no unpack
-
-
-/*struct - driveParam_S - start
- *===========================================================================
- *
- *Description:
- *
- *      This structure defines the drive parameters seen during
- *booting.
- *
- *---------------------------------------------------------------------------*/
-
-#ifdef  __cplusplus
-   struct driveParam_S {
-#else
-   typedef struct  {
-#endif
-
-   uSHORT       cylinders;      /* Up to 1024 */
-   uCHAR        heads;          /* Up to 255 */
-   uCHAR        sectors;        /* Up to 63 */
-
-#ifdef  __cplusplus
-
-//---------- Portability Additions ----------- in sp_sinfo.cpp
-#ifdef DPT_PORTABLE
-       uSHORT          netInsert(dptBuffer_S *buffer);
-       uSHORT          netExtract(dptBuffer_S *buffer);
-#endif // DPT PORTABLE
-//--------------------------------------------
-
-   };
-#else
-   } driveParam_S;
-#endif
-/*driveParam_S - end */
-
-
-/*struct - sysInfo_S - start
- *===========================================================================
- *
- *Description:
- *
- *      This structure defines the command system information that
- *should be returned by every OS dependent layer.
- *
- *---------------------------------------------------------------------------*/
-
-/*flags - bit definitions */
-#define SI_CMOS_Valid           0x0001
-#define SI_NumDrivesValid       0x0002
-#define SI_ProcessorValid       0x0004
-#define SI_MemorySizeValid      0x0008
-#define SI_DriveParamsValid     0x0010
-#define SI_SmartROMverValid     0x0020
-#define SI_OSversionValid       0x0040
-#define SI_OSspecificValid      0x0080  /* 1 if OS structure returned */
-#define SI_BusTypeValid         0x0100
-
-#define SI_ALL_VALID            0x0FFF  /* All Std SysInfo is valid */
-#define SI_NO_SmartROM          0x8000
-
-/*busType - definitions */
-#define SI_ISA_BUS      0x00
-#define SI_MCA_BUS      0x01
-#define SI_EISA_BUS     0x02
-#define SI_PCI_BUS      0x04
-
-#ifdef  __cplusplus
-   struct sysInfo_S {
-#else
-   typedef struct  {
-#endif
-
-   uCHAR        drive0CMOS;             /* CMOS Drive 0 Type */
-   uCHAR        drive1CMOS;             /* CMOS Drive 1 Type */
-   uCHAR        numDrives;              /* 0040:0075 contents */
-   uCHAR        processorFamily;        /* Same as DPTSIG's definition */
-   uCHAR        processorType;          /* Same as DPTSIG's definition */
-   uCHAR        smartROMMajorVersion;
-   uCHAR        smartROMMinorVersion;   /* SmartROM version */
-   uCHAR        smartROMRevision;
-   uSHORT       flags;                  /* See bit definitions above */
-   uSHORT       conventionalMemSize;    /* in KB */
-   uINT         extendedMemSize;        /* in KB */
-   uINT         osType;                 /* Same as DPTSIG's definition */
-   uCHAR        osMajorVersion;
-   uCHAR        osMinorVersion;         /* The OS version */
-   uCHAR        osRevision;
-#ifdef _SINIX_ADDON
-   uCHAR        busType;                /* See defininitions above */
-   uSHORT       osSubRevision;
-   uCHAR        pad[2];                 /* For alignment */
-#else
-   uCHAR        osSubRevision;
-   uCHAR        busType;                /* See defininitions above */
-   uCHAR        pad[3];                 /* For alignment */
-#endif
-   driveParam_S drives[16];             /* SmartROM Logical Drives */
-
-#ifdef  __cplusplus
-
-//---------- Portability Additions ----------- in sp_sinfo.cpp
-#ifdef DPT_PORTABLE
-       uSHORT          netInsert(dptBuffer_S *buffer);
-       uSHORT          netExtract(dptBuffer_S *buffer);
-#endif // DPT PORTABLE
-//--------------------------------------------
-
-   };
-#else
-   } sysInfo_S;
-#endif
-/*sysInfo_S - end */
-
-
-/*struct - DOS_Info_S - start
- *===========================================================================
- *
- *Description:
- *
- *      This structure defines the system information specific to a
- *DOS workstation.
- *
- *---------------------------------------------------------------------------*/
-
-/*flags - bit definitions */
-#define DI_DOS_HIGH             0x01    /* DOS is loaded high */
-#define DI_DPMI_VALID           0x02    /* DPMI version is valid */
-
-#ifdef  __cplusplus
-   struct DOS_Info_S {
-#else
-   typedef struct {
-#endif
-
-   uCHAR        flags;          /* See bit definitions above */
-   uSHORT       driverLocation; /* SmartROM BIOS address */
-   uSHORT       DOS_version;
-   uSHORT       DPMI_version;
-
-#ifdef  __cplusplus
-
-//---------- Portability Additions ----------- in sp_sinfo.cpp
-#ifdef DPT_PORTABLE
-       uSHORT          netInsert(dptBuffer_S *buffer);
-       uSHORT          netExtract(dptBuffer_S *buffer);
-#endif // DPT PORTABLE
-//--------------------------------------------
-
-   };
-#else
-   } DOS_Info_S;
-#endif
-/*DOS_Info_S - end */
-
-
-/*struct - Netware_Info_S - start
- *===========================================================================
- *
- *Description:
- *
- *      This structure defines the system information specific to a
- *Netware machine.
- *
- *---------------------------------------------------------------------------*/
-
-#ifdef  __cplusplus
-   struct Netware_Info_S {
-#else
-   typedef struct {
-#endif
-
-   uCHAR        driverName[13];         /* ie PM12NW31.DSK */
-   uCHAR        serverName[48];
-   uCHAR        netwareVersion;         /* The Netware OS version */
-   uCHAR        netwareSubVersion;
-   uCHAR        netwareRevision;
-   uSHORT       maxConnections;         /* Probably  250 or 1000 */
-   uSHORT       connectionsInUse;
-   uSHORT       maxVolumes;
-   uCHAR        unused;
-   uCHAR        SFTlevel;
-   uCHAR        TTSlevel;
-
-   uCHAR        clibMajorVersion;       /* The CLIB.NLM version */
-   uCHAR        clibMinorVersion;
-   uCHAR        clibRevision;
-
-#ifdef  __cplusplus
-
-//---------- Portability Additions ----------- in sp_sinfo.cpp
-#ifdef DPT_PORTABLE
-       uSHORT          netInsert(dptBuffer_S *buffer);
-       uSHORT          netExtract(dptBuffer_S *buffer);
-#endif // DPT PORTABLE
-//--------------------------------------------
-
-   };
-#else
-   } Netware_Info_S;
-#endif
-/*Netware_Info_S - end */
-
-
-/*struct - OS2_Info_S - start
- *===========================================================================
- *
- *Description:
- *
- *      This structure defines the system information specific to an
- *OS/2 machine.
- *
- *---------------------------------------------------------------------------*/
-
-#ifdef  __cplusplus
-   struct OS2_Info_S {
-#else
-   typedef struct {
-#endif
-
-   uCHAR        something;
-
-#ifdef  __cplusplus
-
-//---------- Portability Additions ----------- in sp_sinfo.cpp
-#ifdef DPT_PORTABLE
-       uSHORT          netInsert(dptBuffer_S *buffer);
-       uSHORT          netExtract(dptBuffer_S *buffer);
-#endif // DPT PORTABLE
-//--------------------------------------------
-
-   };
-#else
-   } OS2_Info_S;
-#endif
-/*OS2_Info_S - end */
-
-
-/*struct - WinNT_Info_S - start
- *===========================================================================
- *
- *Description:
- *
- *      This structure defines the system information specific to a
- *Windows NT machine.
- *
- *---------------------------------------------------------------------------*/
-
-#ifdef  __cplusplus
-   struct WinNT_Info_S {
-#else
-   typedef struct {
-#endif
-
-   uCHAR        something;
-
-#ifdef  __cplusplus
-
-//---------- Portability Additions ----------- in sp_sinfo.cpp
-#ifdef DPT_PORTABLE
-       uSHORT          netInsert(dptBuffer_S *buffer);
-       uSHORT          netExtract(dptBuffer_S *buffer);
-#endif // DPT PORTABLE
-//--------------------------------------------
-
-   };
-#else
-   } WinNT_Info_S;
-#endif
-/*WinNT_Info_S - end */
-
-
-/*struct - SCO_Info_S - start
- *===========================================================================
- *
- *Description:
- *
- *      This structure defines the system information specific to an
- *SCO UNIX machine.
- *
- *---------------------------------------------------------------------------*/
-
-#ifdef  __cplusplus
-   struct SCO_Info_S {
-#else
-   typedef struct {
-#endif
-
-   uCHAR        something;
-
-#ifdef  __cplusplus
-
-//---------- Portability Additions ----------- in sp_sinfo.cpp
-#ifdef DPT_PORTABLE
-       uSHORT          netInsert(dptBuffer_S *buffer);
-       uSHORT          netExtract(dptBuffer_S *buffer);
-#endif // DPT PORTABLE
-//--------------------------------------------
-
-   };
-#else
-   } SCO_Info_S;
-#endif
-/*SCO_Info_S - end */
-
-
-/*struct - USL_Info_S - start
- *===========================================================================
- *
- *Description:
- *
- *      This structure defines the system information specific to a
- *USL UNIX machine.
- *
- *---------------------------------------------------------------------------*/
-
-#ifdef  __cplusplus
-   struct USL_Info_S {
-#else
-   typedef struct {
-#endif
-
-   uCHAR        something;
-
-#ifdef  __cplusplus
-
-//---------- Portability Additions ----------- in sp_sinfo.cpp
-#ifdef DPT_PORTABLE
-       uSHORT          netInsert(dptBuffer_S *buffer);
-       uSHORT          netExtract(dptBuffer_S *buffer);
-#endif // DPT PORTABLE
-//--------------------------------------------
-
-   };
-#else
-   } USL_Info_S;
-#endif
-/*USL_Info_S - end */
-
-
-  /* Restore default structure packing */
-#ifndef NO_UNPACK
-#if defined (_DPT_AIX)
-#pragma options align=reset
-#elif defined (UNPACK_FOUR)
-#pragma pack(4)
-#else
-#pragma pack()
-#endif  /* aix */
-#endif  // no unpack
-
-#endif  // __SYS_INFO_H
-
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
deleted file mode 100644 (file)
index 2e9155b..0000000
+++ /dev/null
@@ -1,3545 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/***************************************************************************
-                          dpti.c  -  description
-                             -------------------
-    begin                : Thu Sep 7 2000
-    copyright            : (C) 2000 by Adaptec
-
-                          July 30, 2001 First version being submitted
-                          for inclusion in the kernel.  V2.4
-
-    See Documentation/scsi/dpti.rst for history, notes, license info
-    and credits
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *                                                                         *
- ***************************************************************************/
-/***************************************************************************
- * Sat Dec 20 2003 Go Taniguchi <go@turbolinux.co.jp>
- - Support 2.6 kernel and DMA-mapping
- - ioctl fix for raid tools
- - use schedule_timeout in long long loop
- **************************************************************************/
-
-/*#define DEBUG 1 */
-/*#define UARTDELAY 1 */
-
-#include <linux/module.h>
-#include <linux/pgtable.h>
-
-MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
-MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
-
-////////////////////////////////////////////////////////////////
-
-#include <linux/ioctl.h>       /* For SCSI-Passthrough */
-#include <linux/uaccess.h>
-
-#include <linux/stat.h>
-#include <linux/slab.h>                /* for kmalloc() */
-#include <linux/pci.h>         /* for PCI support */
-#include <linux/proc_fs.h>
-#include <linux/blkdev.h>
-#include <linux/delay.h>       /* for udelay */
-#include <linux/interrupt.h>
-#include <linux/kernel.h>      /* for printk */
-#include <linux/sched.h>
-#include <linux/reboot.h>
-#include <linux/spinlock.h>
-#include <linux/dma-mapping.h>
-
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/mutex.h>
-
-#include <asm/processor.h>     /* for boot_cpu_data */
-#include <asm/io.h>            /* for virt_to_bus, etc. */
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_tcq.h>
-
-#include "dpt/dptsig.h"
-#include "dpti.h"
-
-/*============================================================================
- * Create a binary signature - this is read by dptsig
- * Needed for our management apps
- *============================================================================
- */
-static DEFINE_MUTEX(adpt_mutex);
-static dpt_sig_S DPTI_sig = {
-       {'d', 'P', 't', 'S', 'i', 'G'}, SIG_VERSION,
-#ifdef __i386__
-       PROC_INTEL, PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM,
-#elif defined(__ia64__)
-       PROC_INTEL, PROC_IA64,
-#elif defined(__sparc__)
-       PROC_ULTRASPARC, PROC_ULTRASPARC,
-#elif defined(__alpha__)
-       PROC_ALPHA, PROC_ALPHA,
-#else
-       (-1),(-1),
-#endif
-        FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL,
-       ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION,
-       DPT_MONTH, DPT_DAY, DPT_YEAR, "Adaptec Linux I2O RAID Driver"
-};
-
-
-
-
-/*============================================================================
- * Globals
- *============================================================================
- */
-
-static DEFINE_MUTEX(adpt_configuration_lock);
-
-static struct i2o_sys_tbl *sys_tbl;
-static dma_addr_t sys_tbl_pa;
-static int sys_tbl_ind;
-static int sys_tbl_len;
-
-static adpt_hba* hba_chain = NULL;
-static int hba_count = 0;
-
-static struct class *adpt_sysfs_class;
-
-static long adpt_unlocked_ioctl(struct file *, unsigned int, unsigned long);
-#ifdef CONFIG_COMPAT
-static long compat_adpt_ioctl(struct file *, unsigned int, unsigned long);
-#endif
-
-static const struct file_operations adpt_fops = {
-       .unlocked_ioctl = adpt_unlocked_ioctl,
-       .open           = adpt_open,
-       .release        = adpt_close,
-#ifdef CONFIG_COMPAT
-       .compat_ioctl   = compat_adpt_ioctl,
-#endif
-       .llseek         = noop_llseek,
-};
-
-/* Structures and definitions for synchronous message posting.
- * See adpt_i2o_post_wait() for description
- * */
-struct adpt_i2o_post_wait_data
-{
-       int status;
-       u32 id;
-       adpt_wait_queue_head_t *wq;
-       struct adpt_i2o_post_wait_data *next;
-};
-
-static struct adpt_i2o_post_wait_data *adpt_post_wait_queue = NULL;
-static u32 adpt_post_wait_id = 0;
-static DEFINE_SPINLOCK(adpt_post_wait_lock);
-
-
-/*============================================================================
- *                             Functions
- *============================================================================
- */
-
-static inline int dpt_dma64(adpt_hba *pHba)
-{
-       return (sizeof(dma_addr_t) > 4 && (pHba)->dma64);
-}
-
-static inline u32 dma_high(dma_addr_t addr)
-{
-       return upper_32_bits(addr);
-}
-
-static inline u32 dma_low(dma_addr_t addr)
-{
-       return (u32)addr;
-}
-
-static u8 adpt_read_blink_led(adpt_hba* host)
-{
-       if (host->FwDebugBLEDflag_P) {
-               if( readb(host->FwDebugBLEDflag_P) == 0xbc ){
-                       return readb(host->FwDebugBLEDvalue_P);
-               }
-       }
-       return 0;
-}
-
-/*============================================================================
- * Scsi host template interface functions
- *============================================================================
- */
-
-#ifdef MODULE
-static struct pci_device_id dptids[] = {
-       { PCI_DPT_VENDOR_ID, PCI_DPT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
-       { PCI_DPT_VENDOR_ID, PCI_DPT_RAPTOR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
-       { 0, }
-};
-#endif
-
-MODULE_DEVICE_TABLE(pci,dptids);
-
-static int adpt_detect(struct scsi_host_template* sht)
-{
-       struct pci_dev *pDev = NULL;
-       adpt_hba *pHba;
-       adpt_hba *next;
-
-       PINFO("Detecting Adaptec I2O RAID controllers...\n");
-
-        /* search for all Adatpec I2O RAID cards */
-       while ((pDev = pci_get_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
-               if(pDev->device == PCI_DPT_DEVICE_ID ||
-                  pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
-                       if(adpt_install_hba(sht, pDev) ){
-                               PERROR("Could not Init an I2O RAID device\n");
-                               PERROR("Will not try to detect others.\n");
-                               return hba_count-1;
-                       }
-                       pci_dev_get(pDev);
-               }
-       }
-
-       /* In INIT state, Activate IOPs */
-       for (pHba = hba_chain; pHba; pHba = next) {
-               next = pHba->next;
-               // Activate does get status , init outbound, and get hrt
-               if (adpt_i2o_activate_hba(pHba) < 0) {
-                       adpt_i2o_delete_hba(pHba);
-               }
-       }
-
-
-       /* Active IOPs in HOLD state */
-
-rebuild_sys_tab:
-       if (hba_chain == NULL) 
-               return 0;
-
-       /*
-        * If build_sys_table fails, we kill everything and bail
-        * as we can't init the IOPs w/o a system table
-        */     
-       if (adpt_i2o_build_sys_table() < 0) {
-               adpt_i2o_sys_shutdown();
-               return 0;
-       }
-
-       PDEBUG("HBA's in HOLD state\n");
-
-       /* If IOP don't get online, we need to rebuild the System table */
-       for (pHba = hba_chain; pHba; pHba = pHba->next) {
-               if (adpt_i2o_online_hba(pHba) < 0) {
-                       adpt_i2o_delete_hba(pHba);      
-                       goto rebuild_sys_tab;
-               }
-       }
-
-       /* Active IOPs now in OPERATIONAL state */
-       PDEBUG("HBA's in OPERATIONAL state\n");
-
-       printk("dpti: If you have a lot of devices this could take a few minutes.\n");
-       for (pHba = hba_chain; pHba; pHba = next) {
-               next = pHba->next;
-               printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
-               if (adpt_i2o_lct_get(pHba) < 0){
-                       adpt_i2o_delete_hba(pHba);
-                       continue;
-               }
-
-               if (adpt_i2o_parse_lct(pHba) < 0){
-                       adpt_i2o_delete_hba(pHba);
-                       continue;
-               }
-               adpt_inquiry(pHba);
-       }
-
-       adpt_sysfs_class = class_create(THIS_MODULE, "dpt_i2o");
-       if (IS_ERR(adpt_sysfs_class)) {
-               printk(KERN_WARNING"dpti: unable to create dpt_i2o class\n");
-               adpt_sysfs_class = NULL;
-       }
-
-       for (pHba = hba_chain; pHba; pHba = next) {
-               next = pHba->next;
-               if (adpt_scsi_host_alloc(pHba, sht) < 0){
-                       adpt_i2o_delete_hba(pHba);
-                       continue;
-               }
-               pHba->initialized = TRUE;
-               pHba->state &= ~DPTI_STATE_RESET;
-               if (adpt_sysfs_class) {
-                       struct device *dev = device_create(adpt_sysfs_class,
-                               NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), NULL,
-                               "dpti%d", pHba->unit);
-                       if (IS_ERR(dev)) {
-                               printk(KERN_WARNING"dpti%d: unable to "
-                                       "create device in dpt_i2o class\n",
-                                       pHba->unit);
-                       }
-               }
-       }
-
-       // Register our control device node
-       // nodes will need to be created in /dev to access this
-       // the nodes can not be created from within the driver
-       if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
-               adpt_i2o_sys_shutdown();
-               return 0;
-       }
-       return hba_count;
-}
-
-
-static void adpt_release(adpt_hba *pHba)
-{
-       struct Scsi_Host *shost = pHba->host;
-
-       scsi_remove_host(shost);
-//     adpt_i2o_quiesce_hba(pHba);
-       adpt_i2o_delete_hba(pHba);
-       scsi_host_put(shost);
-}
-
-
-static void adpt_inquiry(adpt_hba* pHba)
-{
-       u32 msg[17]; 
-       u32 *mptr;
-       u32 *lenptr;
-       int direction;
-       int scsidir;
-       u32 len;
-       u32 reqlen;
-       u8* buf;
-       dma_addr_t addr;
-       u8  scb[16];
-       s32 rcode;
-
-       memset(msg, 0, sizeof(msg));
-       buf = dma_alloc_coherent(&pHba->pDev->dev, 80, &addr, GFP_KERNEL);
-       if(!buf){
-               printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
-               return;
-       }
-       memset((void*)buf, 0, 36);
-       
-       len = 36;
-       direction = 0x00000000; 
-       scsidir  =0x40000000;   // DATA IN  (iop<--dev)
-
-       if (dpt_dma64(pHba))
-               reqlen = 17;            // SINGLE SGE, 64 bit
-       else
-               reqlen = 14;            // SINGLE SGE, 32 bit
-       /* Stick the headers on */
-       msg[0] = reqlen<<16 | SGL_OFFSET_12;
-       msg[1] = (0xff<<24|HOST_TID<<12|ADAPTER_TID);
-       msg[2] = 0;
-       msg[3]  = 0;
-       // Adaptec/DPT Private stuff 
-       msg[4] = I2O_CMD_SCSI_EXEC|DPT_ORGANIZATION_ID<<16;
-       msg[5] = ADAPTER_TID | 1<<16 /* Interpret*/;
-       /* Direction, disconnect ok | sense data | simple queue , CDBLen */
-       // I2O_SCB_FLAG_ENABLE_DISCONNECT | 
-       // I2O_SCB_FLAG_SIMPLE_QUEUE_TAG | 
-       // I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
-       msg[6] = scsidir|0x20a00000| 6 /* cmd len*/;
-
-       mptr=msg+7;
-
-       memset(scb, 0, sizeof(scb));
-       // Write SCSI command into the message - always 16 byte block 
-       scb[0] = INQUIRY;
-       scb[1] = 0;
-       scb[2] = 0;
-       scb[3] = 0;
-       scb[4] = 36;
-       scb[5] = 0;
-       // Don't care about the rest of scb
-
-       memcpy(mptr, scb, sizeof(scb));
-       mptr+=4;
-       lenptr=mptr++;          /* Remember me - fill in when we know */
-
-       /* Now fill in the SGList and command */
-       *lenptr = len;
-       if (dpt_dma64(pHba)) {
-               *mptr++ = (0x7C<<24)+(2<<16)+0x02; /* Enable 64 bit */
-               *mptr++ = 1 << PAGE_SHIFT;
-               *mptr++ = 0xD0000000|direction|len;
-               *mptr++ = dma_low(addr);
-               *mptr++ = dma_high(addr);
-       } else {
-               *mptr++ = 0xD0000000|direction|len;
-               *mptr++ = addr;
-       }
-
-       // Send it on it's way
-       rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120);
-       if (rcode != 0) {
-               sprintf(pHba->detail, "Adaptec I2O RAID");
-               printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
-               if (rcode != -ETIME && rcode != -EINTR)
-                       dma_free_coherent(&pHba->pDev->dev, 80, buf, addr);
-       } else {
-               memset(pHba->detail, 0, sizeof(pHba->detail));
-               memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
-               memcpy(&(pHba->detail[16]), " Model: ", 8);
-               memcpy(&(pHba->detail[24]), (u8*) &buf[16], 16);
-               memcpy(&(pHba->detail[40]), " FW: ", 4);
-               memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4);
-               pHba->detail[48] = '\0';        /* precautionary */
-               dma_free_coherent(&pHba->pDev->dev, 80, buf, addr);
-       }
-       adpt_i2o_status_get(pHba);
-       return ;
-}
-
-
-static int adpt_slave_configure(struct scsi_device * device)
-{
-       struct Scsi_Host *host = device->host;
-
-       if (host->can_queue && device->tagged_supported) {
-               scsi_change_queue_depth(device,
-                               host->can_queue - 1);
-       }
-       return 0;
-}
-
-static int adpt_queue_lck(struct scsi_cmnd *cmd)
-{
-       adpt_hba* pHba = NULL;
-       struct adpt_device* pDev = NULL;        /* dpt per device information */
-
-       /*
-        * SCSI REQUEST_SENSE commands will be executed automatically by the 
-        * Host Adapter for any errors, so they should not be executed 
-        * explicitly unless the Sense Data is zero indicating that no error 
-        * occurred.
-        */
-
-       if ((cmd->cmnd[0] == REQUEST_SENSE) && (cmd->sense_buffer[0] != 0)) {
-               cmd->result = (DID_OK << 16);
-               scsi_done(cmd);
-               return 0;
-       }
-
-       pHba = (adpt_hba*)cmd->device->host->hostdata[0];
-       if (!pHba) {
-               return FAILED;
-       }
-
-       rmb();
-       if ((pHba->state) & DPTI_STATE_RESET)
-               return SCSI_MLQUEUE_HOST_BUSY;
-
-       // TODO if the cmd->device if offline then I may need to issue a bus rescan
-       // followed by a get_lct to see if the device is there anymore
-       if((pDev = (struct adpt_device*) (cmd->device->hostdata)) == NULL) {
-               /*
-                * First command request for this device.  Set up a pointer
-                * to the device structure.  This should be a TEST_UNIT_READY
-                * command from scan_scsis_single.
-                */
-               if ((pDev = adpt_find_device(pHba, (u32)cmd->device->channel, (u32)cmd->device->id, cmd->device->lun)) == NULL) {
-                       // TODO: if any luns are at this bus, scsi id then fake a TEST_UNIT_READY and INQUIRY response 
-                       // with type 7F (for all luns less than the max for this bus,id) so the lun scan will continue.
-                       cmd->result = (DID_NO_CONNECT << 16);
-                       scsi_done(cmd);
-                       return 0;
-               }
-               cmd->device->hostdata = pDev;
-       }
-       pDev->pScsi_dev = cmd->device;
-
-       /*
-        * If we are being called from when the device is being reset, 
-        * delay processing of the command until later.
-        */
-       if (pDev->state & DPTI_DEV_RESET ) {
-               return FAILED;
-       }
-       return adpt_scsi_to_i2o(pHba, cmd, pDev);
-}
-
-static DEF_SCSI_QCMD(adpt_queue)
-
-static int adpt_bios_param(struct scsi_device *sdev, struct block_device *dev,
-               sector_t capacity, int geom[])
-{
-       int heads=-1;
-       int sectors=-1;
-       int cylinders=-1;
-
-       // *** First lets set the default geometry ****
-       
-       // If the capacity is less than ox2000
-       if (capacity < 0x2000 ) {       // floppy
-               heads = 18;
-               sectors = 2;
-       } 
-       // else if between 0x2000 and 0x20000
-       else if (capacity < 0x20000) {
-               heads = 64;
-               sectors = 32;
-       }
-       // else if between 0x20000 and 0x40000
-       else if (capacity < 0x40000) {
-               heads = 65;
-               sectors = 63;
-       }
-       // else if between 0x4000 and 0x80000
-       else if (capacity < 0x80000) {
-               heads = 128;
-               sectors = 63;
-       }
-       // else if greater than 0x80000
-       else {
-               heads = 255;
-               sectors = 63;
-       }
-       cylinders = sector_div(capacity, heads * sectors);
-
-       // Special case if CDROM
-       if(sdev->type == 5) {  // CDROM
-               heads = 252;
-               sectors = 63;
-               cylinders = 1111;
-       }
-
-       geom[0] = heads;
-       geom[1] = sectors;
-       geom[2] = cylinders;
-       
-       PDEBUG("adpt_bios_param: exit\n");
-       return 0;
-}
-
-
-static const char *adpt_info(struct Scsi_Host *host)
-{
-       adpt_hba* pHba;
-
-       pHba = (adpt_hba *) host->hostdata[0];
-       return (char *) (pHba->detail);
-}
-
-static int adpt_show_info(struct seq_file *m, struct Scsi_Host *host)
-{
-       struct adpt_device* d;
-       int id;
-       int chan;
-       adpt_hba* pHba;
-       int unit;
-
-       // Find HBA (host bus adapter) we are looking for
-       mutex_lock(&adpt_configuration_lock);
-       for (pHba = hba_chain; pHba; pHba = pHba->next) {
-               if (pHba->host == host) {
-                       break;  /* found adapter */
-               }
-       }
-       mutex_unlock(&adpt_configuration_lock);
-       if (pHba == NULL) {
-               return 0;
-       }
-       host = pHba->host;
-
-       seq_printf(m, "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION);
-       seq_printf(m, "%s\n", pHba->detail);
-       seq_printf(m, "SCSI Host=scsi%d  Control Node=/dev/%s  irq=%d\n", 
-                       pHba->host->host_no, pHba->name, host->irq);
-       seq_printf(m, "\tpost fifo size  = %d\n\treply fifo size = %d\n\tsg table size   = %d\n\n",
-                       host->can_queue, (int) pHba->reply_fifo_size , host->sg_tablesize);
-
-       seq_puts(m, "Devices:\n");
-       for(chan = 0; chan < MAX_CHANNEL; chan++) {
-               for(id = 0; id < MAX_ID; id++) {
-                       d = pHba->channel[chan].device[id];
-                       while(d) {
-                               seq_printf(m,"\t%-24.24s", d->pScsi_dev->vendor);
-                               seq_printf(m," Rev: %-8.8s\n", d->pScsi_dev->rev);
-
-                               unit = d->pI2o_dev->lct_data.tid;
-                               seq_printf(m, "\tTID=%d, (Channel=%d, Target=%d, Lun=%llu)  (%s)\n\n",
-                                              unit, (int)d->scsi_channel, (int)d->scsi_id, d->scsi_lun,
-                                              scsi_device_online(d->pScsi_dev)? "online":"offline"); 
-                               d = d->next_lun;
-                       }
-               }
-       }
-       return 0;
-}
-
-/*
- *     Turn a pointer to ioctl reply data into an u32 'context'
- */
-static u32 adpt_ioctl_to_context(adpt_hba * pHba, void *reply)
-{
-#if BITS_PER_LONG == 32
-       return (u32)(unsigned long)reply;
-#else
-       ulong flags = 0;
-       u32 nr, i;
-
-       spin_lock_irqsave(pHba->host->host_lock, flags);
-       nr = ARRAY_SIZE(pHba->ioctl_reply_context);
-       for (i = 0; i < nr; i++) {
-               if (pHba->ioctl_reply_context[i] == NULL) {
-                       pHba->ioctl_reply_context[i] = reply;
-                       break;
-               }
-       }
-       spin_unlock_irqrestore(pHba->host->host_lock, flags);
-       if (i >= nr) {
-               printk(KERN_WARNING"%s: Too many outstanding "
-                               "ioctl commands\n", pHba->name);
-               return (u32)-1;
-       }
-
-       return i;
-#endif
-}
-
-/*
- *     Go from an u32 'context' to a pointer to ioctl reply data.
- */
-static void *adpt_ioctl_from_context(adpt_hba *pHba, u32 context)
-{
-#if BITS_PER_LONG == 32
-       return (void *)(unsigned long)context;
-#else
-       void *p = pHba->ioctl_reply_context[context];
-       pHba->ioctl_reply_context[context] = NULL;
-
-       return p;
-#endif
-}
-
-/*===========================================================================
- * Error Handling routines
- *===========================================================================
- */
-
-static int adpt_abort(struct scsi_cmnd * cmd)
-{
-       adpt_hba* pHba = NULL;  /* host bus adapter structure */
-       struct adpt_device* dptdevice;  /* dpt per device information */
-       u32 msg[5];
-       int rcode;
-
-       pHba = (adpt_hba*) cmd->device->host->hostdata[0];
-       printk(KERN_INFO"%s: Trying to Abort\n",pHba->name);
-       if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) {
-               printk(KERN_ERR "%s: Unable to abort: No device in cmnd\n",pHba->name);
-               return FAILED;
-       }
-
-       memset(msg, 0, sizeof(msg));
-       msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
-       msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid;
-       msg[2] = 0;
-       msg[3]= 0;
-       /* Add 1 to avoid firmware treating it as invalid command */
-       msg[4] = scsi_cmd_to_rq(cmd)->tag + 1;
-       if (pHba->host)
-               spin_lock_irq(pHba->host->host_lock);
-       rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER);
-       if (pHba->host)
-               spin_unlock_irq(pHba->host->host_lock);
-       if (rcode != 0) {
-               if(rcode == -EOPNOTSUPP ){
-                       printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
-                       return FAILED;
-               }
-               printk(KERN_INFO"%s: Abort failed.\n",pHba->name);
-               return FAILED;
-       } 
-       printk(KERN_INFO"%s: Abort complete.\n",pHba->name);
-       return SUCCESS;
-}
-
-
-#define I2O_DEVICE_RESET 0x27
-// This is the same for BLK and SCSI devices
-// NOTE this is wrong in the i2o.h definitions
-// This is not currently supported by our adapter but we issue it anyway
-static int adpt_device_reset(struct scsi_cmnd* cmd)
-{
-       adpt_hba* pHba;
-       u32 msg[4];
-       u32 rcode;
-       int old_state;
-       struct adpt_device* d = cmd->device->hostdata;
-
-       pHba = (void*) cmd->device->host->hostdata[0];
-       printk(KERN_INFO"%s: Trying to reset device\n",pHba->name);
-       if (!d) {
-               printk(KERN_INFO"%s: Reset Device: Device Not found\n",pHba->name);
-               return FAILED;
-       }
-       memset(msg, 0, sizeof(msg));
-       msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
-       msg[1] = (I2O_DEVICE_RESET<<24|HOST_TID<<12|d->tid);
-       msg[2] = 0;
-       msg[3] = 0;
-
-       if (pHba->host)
-               spin_lock_irq(pHba->host->host_lock);
-       old_state = d->state;
-       d->state |= DPTI_DEV_RESET;
-       rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
-       d->state = old_state;
-       if (pHba->host)
-               spin_unlock_irq(pHba->host->host_lock);
-       if (rcode != 0) {
-               if(rcode == -EOPNOTSUPP ){
-                       printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
-                       return FAILED;
-               }
-               printk(KERN_INFO"%s: Device reset failed\n",pHba->name);
-               return FAILED;
-       } else {
-               printk(KERN_INFO"%s: Device reset successful\n",pHba->name);
-               return SUCCESS;
-       }
-}
-
-
-#define I2O_HBA_BUS_RESET 0x87
-// This version of bus reset is called by the eh_error handler
-static int adpt_bus_reset(struct scsi_cmnd* cmd)
-{
-       adpt_hba* pHba;
-       u32 msg[4];
-       u32 rcode;
-
-       pHba = (adpt_hba*)cmd->device->host->hostdata[0];
-       memset(msg, 0, sizeof(msg));
-       printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, cmd->device->channel,pHba->channel[cmd->device->channel].tid );
-       msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
-       msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid);
-       msg[2] = 0;
-       msg[3] = 0;
-       if (pHba->host)
-               spin_lock_irq(pHba->host->host_lock);
-       rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
-       if (pHba->host)
-               spin_unlock_irq(pHba->host->host_lock);
-       if (rcode != 0) {
-               printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
-               return FAILED;
-       } else {
-               printk(KERN_WARNING"%s: Bus reset success.\n",pHba->name);
-               return SUCCESS;
-       }
-}
-
-// This version of reset is called by the eh_error_handler
-static int __adpt_reset(struct scsi_cmnd* cmd)
-{
-       adpt_hba* pHba;
-       int rcode;
-       char name[32];
-
-       pHba = (adpt_hba*)cmd->device->host->hostdata[0];
-       strncpy(name, pHba->name, sizeof(name));
-       printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n", name, cmd->device->channel, pHba->channel[cmd->device->channel].tid);
-       rcode =  adpt_hba_reset(pHba);
-       if(rcode == 0){
-               printk(KERN_WARNING"%s: HBA reset complete\n", name);
-               return SUCCESS;
-       } else {
-               printk(KERN_WARNING"%s: HBA reset failed (%x)\n", name, rcode);
-               return FAILED;
-       }
-}
-
-static int adpt_reset(struct scsi_cmnd* cmd)
-{
-       int rc;
-
-       spin_lock_irq(cmd->device->host->host_lock);
-       rc = __adpt_reset(cmd);
-       spin_unlock_irq(cmd->device->host->host_lock);
-
-       return rc;
-}
-
-// This version of reset is called by the ioctls and indirectly from eh_error_handler via adpt_reset
-static int adpt_hba_reset(adpt_hba* pHba)
-{
-       int rcode;
-
-       pHba->state |= DPTI_STATE_RESET;
-
-       // Activate does get status , init outbound, and get hrt
-       if ((rcode=adpt_i2o_activate_hba(pHba)) < 0) {
-               printk(KERN_ERR "%s: Could not activate\n", pHba->name);
-               adpt_i2o_delete_hba(pHba);
-               return rcode;
-       }
-
-       if ((rcode=adpt_i2o_build_sys_table()) < 0) {
-               adpt_i2o_delete_hba(pHba);
-               return rcode;
-       }
-       PDEBUG("%s: in HOLD state\n",pHba->name);
-
-       if ((rcode=adpt_i2o_online_hba(pHba)) < 0) {
-               adpt_i2o_delete_hba(pHba);      
-               return rcode;
-       }
-       PDEBUG("%s: in OPERATIONAL state\n",pHba->name);
-
-       if ((rcode=adpt_i2o_lct_get(pHba)) < 0){
-               adpt_i2o_delete_hba(pHba);
-               return rcode;
-       }
-
-       if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){
-               adpt_i2o_delete_hba(pHba);
-               return rcode;
-       }
-       pHba->state &= ~DPTI_STATE_RESET;
-
-       scsi_host_complete_all_commands(pHba->host, DID_RESET);
-       return 0;       /* return success */
-}
-
-/*===========================================================================
- * 
- *===========================================================================
- */
-
-
-static void adpt_i2o_sys_shutdown(void)
-{
-       adpt_hba *pHba, *pNext;
-       struct adpt_i2o_post_wait_data *p1, *old;
-
-       printk(KERN_INFO "Shutting down Adaptec I2O controllers.\n");
-       printk(KERN_INFO "   This could take a few minutes if there are many devices attached\n");
-       /* Delete all IOPs from the controller chain */
-       /* They should have already been released by the
-        * scsi-core
-        */
-       for (pHba = hba_chain; pHba; pHba = pNext) {
-               pNext = pHba->next;
-               adpt_i2o_delete_hba(pHba);
-       }
-
-       /* Remove any timedout entries from the wait queue.  */
-//     spin_lock_irqsave(&adpt_post_wait_lock, flags);
-       /* Nothing should be outstanding at this point so just
-        * free them 
-        */
-       for(p1 = adpt_post_wait_queue; p1;) {
-               old = p1;
-               p1 = p1->next;
-               kfree(old);
-       }
-//     spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
-       adpt_post_wait_queue = NULL;
-
-       printk(KERN_INFO "Adaptec I2O controllers down.\n");
-}
-
-static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev)
-{
-
-       adpt_hba* pHba = NULL;
-       adpt_hba* p = NULL;
-       ulong base_addr0_phys = 0;
-       ulong base_addr1_phys = 0;
-       u32 hba_map0_area_size = 0;
-       u32 hba_map1_area_size = 0;
-       void __iomem *base_addr_virt = NULL;
-       void __iomem *msg_addr_virt = NULL;
-       int dma64 = 0;
-
-       int raptorFlag = FALSE;
-
-       if(pci_enable_device(pDev)) {
-               return -EINVAL;
-       }
-
-       if (pci_request_regions(pDev, "dpt_i2o")) {
-               PERROR("dpti: adpt_config_hba: pci request region failed\n");
-               return -EINVAL;
-       }
-
-       pci_set_master(pDev);
-
-       /*
-        *      See if we should enable dma64 mode.
-        */
-       if (sizeof(dma_addr_t) > 4 &&
-           dma_get_required_mask(&pDev->dev) > DMA_BIT_MASK(32) &&
-           dma_set_mask(&pDev->dev, DMA_BIT_MASK(64)) == 0)
-               dma64 = 1;
-
-       if (!dma64 && dma_set_mask(&pDev->dev, DMA_BIT_MASK(32)) != 0)
-               return -EINVAL;
-
-       /* adapter only supports message blocks below 4GB */
-       dma_set_coherent_mask(&pDev->dev, DMA_BIT_MASK(32));
-
-       base_addr0_phys = pci_resource_start(pDev,0);
-       hba_map0_area_size = pci_resource_len(pDev,0);
-
-       // Check if standard PCI card or single BAR Raptor
-       if(pDev->device == PCI_DPT_DEVICE_ID){
-               if(pDev->subsystem_device >=0xc032 && pDev->subsystem_device <= 0xc03b){
-                       // Raptor card with this device id needs 4M
-                       hba_map0_area_size = 0x400000;
-               } else { // Not Raptor - it is a PCI card
-                       if(hba_map0_area_size > 0x100000 ){ 
-                               hba_map0_area_size = 0x100000;
-                       }
-               }
-       } else {// Raptor split BAR config
-               // Use BAR1 in this configuration
-               base_addr1_phys = pci_resource_start(pDev,1);
-               hba_map1_area_size = pci_resource_len(pDev,1);
-               raptorFlag = TRUE;
-       }
-
-#if BITS_PER_LONG == 64
-       /*
-        *      The original Adaptec 64 bit driver has this comment here:
-        *      "x86_64 machines need more optimal mappings"
-        *
-        *      I assume some HBAs report ridiculously large mappings
-        *      and we need to limit them on platforms with IOMMUs.
-        */
-       if (raptorFlag == TRUE) {
-               if (hba_map0_area_size > 128)
-                       hba_map0_area_size = 128;
-               if (hba_map1_area_size > 524288)
-                       hba_map1_area_size = 524288;
-       } else {
-               if (hba_map0_area_size > 524288)
-                       hba_map0_area_size = 524288;
-       }
-#endif
-
-       base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size);
-       if (!base_addr_virt) {
-               pci_release_regions(pDev);
-               PERROR("dpti: adpt_config_hba: io remap failed\n");
-               return -EINVAL;
-       }
-
-        if(raptorFlag == TRUE) {
-               msg_addr_virt = ioremap(base_addr1_phys, hba_map1_area_size );
-               if (!msg_addr_virt) {
-                       PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");
-                       iounmap(base_addr_virt);
-                       pci_release_regions(pDev);
-                       return -EINVAL;
-               }
-       } else {
-               msg_addr_virt = base_addr_virt;
-       }
-       
-       // Allocate and zero the data structure
-       pHba = kzalloc(sizeof(adpt_hba), GFP_KERNEL);
-       if (!pHba) {
-               if (msg_addr_virt != base_addr_virt)
-                       iounmap(msg_addr_virt);
-               iounmap(base_addr_virt);
-               pci_release_regions(pDev);
-               return -ENOMEM;
-       }
-
-       mutex_lock(&adpt_configuration_lock);
-
-       if(hba_chain != NULL){
-               for(p = hba_chain; p->next; p = p->next);
-               p->next = pHba;
-       } else {
-               hba_chain = pHba;
-       }
-       pHba->next = NULL;
-       pHba->unit = hba_count;
-       sprintf(pHba->name, "dpti%d", hba_count);
-       hba_count++;
-       
-       mutex_unlock(&adpt_configuration_lock);
-
-       pHba->pDev = pDev;
-       pHba->base_addr_phys = base_addr0_phys;
-
-       // Set up the Virtual Base Address of the I2O Device
-       pHba->base_addr_virt = base_addr_virt;
-       pHba->msg_addr_virt = msg_addr_virt;
-       pHba->irq_mask = base_addr_virt+0x30;
-       pHba->post_port = base_addr_virt+0x40;
-       pHba->reply_port = base_addr_virt+0x44;
-
-       pHba->hrt = NULL;
-       pHba->lct = NULL;
-       pHba->lct_size = 0;
-       pHba->status_block = NULL;
-       pHba->post_count = 0;
-       pHba->state = DPTI_STATE_RESET;
-       pHba->pDev = pDev;
-       pHba->devices = NULL;
-       pHba->dma64 = dma64;
-
-       // Initializing the spinlocks
-       spin_lock_init(&pHba->state_lock);
-
-       if(raptorFlag == 0){
-               printk(KERN_INFO "Adaptec I2O RAID controller"
-                                " %d at %p size=%x irq=%d%s\n", 
-                       hba_count-1, base_addr_virt,
-                       hba_map0_area_size, pDev->irq,
-                       dma64 ? " (64-bit DMA)" : "");
-       } else {
-               printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d%s\n",
-                       hba_count-1, pDev->irq,
-                       dma64 ? " (64-bit DMA)" : "");
-               printk(KERN_INFO"     BAR0 %p - size= %x\n",base_addr_virt,hba_map0_area_size);
-               printk(KERN_INFO"     BAR1 %p - size= %x\n",msg_addr_virt,hba_map1_area_size);
-       }
-
-       if (request_irq (pDev->irq, adpt_isr, IRQF_SHARED, pHba->name, pHba)) {
-               printk(KERN_ERR"%s: Couldn't register IRQ %d\n", pHba->name, pDev->irq);
-               adpt_i2o_delete_hba(pHba);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-
-static void adpt_i2o_delete_hba(adpt_hba* pHba)
-{
-       adpt_hba* p1;
-       adpt_hba* p2;
-       struct i2o_device* d;
-       struct i2o_device* next;
-       int i;
-       int j;
-       struct adpt_device* pDev;
-       struct adpt_device* pNext;
-
-
-       mutex_lock(&adpt_configuration_lock);
-       if(pHba->host){
-               free_irq(pHba->host->irq, pHba);
-       }
-       p2 = NULL;
-       for( p1 = hba_chain; p1; p2 = p1,p1=p1->next){
-               if(p1 == pHba) {
-                       if(p2) {
-                               p2->next = p1->next;
-                       } else {
-                               hba_chain = p1->next;
-                       }
-                       break;
-               }
-       }
-
-       hba_count--;
-       mutex_unlock(&adpt_configuration_lock);
-
-       iounmap(pHba->base_addr_virt);
-       pci_release_regions(pHba->pDev);
-       if(pHba->msg_addr_virt != pHba->base_addr_virt){
-               iounmap(pHba->msg_addr_virt);
-       }
-       if(pHba->FwDebugBuffer_P)
-               iounmap(pHba->FwDebugBuffer_P);
-       if(pHba->hrt) {
-               dma_free_coherent(&pHba->pDev->dev,
-                       pHba->hrt->num_entries * pHba->hrt->entry_len << 2,
-                       pHba->hrt, pHba->hrt_pa);
-       }
-       if(pHba->lct) {
-               dma_free_coherent(&pHba->pDev->dev, pHba->lct_size,
-                       pHba->lct, pHba->lct_pa);
-       }
-       if(pHba->status_block) {
-               dma_free_coherent(&pHba->pDev->dev, sizeof(i2o_status_block),
-                       pHba->status_block, pHba->status_block_pa);
-       }
-       if(pHba->reply_pool) {
-               dma_free_coherent(&pHba->pDev->dev,
-                       pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4,
-                       pHba->reply_pool, pHba->reply_pool_pa);
-       }
-
-       for(d = pHba->devices; d ; d = next){
-               next = d->next;
-               kfree(d);
-       }
-       for(i = 0 ; i < pHba->top_scsi_channel ; i++){
-               for(j = 0; j < MAX_ID; j++){
-                       if(pHba->channel[i].device[j] != NULL){
-                               for(pDev = pHba->channel[i].device[j]; pDev; pDev = pNext){
-                                       pNext = pDev->next_lun;
-                                       kfree(pDev);
-                               }
-                       }
-               }
-       }
-       pci_dev_put(pHba->pDev);
-       if (adpt_sysfs_class)
-               device_destroy(adpt_sysfs_class,
-                               MKDEV(DPTI_I2O_MAJOR, pHba->unit));
-       kfree(pHba);
-
-       if(hba_count <= 0){
-               unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);   
-               if (adpt_sysfs_class) {
-                       class_destroy(adpt_sysfs_class);
-                       adpt_sysfs_class = NULL;
-               }
-       }
-}
-
-static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u64 lun)
-{
-       struct adpt_device* d;
-
-       if (chan >= MAX_CHANNEL)
-               return NULL;
-       
-       d = pHba->channel[chan].device[id];
-       if(!d || d->tid == 0) {
-               return NULL;
-       }
-
-       /* If it is the only lun at that address then this should match*/
-       if(d->scsi_lun == lun){
-               return d;
-       }
-
-       /* else we need to look through all the luns */
-       for(d=d->next_lun ; d ; d = d->next_lun){
-               if(d->scsi_lun == lun){
-                       return d;
-               }
-       }
-       return NULL;
-}
-
-
-static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
-{
-       // I used my own version of the WAIT_QUEUE_HEAD
-       // to handle some version differences
-       // When embedded in the kernel this could go back to the vanilla one
-       ADPT_DECLARE_WAIT_QUEUE_HEAD(adpt_wq_i2o_post);
-       int status = 0;
-       ulong flags = 0;
-       struct adpt_i2o_post_wait_data *p1, *p2;
-       struct adpt_i2o_post_wait_data *wait_data =
-               kmalloc(sizeof(struct adpt_i2o_post_wait_data), GFP_ATOMIC);
-       DECLARE_WAITQUEUE(wait, current);
-
-       if (!wait_data)
-               return -ENOMEM;
-
-       /*
-        * The spin locking is needed to keep anyone from playing
-        * with the queue pointers and id while we do the same
-        */
-       spin_lock_irqsave(&adpt_post_wait_lock, flags);
-       // TODO we need a MORE unique way of getting ids
-       // to support async LCT get
-       wait_data->next = adpt_post_wait_queue;
-       adpt_post_wait_queue = wait_data;
-       adpt_post_wait_id++;
-       adpt_post_wait_id &= 0x7fff;
-       wait_data->id =  adpt_post_wait_id;
-       spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
-
-       wait_data->wq = &adpt_wq_i2o_post;
-       wait_data->status = -ETIMEDOUT;
-
-       add_wait_queue(&adpt_wq_i2o_post, &wait);
-
-       msg[2] |= 0x80000000 | ((u32)wait_data->id);
-       timeout *= HZ;
-       if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
-               set_current_state(TASK_INTERRUPTIBLE);
-               if(pHba->host)
-                       spin_unlock_irq(pHba->host->host_lock);
-               if (!timeout)
-                       schedule();
-               else{
-                       timeout = schedule_timeout(timeout);
-                       if (timeout == 0) {
-                               // I/O issued, but cannot get result in
-                               // specified time. Freeing resorces is
-                               // dangerous.
-                               status = -ETIME;
-                       }
-               }
-               if(pHba->host)
-                       spin_lock_irq(pHba->host->host_lock);
-       }
-       remove_wait_queue(&adpt_wq_i2o_post, &wait);
-
-       if(status == -ETIMEDOUT){
-               printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
-               // We will have to free the wait_data memory during shutdown
-               return status;
-       }
-
-       /* Remove the entry from the queue.  */
-       p2 = NULL;
-       spin_lock_irqsave(&adpt_post_wait_lock, flags);
-       for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p1->next) {
-               if(p1 == wait_data) {
-                       if(p1->status == I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION ) {
-                               status = -EOPNOTSUPP;
-                       }
-                       if(p2) {
-                               p2->next = p1->next;
-                       } else {
-                               adpt_post_wait_queue = p1->next;
-                       }
-                       break;
-               }
-       }
-       spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
-
-       kfree(wait_data);
-
-       return status;
-}
-
-
-static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len)
-{
-
-       u32 m = EMPTY_QUEUE;
-       u32 __iomem *msg;
-       ulong timeout = jiffies + 30*HZ;
-       do {
-               rmb();
-               m = readl(pHba->post_port);
-               if (m != EMPTY_QUEUE) {
-                       break;
-               }
-               if(time_after(jiffies,timeout)){
-                       printk(KERN_WARNING"dpti%d: Timeout waiting for message frame!\n", pHba->unit);
-                       return -ETIMEDOUT;
-               }
-               schedule_timeout_uninterruptible(1);
-       } while(m == EMPTY_QUEUE);
-               
-       msg = pHba->msg_addr_virt + m;
-       memcpy_toio(msg, data, len);
-       wmb();
-
-       //post message
-       writel(m, pHba->post_port);
-       wmb();
-
-       return 0;
-}
-
-
-static void adpt_i2o_post_wait_complete(u32 context, int status)
-{
-       struct adpt_i2o_post_wait_data *p1 = NULL;
-       /*
-        * We need to search through the adpt_post_wait
-        * queue to see if the given message is still
-        * outstanding.  If not, it means that the IOP
-        * took longer to respond to the message than we
-        * had allowed and timer has already expired.
-        * Not much we can do about that except log
-        * it for debug purposes, increase timeout, and recompile
-        *
-        * Lock needed to keep anyone from moving queue pointers
-        * around while we're looking through them.
-        */
-
-       context &= 0x7fff;
-
-       spin_lock(&adpt_post_wait_lock);
-       for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
-               if(p1->id == context) {
-                       p1->status = status;
-                       spin_unlock(&adpt_post_wait_lock);
-                       wake_up_interruptible(p1->wq);
-                       return;
-               }
-       }
-       spin_unlock(&adpt_post_wait_lock);
-        // If this happens we lose commands that probably really completed
-       printk(KERN_DEBUG"dpti: Could Not find task %d in wait queue\n",context);
-       printk(KERN_DEBUG"      Tasks in wait queue:\n");
-       for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
-               printk(KERN_DEBUG"           %d\n",p1->id);
-       }
-       return;
-}
-
-static s32 adpt_i2o_reset_hba(adpt_hba* pHba)                  
-{
-       u32 msg[8];
-       u8* status;
-       dma_addr_t addr;
-       u32 m = EMPTY_QUEUE ;
-       ulong timeout = jiffies + (TMOUT_IOPRESET*HZ);
-
-       if(pHba->initialized  == FALSE) {       // First time reset should be quick
-               timeout = jiffies + (25*HZ);
-       } else {
-               adpt_i2o_quiesce_hba(pHba);
-       }
-
-       do {
-               rmb();
-               m = readl(pHba->post_port);
-               if (m != EMPTY_QUEUE) {
-                       break;
-               }
-               if(time_after(jiffies,timeout)){
-                       printk(KERN_WARNING"Timeout waiting for message!\n");
-                       return -ETIMEDOUT;
-               }
-               schedule_timeout_uninterruptible(1);
-       } while (m == EMPTY_QUEUE);
-
-       status = dma_alloc_coherent(&pHba->pDev->dev, 4, &addr, GFP_KERNEL);
-       if(status == NULL) {
-               adpt_send_nop(pHba, m);
-               printk(KERN_ERR"IOP reset failed - no free memory.\n");
-               return -ENOMEM;
-       }
-
-       msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
-       msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
-       msg[2]=0;
-       msg[3]=0;
-       msg[4]=0;
-       msg[5]=0;
-       msg[6]=dma_low(addr);
-       msg[7]=dma_high(addr);
-
-       memcpy_toio(pHba->msg_addr_virt+m, msg, sizeof(msg));
-       wmb();
-       writel(m, pHba->post_port);
-       wmb();
-
-       while(*status == 0){
-               if(time_after(jiffies,timeout)){
-                       printk(KERN_WARNING"%s: IOP Reset Timeout\n",pHba->name);
-                       /* We lose 4 bytes of "status" here, but we cannot
-                          free these because controller may awake and corrupt
-                          those bytes at any time */
-                       /* dma_free_coherent(&pHba->pDev->dev, 4, buf, addr); */
-                       return -ETIMEDOUT;
-               }
-               rmb();
-               schedule_timeout_uninterruptible(1);
-       }
-
-       if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
-               PDEBUG("%s: Reset in progress...\n", pHba->name);
-               // Here we wait for message frame to become available
-               // indicated that reset has finished
-               do {
-                       rmb();
-                       m = readl(pHba->post_port);
-                       if (m != EMPTY_QUEUE) {
-                               break;
-                       }
-                       if(time_after(jiffies,timeout)){
-                               printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
-                               /* We lose 4 bytes of "status" here, but we
-                                  cannot free these because controller may
-                                  awake and corrupt those bytes at any time */
-                               /* dma_free_coherent(&pHba->pDev->dev, 4, buf, addr); */
-                               return -ETIMEDOUT;
-                       }
-                       schedule_timeout_uninterruptible(1);
-               } while (m == EMPTY_QUEUE);
-               // Flush the offset
-               adpt_send_nop(pHba, m);
-       }
-       adpt_i2o_status_get(pHba);
-       if(*status == 0x02 ||
-                       pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
-               printk(KERN_WARNING"%s: Reset reject, trying to clear\n",
-                               pHba->name);
-       } else {
-               PDEBUG("%s: Reset completed.\n", pHba->name);
-       }
-
-       dma_free_coherent(&pHba->pDev->dev, 4, status, addr);
-#ifdef UARTDELAY
-       // This delay is to allow someone attached to the card through the debug UART to 
-       // set up the dump levels that they want before the rest of the initialization sequence
-       adpt_delay(20000);
-#endif
-       return 0;
-}
-
-
-static int adpt_i2o_parse_lct(adpt_hba* pHba)
-{
-       int i;
-       int max;
-       int tid;
-       struct i2o_device *d;
-       i2o_lct *lct = pHba->lct;
-       u8 bus_no = 0;
-       s16 scsi_id;
-       u64 scsi_lun;
-       u32 buf[10]; // larger than 7, or 8 ...
-       struct adpt_device* pDev; 
-       
-       if (lct == NULL) {
-               printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
-               return -1;
-       }
-       
-       max = lct->table_size;  
-       max -= 3;
-       max /= 9;
-
-       for(i=0;i<max;i++) {
-               if( lct->lct_entry[i].user_tid != 0xfff){
-                       /*
-                        * If we have hidden devices, we need to inform the upper layers about
-                        * the possible maximum id reference to handle device access when
-                        * an array is disassembled. This code has no other purpose but to
-                        * allow us future access to devices that are currently hidden
-                        * behind arrays, hotspares or have not been configured (JBOD mode).
-                        */
-                       if( lct->lct_entry[i].class_id != I2O_CLASS_RANDOM_BLOCK_STORAGE &&
-                           lct->lct_entry[i].class_id != I2O_CLASS_SCSI_PERIPHERAL &&
-                           lct->lct_entry[i].class_id != I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
-                               continue;
-                       }
-                       tid = lct->lct_entry[i].tid;
-                       // I2O_DPT_DEVICE_INFO_GROUP_NO;
-                       if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
-                               continue;
-                       }
-                       bus_no = buf[0]>>16;
-                       scsi_id = buf[1];
-                       scsi_lun = scsilun_to_int((struct scsi_lun *)&buf[2]);
-                       if(bus_no >= MAX_CHANNEL) {     // Something wrong skip it
-                               printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
-                               continue;
-                       }
-                       if (scsi_id >= MAX_ID){
-                               printk(KERN_WARNING"%s: SCSI ID %d out of range \n", pHba->name, bus_no);
-                               continue;
-                       }
-                       if(bus_no > pHba->top_scsi_channel){
-                               pHba->top_scsi_channel = bus_no;
-                       }
-                       if(scsi_id > pHba->top_scsi_id){
-                               pHba->top_scsi_id = scsi_id;
-                       }
-                       if(scsi_lun > pHba->top_scsi_lun){
-                               pHba->top_scsi_lun = scsi_lun;
-                       }
-                       continue;
-               }
-               d = kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
-               if(d==NULL)
-               {
-                       printk(KERN_CRIT"%s: Out of memory for I2O device data.\n",pHba->name);
-                       return -ENOMEM;
-               }
-               
-               d->controller = pHba;
-               d->next = NULL;
-
-               memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
-
-               d->flags = 0;
-               tid = d->lct_data.tid;
-               adpt_i2o_report_hba_unit(pHba, d);
-               adpt_i2o_install_device(pHba, d);
-       }
-       bus_no = 0;
-       for(d = pHba->devices; d ; d = d->next) {
-               if(d->lct_data.class_id  == I2O_CLASS_BUS_ADAPTER_PORT ||
-                  d->lct_data.class_id  == I2O_CLASS_FIBRE_CHANNEL_PORT){
-                       tid = d->lct_data.tid;
-                       // TODO get the bus_no from hrt-but for now they are in order
-                       //bus_no = 
-                       if(bus_no > pHba->top_scsi_channel){
-                               pHba->top_scsi_channel = bus_no;
-                       }
-                       pHba->channel[bus_no].type = d->lct_data.class_id;
-                       pHba->channel[bus_no].tid = tid;
-                       if(adpt_i2o_query_scalar(pHba, tid, 0x0200, -1, buf, 28)>=0)
-                       {
-                               pHba->channel[bus_no].scsi_id = buf[1];
-                               PDEBUG("Bus %d - SCSI ID %d.\n", bus_no, buf[1]);
-                       }
-                       // TODO remove - this is just until we get from hrt
-                       bus_no++;
-                       if(bus_no >= MAX_CHANNEL) {     // Something wrong skip it
-                               printk(KERN_WARNING"%s: Channel number %d out of range - LCT\n", pHba->name, bus_no);
-                               break;
-                       }
-               }
-       }
-
-       // Setup adpt_device table
-       for(d = pHba->devices; d ; d = d->next) {
-               if(d->lct_data.class_id  == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
-                  d->lct_data.class_id  == I2O_CLASS_SCSI_PERIPHERAL ||
-                  d->lct_data.class_id  == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
-
-                       tid = d->lct_data.tid;
-                       scsi_id = -1;
-                       // I2O_DPT_DEVICE_INFO_GROUP_NO;
-                       if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)>=0) {
-                               bus_no = buf[0]>>16;
-                               scsi_id = buf[1];
-                               scsi_lun = scsilun_to_int((struct scsi_lun *)&buf[2]);
-                               if(bus_no >= MAX_CHANNEL) {     // Something wrong skip it
-                                       continue;
-                               }
-                               if (scsi_id >= MAX_ID) {
-                                       continue;
-                               }
-                               if( pHba->channel[bus_no].device[scsi_id] == NULL){
-                                       pDev =  kzalloc(sizeof(struct adpt_device),GFP_KERNEL);
-                                       if(pDev == NULL) {
-                                               return -ENOMEM;
-                                       }
-                                       pHba->channel[bus_no].device[scsi_id] = pDev;
-                               } else {
-                                       for( pDev = pHba->channel[bus_no].device[scsi_id];      
-                                                       pDev->next_lun; pDev = pDev->next_lun){
-                                       }
-                                       pDev->next_lun = kzalloc(sizeof(struct adpt_device),GFP_KERNEL);
-                                       if(pDev->next_lun == NULL) {
-                                               return -ENOMEM;
-                                       }
-                                       pDev = pDev->next_lun;
-                               }
-                               pDev->tid = tid;
-                               pDev->scsi_channel = bus_no;
-                               pDev->scsi_id = scsi_id;
-                               pDev->scsi_lun = scsi_lun;
-                               pDev->pI2o_dev = d;
-                               d->owner = pDev;
-                               pDev->type = (buf[0])&0xff;
-                               pDev->flags = (buf[0]>>8)&0xff;
-                               if(scsi_id > pHba->top_scsi_id){
-                                       pHba->top_scsi_id = scsi_id;
-                               }
-                               if(scsi_lun > pHba->top_scsi_lun){
-                                       pHba->top_scsi_lun = scsi_lun;
-                               }
-                       }
-                       if(scsi_id == -1){
-                               printk(KERN_WARNING"Could not find SCSI ID for %s\n",
-                                               d->lct_data.identity_tag);
-                       }
-               }
-       }
-       return 0;
-}
-
-
-/*
- *     Each I2O controller has a chain of devices on it - these match
- *     the useful parts of the LCT of the board.
- */
-static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
-{
-       mutex_lock(&adpt_configuration_lock);
-       d->controller=pHba;
-       d->owner=NULL;
-       d->next=pHba->devices;
-       d->prev=NULL;
-       if (pHba->devices != NULL){
-               pHba->devices->prev=d;
-       }
-       pHba->devices=d;
-       *d->dev_name = 0;
-
-       mutex_unlock(&adpt_configuration_lock);
-       return 0;
-}
-
-static int adpt_open(struct inode *inode, struct file *file)
-{
-       int minor;
-       adpt_hba* pHba;
-
-       mutex_lock(&adpt_mutex);
-       //TODO check for root access
-       //
-       minor = iminor(inode);
-       if (minor >= hba_count) {
-               mutex_unlock(&adpt_mutex);
-               return -ENXIO;
-       }
-       mutex_lock(&adpt_configuration_lock);
-       for (pHba = hba_chain; pHba; pHba = pHba->next) {
-               if (pHba->unit == minor) {
-                       break;  /* found adapter */
-               }
-       }
-       if (pHba == NULL) {
-               mutex_unlock(&adpt_configuration_lock);
-               mutex_unlock(&adpt_mutex);
-               return -ENXIO;
-       }
-
-//     if(pHba->in_use){
-       //      mutex_unlock(&adpt_configuration_lock);
-//             return -EBUSY;
-//     }
-
-       pHba->in_use = 1;
-       mutex_unlock(&adpt_configuration_lock);
-       mutex_unlock(&adpt_mutex);
-
-       return 0;
-}
-
-static int adpt_close(struct inode *inode, struct file *file)
-{
-       int minor;
-       adpt_hba* pHba;
-
-       minor = iminor(inode);
-       if (minor >= hba_count) {
-               return -ENXIO;
-       }
-       mutex_lock(&adpt_configuration_lock);
-       for (pHba = hba_chain; pHba; pHba = pHba->next) {
-               if (pHba->unit == minor) {
-                       break;  /* found adapter */
-               }
-       }
-       mutex_unlock(&adpt_configuration_lock);
-       if (pHba == NULL) {
-               return -ENXIO;
-       }
-
-       pHba->in_use = 0;
-
-       return 0;
-}
-
-
-static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
-{
-       u32 msg[MAX_MESSAGE_SIZE];
-       u32* reply = NULL;
-       u32 size = 0;
-       u32 reply_size = 0;
-       u32 __user *user_msg = arg;
-       u32 __user * user_reply = NULL;
-       void **sg_list = NULL;
-       u32 sg_offset = 0;
-       u32 sg_count = 0;
-       int sg_index = 0;
-       u32 i = 0;
-       u32 rcode = 0;
-       void *p = NULL;
-       dma_addr_t addr;
-       ulong flags = 0;
-
-       memset(&msg, 0, MAX_MESSAGE_SIZE*4);
-       // get user msg size in u32s 
-       if(get_user(size, &user_msg[0])){
-               return -EFAULT;
-       }
-       size = size>>16;
-
-       user_reply = &user_msg[size];
-       if(size > MAX_MESSAGE_SIZE){
-               return -EFAULT;
-       }
-       size *= 4; // Convert to bytes
-
-       /* Copy in the user's I2O command */
-       if(copy_from_user(msg, user_msg, size)) {
-               return -EFAULT;
-       }
-       get_user(reply_size, &user_reply[0]);
-       reply_size = reply_size>>16;
-       if(reply_size > REPLY_FRAME_SIZE){
-               reply_size = REPLY_FRAME_SIZE;
-       }
-       reply_size *= 4;
-       reply = kzalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL);
-       if(reply == NULL) {
-               printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name);
-               return -ENOMEM;
-       }
-       sg_offset = (msg[0]>>4)&0xf;
-       msg[2] = 0x40000000; // IOCTL context
-       msg[3] = adpt_ioctl_to_context(pHba, reply);
-       if (msg[3] == (u32)-1) {
-               rcode = -EBUSY;
-               goto free;
-       }
-
-       sg_list = kcalloc(pHba->sg_tablesize, sizeof(*sg_list), GFP_KERNEL);
-       if (!sg_list) {
-               rcode = -ENOMEM;
-               goto free;
-       }
-       if(sg_offset) {
-               // TODO add 64 bit API
-               struct sg_simple_element *sg =  (struct sg_simple_element*) (msg+sg_offset);
-               sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
-               if (sg_count > pHba->sg_tablesize){
-                       printk(KERN_DEBUG"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count);
-                       rcode = -EINVAL;
-                       goto free;
-               }
-
-               for(i = 0; i < sg_count; i++) {
-                       int sg_size;
-
-                       if (!(sg[i].flag_count & 0x10000000 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT*/)) {
-                               printk(KERN_DEBUG"%s:Bad SG element %d - not simple (%x)\n",pHba->name,i,  sg[i].flag_count);
-                               rcode = -EINVAL;
-                               goto cleanup;
-                       }
-                       sg_size = sg[i].flag_count & 0xffffff;      
-                       /* Allocate memory for the transfer */
-                       p = dma_alloc_coherent(&pHba->pDev->dev, sg_size, &addr, GFP_KERNEL);
-                       if(!p) {
-                               printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
-                                               pHba->name,sg_size,i,sg_count);
-                               rcode = -ENOMEM;
-                               goto cleanup;
-                       }
-                       sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
-                       /* Copy in the user's SG buffer if necessary */
-                       if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {
-                               // sg_simple_element API is 32 bit
-                               if (copy_from_user(p,(void __user *)(ulong)sg[i].addr_bus, sg_size)) {
-                                       printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i);
-                                       rcode = -EFAULT;
-                                       goto cleanup;
-                               }
-                       }
-                       /* sg_simple_element API is 32 bit, but addr < 4GB */
-                       sg[i].addr_bus = addr;
-               }
-       }
-
-       do {
-               /*
-                * Stop any new commands from enterring the
-                * controller while processing the ioctl
-                */
-               if (pHba->host) {
-                       scsi_block_requests(pHba->host);
-                       spin_lock_irqsave(pHba->host->host_lock, flags);
-               }
-               rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);
-               if (rcode != 0)
-                       printk("adpt_i2o_passthru: post wait failed %d %p\n",
-                                       rcode, reply);
-               if (pHba->host) {
-                       spin_unlock_irqrestore(pHba->host->host_lock, flags);
-                       scsi_unblock_requests(pHba->host);
-               }
-       } while (rcode == -ETIMEDOUT);
-
-       if(rcode){
-               goto cleanup;
-       }
-
-       if(sg_offset) {
-       /* Copy back the Scatter Gather buffers back to user space */
-               u32 j;
-               // TODO add 64 bit API
-               struct sg_simple_element* sg;
-               int sg_size;
-
-               // re-acquire the original message to handle correctly the sg copy operation
-               memset(&msg, 0, MAX_MESSAGE_SIZE*4); 
-               // get user msg size in u32s 
-               if(get_user(size, &user_msg[0])){
-                       rcode = -EFAULT; 
-                       goto cleanup; 
-               }
-               size = size>>16;
-               size *= 4;
-               if (size > MAX_MESSAGE_SIZE) {
-                       rcode = -EINVAL;
-                       goto cleanup;
-               }
-               /* Copy in the user's I2O command */
-               if (copy_from_user (msg, user_msg, size)) {
-                       rcode = -EFAULT;
-                       goto cleanup;
-               }
-               sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
-
-               // TODO add 64 bit API
-               sg       = (struct sg_simple_element*)(msg + sg_offset);
-               for (j = 0; j < sg_count; j++) {
-                       /* Copy out the SG list to user's buffer if necessary */
-                       if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) {
-                               sg_size = sg[j].flag_count & 0xffffff; 
-                               // sg_simple_element API is 32 bit
-                               if (copy_to_user((void __user *)(ulong)sg[j].addr_bus,sg_list[j], sg_size)) {
-                                       printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);
-                                       rcode = -EFAULT;
-                                       goto cleanup;
-                               }
-                       }
-               }
-       } 
-
-       /* Copy back the reply to user space */
-       if (reply_size) {
-               // we wrote our own values for context - now restore the user supplied ones
-               if(copy_from_user(reply+2, user_msg+2, sizeof(u32)*2)) {
-                       printk(KERN_WARNING"%s: Could not copy message context FROM user\n",pHba->name);
-                       rcode = -EFAULT;
-               }
-               if(copy_to_user(user_reply, reply, reply_size)) {
-                       printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name);
-                       rcode = -EFAULT;
-               }
-       }
-
-
-cleanup:
-       if (rcode != -ETIME && rcode != -EINTR) {
-               struct sg_simple_element *sg =
-                               (struct sg_simple_element*) (msg +sg_offset);
-               while(sg_index) {
-                       if(sg_list[--sg_index]) {
-                               dma_free_coherent(&pHba->pDev->dev,
-                                       sg[sg_index].flag_count & 0xffffff,
-                                       sg_list[sg_index],
-                                       sg[sg_index].addr_bus);
-                       }
-               }
-       }
-
-free:
-       kfree(sg_list);
-       kfree(reply);
-       return rcode;
-}
-
-#if defined __ia64__ 
-static void adpt_ia64_info(sysInfo_S* si)
-{
-       // This is all the info we need for now
-       // We will add more info as our new
-       // managmenent utility requires it
-       si->processorType = PROC_IA64;
-}
-#endif
-
-#if defined __sparc__ 
-static void adpt_sparc_info(sysInfo_S* si)
-{
-       // This is all the info we need for now
-       // We will add more info as our new
-       // managmenent utility requires it
-       si->processorType = PROC_ULTRASPARC;
-}
-#endif
-#if defined __alpha__ 
-static void adpt_alpha_info(sysInfo_S* si)
-{
-       // This is all the info we need for now
-       // We will add more info as our new
-       // managmenent utility requires it
-       si->processorType = PROC_ALPHA;
-}
-#endif
-
-#if defined __i386__
-
-#include <uapi/asm/vm86.h>
-
-static void adpt_i386_info(sysInfo_S* si)
-{
-       // This is all the info we need for now
-       // We will add more info as our new
-       // managmenent utility requires it
-       switch (boot_cpu_data.x86) {
-       case CPU_386:
-               si->processorType = PROC_386;
-               break;
-       case CPU_486:
-               si->processorType = PROC_486;
-               break;
-       case CPU_586:
-               si->processorType = PROC_PENTIUM;
-               break;
-       default:  // Just in case 
-               si->processorType = PROC_PENTIUM;
-               break;
-       }
-}
-#endif
-
-/*
- * This routine returns information about the system.  This does not effect
- * any logic and if the info is wrong - it doesn't matter.
- */
-
-/* Get all the info we can not get from kernel services */
-static int adpt_system_info(void __user *buffer)
-{
-       sysInfo_S si;
-
-       memset(&si, 0, sizeof(si));
-
-       si.osType = OS_LINUX;
-       si.osMajorVersion = 0;
-       si.osMinorVersion = 0;
-       si.osRevision = 0;
-       si.busType = SI_PCI_BUS;
-       si.processorFamily = DPTI_sig.dsProcessorFamily;
-
-#if defined __i386__
-       adpt_i386_info(&si);
-#elif defined (__ia64__)
-       adpt_ia64_info(&si);
-#elif defined(__sparc__)
-       adpt_sparc_info(&si);
-#elif defined (__alpha__)
-       adpt_alpha_info(&si);
-#else
-       si.processorType = 0xff ;
-#endif
-       if (copy_to_user(buffer, &si, sizeof(si))){
-               printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
-               return -EFAULT;
-       }
-
-       return 0;
-}
-
-static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
-{
-       int minor;
-       int error = 0;
-       adpt_hba* pHba;
-       ulong flags = 0;
-       void __user *argp = (void __user *)arg;
-
-       minor = iminor(inode);
-       if (minor >= DPTI_MAX_HBA){
-               return -ENXIO;
-       }
-       mutex_lock(&adpt_configuration_lock);
-       for (pHba = hba_chain; pHba; pHba = pHba->next) {
-               if (pHba->unit == minor) {
-                       break;  /* found adapter */
-               }
-       }
-       mutex_unlock(&adpt_configuration_lock);
-       if(pHba == NULL){
-               return -ENXIO;
-       }
-
-       while((volatile u32) pHba->state & DPTI_STATE_RESET )
-               schedule_timeout_uninterruptible(2);
-
-       switch (cmd) {
-       // TODO: handle 3 cases
-       case DPT_SIGNATURE:
-               if (copy_to_user(argp, &DPTI_sig, sizeof(DPTI_sig))) {
-                       return -EFAULT;
-               }
-               break;
-       case I2OUSRCMD:
-               return adpt_i2o_passthru(pHba, argp);
-
-       case DPT_CTRLINFO:{
-               drvrHBAinfo_S HbaInfo;
-
-#define FLG_OSD_PCI_VALID 0x0001
-#define FLG_OSD_DMA      0x0002
-#define FLG_OSD_I2O      0x0004
-               memset(&HbaInfo, 0, sizeof(HbaInfo));
-               HbaInfo.drvrHBAnum = pHba->unit;
-               HbaInfo.baseAddr = (ulong) pHba->base_addr_phys;
-               HbaInfo.blinkState = adpt_read_blink_led(pHba);
-               HbaInfo.pciBusNum =  pHba->pDev->bus->number;
-               HbaInfo.pciDeviceNum=PCI_SLOT(pHba->pDev->devfn); 
-               HbaInfo.Interrupt = pHba->pDev->irq; 
-               HbaInfo.hbaFlags = FLG_OSD_PCI_VALID | FLG_OSD_DMA | FLG_OSD_I2O;
-               if(copy_to_user(argp, &HbaInfo, sizeof(HbaInfo))){
-                       printk(KERN_WARNING"%s: Could not copy HbaInfo TO user\n",pHba->name);
-                       return -EFAULT;
-               }
-               break;
-               }
-       case DPT_SYSINFO:
-               return adpt_system_info(argp);
-       case DPT_BLINKLED:{
-               u32 value;
-               value = (u32)adpt_read_blink_led(pHba);
-               if (copy_to_user(argp, &value, sizeof(value))) {
-                       return -EFAULT;
-               }
-               break;
-               }
-       case I2ORESETCMD: {
-               struct Scsi_Host *shost = pHba->host;
-
-               if (shost)
-                       spin_lock_irqsave(shost->host_lock, flags);
-               adpt_hba_reset(pHba);
-               if (shost)
-                       spin_unlock_irqrestore(shost->host_lock, flags);
-               break;
-       }
-       case I2ORESCANCMD:
-               adpt_rescan(pHba);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return error;
-}
-
-static long adpt_unlocked_ioctl(struct file *file, uint cmd, ulong arg)
-{
-       struct inode *inode;
-       long ret;
-       inode = file_inode(file);
-       mutex_lock(&adpt_mutex);
-       ret = adpt_ioctl(inode, file, cmd, arg);
-       mutex_unlock(&adpt_mutex);
-
-       return ret;
-}
-
-#ifdef CONFIG_COMPAT
-static long compat_adpt_ioctl(struct file *file,
-                               unsigned int cmd, unsigned long arg)
-{
-       struct inode *inode;
-       long ret;
-       inode = file_inode(file);
-       mutex_lock(&adpt_mutex);
-       switch(cmd) {
-               case DPT_SIGNATURE:
-               case I2OUSRCMD:
-               case DPT_CTRLINFO:
-               case DPT_SYSINFO:
-               case DPT_BLINKLED:
-               case I2ORESETCMD:
-               case I2ORESCANCMD:
-               case (DPT_TARGET_BUSY & 0xFFFF):
-               case DPT_TARGET_BUSY:
-                       ret = adpt_ioctl(inode, file, cmd, arg);
-                       break;
-               default:
-                       ret =  -ENOIOCTLCMD;
-       }
-       mutex_unlock(&adpt_mutex);
-       return ret;
-}
-#endif
-
-static irqreturn_t adpt_isr(int irq, void *dev_id)
-{
-       struct scsi_cmnd* cmd;
-       adpt_hba* pHba = dev_id;
-       u32 m;
-       void __iomem *reply;
-       u32 status=0;
-       u32 context;
-       ulong flags = 0;
-       int handled = 0;
-
-       if (pHba == NULL){
-               printk(KERN_WARNING"adpt_isr: NULL dev_id\n");
-               return IRQ_NONE;
-       }
-       if(pHba->host)
-               spin_lock_irqsave(pHba->host->host_lock, flags);
-
-       while( readl(pHba->irq_mask) & I2O_INTERRUPT_PENDING_B) {
-               m = readl(pHba->reply_port);
-               if(m == EMPTY_QUEUE){
-                       // Try twice then give up
-                       rmb();
-                       m = readl(pHba->reply_port);
-                       if(m == EMPTY_QUEUE){ 
-                               // This really should not happen
-                               printk(KERN_ERR"dpti: Could not get reply frame\n");
-                               goto out;
-                       }
-               }
-               if (pHba->reply_pool_pa <= m &&
-                   m < pHba->reply_pool_pa +
-                       (pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4)) {
-                       reply = (u8 *)pHba->reply_pool +
-                                               (m - pHba->reply_pool_pa);
-               } else {
-                       /* Ick, we should *never* be here */
-                       printk(KERN_ERR "dpti: reply frame not from pool\n");
-                       reply = (u8 *)bus_to_virt(m);
-               }
-
-               if (readl(reply) & MSG_FAIL) {
-                       u32 old_m = readl(reply+28); 
-                       void __iomem *msg;
-                       u32 old_context;
-                       PDEBUG("%s: Failed message\n",pHba->name);
-                       if(old_m >= 0x100000){
-                               printk(KERN_ERR"%s: Bad preserved MFA (%x)- dropping frame\n",pHba->name,old_m);
-                               writel(m,pHba->reply_port);
-                               continue;
-                       }
-                       // Transaction context is 0 in failed reply frame
-                       msg = pHba->msg_addr_virt + old_m;
-                       old_context = readl(msg+12);
-                       writel(old_context, reply+12);
-                       adpt_send_nop(pHba, old_m);
-               } 
-               context = readl(reply+8);
-               if(context & 0x40000000){ // IOCTL
-                       void *p = adpt_ioctl_from_context(pHba, readl(reply+12));
-                       if( p != NULL) {
-                               memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4);
-                       }
-                       // All IOCTLs will also be post wait
-               }
-               if(context & 0x80000000){ // Post wait message
-                       status = readl(reply+16);
-                       if(status  >> 24){
-                               status &=  0xffff; /* Get detail status */
-                       } else {
-                               status = I2O_POST_WAIT_OK;
-                       }
-                       if(!(context & 0x40000000)) {
-                               /*
-                                * The request tag is one less than the command tag
-                                * as the firmware might treat a 0 tag as invalid
-                                */
-                               cmd = scsi_host_find_tag(pHba->host,
-                                                        readl(reply + 12) - 1);
-                               if(cmd != NULL) {
-                                       printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
-                               }
-                       }
-                       adpt_i2o_post_wait_complete(context, status);
-               } else { // SCSI message
-                       /*
-                        * The request tag is one less than the command tag
-                        * as the firmware might treat a 0 tag as invalid
-                        */
-                       cmd = scsi_host_find_tag(pHba->host,
-                                                readl(reply + 12) - 1);
-                       if(cmd != NULL){
-                               scsi_dma_unmap(cmd);
-                               adpt_i2o_scsi_complete(reply, cmd);
-                       }
-               }
-               writel(m, pHba->reply_port);
-               wmb();
-               rmb();
-       }
-       handled = 1;
-out:   if(pHba->host)
-               spin_unlock_irqrestore(pHba->host->host_lock, flags);
-       return IRQ_RETVAL(handled);
-}
-
-static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* d)
-{
-       int i;
-       u32 msg[MAX_MESSAGE_SIZE];
-       u32* mptr;
-       u32* lptr;
-       u32 *lenptr;
-       int direction;
-       int scsidir;
-       int nseg;
-       u32 len;
-       u32 reqlen;
-       s32 rcode;
-       dma_addr_t addr;
-
-       memset(msg, 0 , sizeof(msg));
-       len = scsi_bufflen(cmd);
-       direction = 0x00000000; 
-       
-       scsidir = 0x00000000;                   // DATA NO XFER
-       if(len) {
-               /*
-                * Set SCBFlags to indicate if data is being transferred
-                * in or out, or no data transfer
-                * Note:  Do not have to verify index is less than 0 since
-                * cmd->cmnd[0] is an unsigned char
-                */
-               switch(cmd->sc_data_direction){
-               case DMA_FROM_DEVICE:
-                       scsidir  =0x40000000;   // DATA IN  (iop<--dev)
-                       break;
-               case DMA_TO_DEVICE:
-                       direction=0x04000000;   // SGL OUT
-                       scsidir  =0x80000000;   // DATA OUT (iop-->dev)
-                       break;
-               case DMA_NONE:
-                       break;
-               case DMA_BIDIRECTIONAL:
-                       scsidir  =0x40000000;   // DATA IN  (iop<--dev)
-                       // Assume In - and continue;
-                       break;
-               default:
-                       printk(KERN_WARNING"%s: scsi opcode 0x%x not supported.\n",
-                            pHba->name, cmd->cmnd[0]);
-                       cmd->result = (DID_ERROR <<16);
-                       scsi_done(cmd);
-                       return  0;
-               }
-       }
-       // msg[0] is set later
-       // I2O_CMD_SCSI_EXEC
-       msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid);
-       msg[2] = 0;
-       /* Add 1 to avoid firmware treating it as invalid command */
-       msg[3] = scsi_cmd_to_rq(cmd)->tag + 1;
-       // Our cards use the transaction context as the tag for queueing
-       // Adaptec/DPT Private stuff 
-       msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16);
-       msg[5] = d->tid;
-       /* Direction, disconnect ok | sense data | simple queue , CDBLen */
-       // I2O_SCB_FLAG_ENABLE_DISCONNECT | 
-       // I2O_SCB_FLAG_SIMPLE_QUEUE_TAG | 
-       // I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
-       msg[6] = scsidir|0x20a00000|cmd->cmd_len;
-
-       mptr=msg+7;
-
-       // Write SCSI command into the message - always 16 byte block 
-       memset(mptr, 0,  16);
-       memcpy(mptr, cmd->cmnd, cmd->cmd_len);
-       mptr+=4;
-       lenptr=mptr++;          /* Remember me - fill in when we know */
-       if (dpt_dma64(pHba)) {
-               reqlen = 16;            // SINGLE SGE
-               *mptr++ = (0x7C<<24)+(2<<16)+0x02; /* Enable 64 bit */
-               *mptr++ = 1 << PAGE_SHIFT;
-       } else {
-               reqlen = 14;            // SINGLE SGE
-       }
-       /* Now fill in the SGList and command */
-
-       nseg = scsi_dma_map(cmd);
-       BUG_ON(nseg < 0);
-       if (nseg) {
-               struct scatterlist *sg;
-
-               len = 0;
-               scsi_for_each_sg(cmd, sg, nseg, i) {
-                       lptr = mptr;
-                       *mptr++ = direction|0x10000000|sg_dma_len(sg);
-                       len+=sg_dma_len(sg);
-                       addr = sg_dma_address(sg);
-                       *mptr++ = dma_low(addr);
-                       if (dpt_dma64(pHba))
-                               *mptr++ = dma_high(addr);
-                       /* Make this an end of list */
-                       if (i == nseg - 1)
-                               *lptr = direction|0xD0000000|sg_dma_len(sg);
-               }
-               reqlen = mptr - msg;
-               *lenptr = len;
-               
-               if(cmd->underflow && len != cmd->underflow){
-                       printk(KERN_WARNING"Cmd len %08X Cmd underflow %08X\n",
-                               len, cmd->underflow);
-               }
-       } else {
-               *lenptr = len = 0;
-               reqlen = 12;
-       }
-       
-       /* Stick the headers on */
-       msg[0] = reqlen<<16 | ((reqlen > 12) ? SGL_OFFSET_12 : SGL_OFFSET_0);
-       
-       // Send it on it's way
-       rcode = adpt_i2o_post_this(pHba, msg, reqlen<<2);
-       if (rcode == 0) {
-               return 0;
-       }
-       return rcode;
-}
-
-
-static s32 adpt_scsi_host_alloc(adpt_hba* pHba, struct scsi_host_template *sht)
-{
-       struct Scsi_Host *host;
-
-       host = scsi_host_alloc(sht, sizeof(adpt_hba*));
-       if (host == NULL) {
-               printk("%s: scsi_host_alloc returned NULL\n", pHba->name);
-               return -1;
-       }
-       host->hostdata[0] = (unsigned long)pHba;
-       pHba->host = host;
-
-       host->irq = pHba->pDev->irq;
-       /* no IO ports, so don't have to set host->io_port and
-        * host->n_io_port
-        */
-       host->io_port = 0;
-       host->n_io_port = 0;
-                               /* see comments in scsi_host.h */
-       host->max_id = 16;
-       host->max_lun = 256;
-       host->max_channel = pHba->top_scsi_channel + 1;
-       host->cmd_per_lun = 1;
-       host->unique_id = (u32)sys_tbl_pa + pHba->unit;
-       host->sg_tablesize = pHba->sg_tablesize;
-       host->can_queue = pHba->post_fifo_size;
-
-       return 0;
-}
-
-
-static void adpt_i2o_scsi_complete(void __iomem *reply, struct scsi_cmnd *cmd)
-{
-       adpt_hba* pHba;
-       u32 hba_status;
-       u32 dev_status;
-       u32 reply_flags = readl(reply) & 0xff00; // Leave it shifted up 8 bits 
-       // I know this would look cleaner if I just read bytes
-       // but the model I have been using for all the rest of the
-       // io is in 4 byte words - so I keep that model
-       u16 detailed_status = readl(reply+16) &0xffff;
-       dev_status = (detailed_status & 0xff);
-       hba_status = detailed_status >> 8;
-
-       // calculate resid for sg 
-       scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+20));
-
-       pHba = (adpt_hba*) cmd->device->host->hostdata[0];
-
-       cmd->sense_buffer[0] = '\0';  // initialize sense valid flag to false
-
-       if(!(reply_flags & MSG_FAIL)) {
-               switch(detailed_status & I2O_SCSI_DSC_MASK) {
-               case I2O_SCSI_DSC_SUCCESS:
-                       cmd->result = (DID_OK << 16);
-                       // handle underflow
-                       if (readl(reply+20) < cmd->underflow) {
-                               cmd->result = (DID_ERROR <<16);
-                               printk(KERN_WARNING"%s: SCSI CMD underflow\n",pHba->name);
-                       }
-                       break;
-               case I2O_SCSI_DSC_REQUEST_ABORTED:
-                       cmd->result = (DID_ABORT << 16);
-                       break;
-               case I2O_SCSI_DSC_PATH_INVALID:
-               case I2O_SCSI_DSC_DEVICE_NOT_PRESENT:
-               case I2O_SCSI_DSC_SELECTION_TIMEOUT:
-               case I2O_SCSI_DSC_COMMAND_TIMEOUT:
-               case I2O_SCSI_DSC_NO_ADAPTER:
-               case I2O_SCSI_DSC_RESOURCE_UNAVAILABLE:
-                       printk(KERN_WARNING"%s: SCSI Timeout-Device (%d,%d,%llu) hba status=0x%x, dev status=0x%x, cmd=0x%x\n",
-                               pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, cmd->device->lun, hba_status, dev_status, cmd->cmnd[0]);
-                       cmd->result = (DID_TIME_OUT << 16);
-                       break;
-               case I2O_SCSI_DSC_ADAPTER_BUSY:
-               case I2O_SCSI_DSC_BUS_BUSY:
-                       cmd->result = (DID_BUS_BUSY << 16);
-                       break;
-               case I2O_SCSI_DSC_SCSI_BUS_RESET:
-               case I2O_SCSI_DSC_BDR_MESSAGE_SENT:
-                       cmd->result = (DID_RESET << 16);
-                       break;
-               case I2O_SCSI_DSC_PARITY_ERROR_FAILURE:
-                       printk(KERN_WARNING"%s: SCSI CMD parity error\n",pHba->name);
-                       cmd->result = (DID_PARITY << 16);
-                       break;
-               case I2O_SCSI_DSC_UNABLE_TO_ABORT:
-               case I2O_SCSI_DSC_COMPLETE_WITH_ERROR:
-               case I2O_SCSI_DSC_UNABLE_TO_TERMINATE:
-               case I2O_SCSI_DSC_MR_MESSAGE_RECEIVED:
-               case I2O_SCSI_DSC_AUTOSENSE_FAILED:
-               case I2O_SCSI_DSC_DATA_OVERRUN:
-               case I2O_SCSI_DSC_UNEXPECTED_BUS_FREE:
-               case I2O_SCSI_DSC_SEQUENCE_FAILURE:
-               case I2O_SCSI_DSC_REQUEST_LENGTH_ERROR:
-               case I2O_SCSI_DSC_PROVIDE_FAILURE:
-               case I2O_SCSI_DSC_REQUEST_TERMINATED:
-               case I2O_SCSI_DSC_IDE_MESSAGE_SENT:
-               case I2O_SCSI_DSC_UNACKNOWLEDGED_EVENT:
-               case I2O_SCSI_DSC_MESSAGE_RECEIVED:
-               case I2O_SCSI_DSC_INVALID_CDB:
-               case I2O_SCSI_DSC_LUN_INVALID:
-               case I2O_SCSI_DSC_SCSI_TID_INVALID:
-               case I2O_SCSI_DSC_FUNCTION_UNAVAILABLE:
-               case I2O_SCSI_DSC_NO_NEXUS:
-               case I2O_SCSI_DSC_CDB_RECEIVED:
-               case I2O_SCSI_DSC_LUN_ALREADY_ENABLED:
-               case I2O_SCSI_DSC_QUEUE_FROZEN:
-               case I2O_SCSI_DSC_REQUEST_INVALID:
-               default:
-                       printk(KERN_WARNING"%s: SCSI error %0x-Device(%d,%d,%llu) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
-                               pHba->name, detailed_status & I2O_SCSI_DSC_MASK, (u32)cmd->device->channel, (u32)cmd->device->id, cmd->device->lun,
-                              hba_status, dev_status, cmd->cmnd[0]);
-                       cmd->result = (DID_ERROR << 16);
-                       break;
-               }
-
-               // copy over the request sense data if it was a check
-               // condition status
-               if (dev_status == SAM_STAT_CHECK_CONDITION) {
-                       u32 len = min(SCSI_SENSE_BUFFERSIZE, 40);
-                       // Copy over the sense data
-                       memcpy_fromio(cmd->sense_buffer, (reply+28) , len);
-                       if(cmd->sense_buffer[0] == 0x70 /* class 7 */ && 
-                          cmd->sense_buffer[2] == DATA_PROTECT ){
-                               /* This is to handle an array failed */
-                               cmd->result = (DID_TIME_OUT << 16);
-                               printk(KERN_WARNING"%s: SCSI Data Protect-Device (%d,%d,%llu) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
-                                       pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, cmd->device->lun,
-                                       hba_status, dev_status, cmd->cmnd[0]);
-
-                       }
-               }
-       } else {
-               /* In this condtion we could not talk to the tid
-                * the card rejected it.  We should signal a retry
-                * for a limitted number of retries.
-                */
-               cmd->result = (DID_TIME_OUT << 16);
-               printk(KERN_WARNING"%s: I2O MSG_FAIL - Device (%d,%d,%llu) tid=%d, cmd=0x%x\n",
-                       pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, cmd->device->lun,
-                       ((struct adpt_device*)(cmd->device->hostdata))->tid, cmd->cmnd[0]);
-       }
-
-       cmd->result |= (dev_status);
-
-       scsi_done(cmd);
-}
-
-
-static s32 adpt_rescan(adpt_hba* pHba)
-{
-       s32 rcode;
-       ulong flags = 0;
-
-       if(pHba->host)
-               spin_lock_irqsave(pHba->host->host_lock, flags);
-       if ((rcode=adpt_i2o_lct_get(pHba)) < 0)
-               goto out;
-       if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0)
-               goto out;
-       rcode = 0;
-out:   if(pHba->host)
-               spin_unlock_irqrestore(pHba->host->host_lock, flags);
-       return rcode;
-}
-
-
-static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
-{
-       int i;
-       int max;
-       int tid;
-       struct i2o_device *d;
-       i2o_lct *lct = pHba->lct;
-       u8 bus_no = 0;
-       s16 scsi_id;
-       u64 scsi_lun;
-       u32 buf[10]; // at least 8 u32's
-       struct adpt_device* pDev = NULL;
-       struct i2o_device* pI2o_dev = NULL;
-       
-       if (lct == NULL) {
-               printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
-               return -1;
-       }
-       
-       max = lct->table_size;  
-       max -= 3;
-       max /= 9;
-
-       // Mark each drive as unscanned
-       for (d = pHba->devices; d; d = d->next) {
-               pDev =(struct adpt_device*) d->owner;
-               if(!pDev){
-                       continue;
-               }
-               pDev->state |= DPTI_DEV_UNSCANNED;
-       }
-
-       printk(KERN_INFO "%s: LCT has %d entries.\n", pHba->name,max);
-       
-       for(i=0;i<max;i++) {
-               if( lct->lct_entry[i].user_tid != 0xfff){
-                       continue;
-               }
-
-               if( lct->lct_entry[i].class_id == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
-                   lct->lct_entry[i].class_id == I2O_CLASS_SCSI_PERIPHERAL ||
-                   lct->lct_entry[i].class_id == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
-                       tid = lct->lct_entry[i].tid;
-                       if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
-                               printk(KERN_ERR"%s: Could not query device\n",pHba->name);
-                               continue;
-                       }
-                       bus_no = buf[0]>>16;
-                       if (bus_no >= MAX_CHANNEL) {    /* Something wrong skip it */
-                               printk(KERN_WARNING
-                                       "%s: Channel number %d out of range\n",
-                                       pHba->name, bus_no);
-                               continue;
-                       }
-
-                       scsi_id = buf[1];
-                       scsi_lun = scsilun_to_int((struct scsi_lun *)&buf[2]);
-                       pDev = pHba->channel[bus_no].device[scsi_id];
-                       /* da lun */
-                       while(pDev) {
-                               if(pDev->scsi_lun == scsi_lun) {
-                                       break;
-                               }
-                               pDev = pDev->next_lun;
-                       }
-                       if(!pDev ) { // Something new add it
-                               d = kmalloc(sizeof(struct i2o_device),
-                                           GFP_ATOMIC);
-                               if(d==NULL)
-                               {
-                                       printk(KERN_CRIT "Out of memory for I2O device data.\n");
-                                       return -ENOMEM;
-                               }
-                               
-                               d->controller = pHba;
-                               d->next = NULL;
-
-                               memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
-
-                               d->flags = 0;
-                               adpt_i2o_report_hba_unit(pHba, d);
-                               adpt_i2o_install_device(pHba, d);
-       
-                               pDev = pHba->channel[bus_no].device[scsi_id];   
-                               if( pDev == NULL){
-                                       pDev =
-                                         kzalloc(sizeof(struct adpt_device),
-                                                 GFP_ATOMIC);
-                                       if(pDev == NULL) {
-                                               return -ENOMEM;
-                                       }
-                                       pHba->channel[bus_no].device[scsi_id] = pDev;
-                               } else {
-                                       while (pDev->next_lun) {
-                                               pDev = pDev->next_lun;
-                                       }
-                                       pDev = pDev->next_lun =
-                                         kzalloc(sizeof(struct adpt_device),
-                                                 GFP_ATOMIC);
-                                       if(pDev == NULL) {
-                                               return -ENOMEM;
-                                       }
-                               }
-                               pDev->tid = d->lct_data.tid;
-                               pDev->scsi_channel = bus_no;
-                               pDev->scsi_id = scsi_id;
-                               pDev->scsi_lun = scsi_lun;
-                               pDev->pI2o_dev = d;
-                               d->owner = pDev;
-                               pDev->type = (buf[0])&0xff;
-                               pDev->flags = (buf[0]>>8)&0xff;
-                               // Too late, SCSI system has made up it's mind, but what the hey ...
-                               if(scsi_id > pHba->top_scsi_id){
-                                       pHba->top_scsi_id = scsi_id;
-                               }
-                               if(scsi_lun > pHba->top_scsi_lun){
-                                       pHba->top_scsi_lun = scsi_lun;
-                               }
-                               continue;
-                       } // end of new i2o device
-
-                       // We found an old device - check it
-                       while(pDev) {
-                               if(pDev->scsi_lun == scsi_lun) {
-                                       if(!scsi_device_online(pDev->pScsi_dev)) {
-                                               printk(KERN_WARNING"%s: Setting device (%d,%d,%llu) back online\n",
-                                                               pHba->name,bus_no,scsi_id,scsi_lun);
-                                               if (pDev->pScsi_dev) {
-                                                       scsi_device_set_state(pDev->pScsi_dev, SDEV_RUNNING);
-                                               }
-                                       }
-                                       d = pDev->pI2o_dev;
-                                       if(d->lct_data.tid != tid) { // something changed
-                                               pDev->tid = tid;
-                                               memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
-                                               if (pDev->pScsi_dev) {
-                                                       pDev->pScsi_dev->changed = TRUE;
-                                                       pDev->pScsi_dev->removable = TRUE;
-                                               }
-                                       }
-                                       // Found it - mark it scanned
-                                       pDev->state = DPTI_DEV_ONLINE;
-                                       break;
-                               }
-                               pDev = pDev->next_lun;
-                       }
-               }
-       }
-       for (pI2o_dev = pHba->devices; pI2o_dev; pI2o_dev = pI2o_dev->next) {
-               pDev =(struct adpt_device*) pI2o_dev->owner;
-               if(!pDev){
-                       continue;
-               }
-               // Drive offline drives that previously existed but could not be found
-               // in the LCT table
-               if (pDev->state & DPTI_DEV_UNSCANNED){
-                       pDev->state = DPTI_DEV_OFFLINE;
-                       printk(KERN_WARNING"%s: Device (%d,%d,%llu) offline\n",pHba->name,pDev->scsi_channel,pDev->scsi_id,pDev->scsi_lun);
-                       if (pDev->pScsi_dev) {
-                               scsi_device_set_state(pDev->pScsi_dev, SDEV_OFFLINE);
-                       }
-               }
-       }
-       return 0;
-}
-
-/*============================================================================
- *  Routines from i2o subsystem
- *============================================================================
- */
-
-
-
-/*
- *     Bring an I2O controller into HOLD state. See the spec.
- */
-static int adpt_i2o_activate_hba(adpt_hba* pHba)
-{
-       int rcode;
-
-       if(pHba->initialized ) {
-               if (adpt_i2o_status_get(pHba) < 0) {
-                       if((rcode = adpt_i2o_reset_hba(pHba)) != 0){
-                               printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
-                               return rcode;
-                       }
-                       if (adpt_i2o_status_get(pHba) < 0) {
-                               printk(KERN_INFO "HBA not responding.\n");
-                               return -1;
-                       }
-               }
-
-               if(pHba->status_block->iop_state == ADAPTER_STATE_FAULTED) {
-                       printk(KERN_CRIT "%s: hardware fault\n", pHba->name);
-                       return -1;
-               }
-
-               if (pHba->status_block->iop_state == ADAPTER_STATE_READY ||
-                   pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL ||
-                   pHba->status_block->iop_state == ADAPTER_STATE_HOLD ||
-                   pHba->status_block->iop_state == ADAPTER_STATE_FAILED) {
-                       adpt_i2o_reset_hba(pHba);                       
-                       if (adpt_i2o_status_get(pHba) < 0 || pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
-                               printk(KERN_ERR "%s: Failed to initialize.\n", pHba->name);
-                               return -1;
-                       }
-               }
-       } else {
-               if((rcode = adpt_i2o_reset_hba(pHba)) != 0){
-                       printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
-                       return rcode;
-               }
-
-       }
-
-       if (adpt_i2o_init_outbound_q(pHba) < 0) {
-               return -1;
-       }
-
-       /* In HOLD state */
-       
-       if (adpt_i2o_hrt_get(pHba) < 0) {
-               return -1;
-       }
-
-       return 0;
-}
-
-/*
- *     Bring a controller online into OPERATIONAL state. 
- */
-static int adpt_i2o_online_hba(adpt_hba* pHba)
-{
-       if (adpt_i2o_systab_send(pHba) < 0)
-               return -1;
-       /* In READY state */
-
-       if (adpt_i2o_enable_hba(pHba) < 0)
-               return -1;
-
-       /* In OPERATIONAL state  */
-       return 0;
-}
-
-static s32 adpt_send_nop(adpt_hba*pHba,u32 m)
-{
-       u32 __iomem *msg;
-       ulong timeout = jiffies + 5*HZ;
-
-       while(m == EMPTY_QUEUE){
-               rmb();
-               m = readl(pHba->post_port);
-               if(m != EMPTY_QUEUE){
-                       break;
-               }
-               if(time_after(jiffies,timeout)){
-                       printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name);
-                       return 2;
-               }
-               schedule_timeout_uninterruptible(1);
-       }
-       msg = (u32 __iomem *)(pHba->msg_addr_virt + m);
-       writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
-       writel( I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0,&msg[1]);
-       writel( 0,&msg[2]);
-       wmb();
-
-       writel(m, pHba->post_port);
-       wmb();
-       return 0;
-}
-
-static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
-{
-       u8 *status;
-       dma_addr_t addr;
-       u32 __iomem *msg = NULL;
-       int i;
-       ulong timeout = jiffies + TMOUT_INITOUTBOUND*HZ;
-       u32 m;
-
-       do {
-               rmb();
-               m = readl(pHba->post_port);
-               if (m != EMPTY_QUEUE) {
-                       break;
-               }
-
-               if(time_after(jiffies,timeout)){
-                       printk(KERN_WARNING"%s: Timeout waiting for message frame\n",pHba->name);
-                       return -ETIMEDOUT;
-               }
-               schedule_timeout_uninterruptible(1);
-       } while(m == EMPTY_QUEUE);
-
-       msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
-
-       status = dma_alloc_coherent(&pHba->pDev->dev, 4, &addr, GFP_KERNEL);
-       if (!status) {
-               adpt_send_nop(pHba, m);
-               printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n",
-                       pHba->name);
-               return -ENOMEM;
-       }
-
-       writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]);
-       writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]);
-       writel(0, &msg[2]);
-       writel(0x0106, &msg[3]);        /* Transaction context */
-       writel(4096, &msg[4]);          /* Host page frame size */
-       writel((REPLY_FRAME_SIZE)<<16|0x80, &msg[5]);   /* Outbound msg frame size and Initcode */
-       writel(0xD0000004, &msg[6]);            /* Simple SG LE, EOB */
-       writel((u32)addr, &msg[7]);
-
-       writel(m, pHba->post_port);
-       wmb();
-
-       // Wait for the reply status to come back
-       do {
-               if (*status) {
-                       if (*status != 0x01 /*I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS*/) {
-                               break;
-                       }
-               }
-               rmb();
-               if(time_after(jiffies,timeout)){
-                       printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
-                       /* We lose 4 bytes of "status" here, but we
-                          cannot free these because controller may
-                          awake and corrupt those bytes at any time */
-                       /* dma_free_coherent(&pHba->pDev->dev, 4, status, addr); */
-                       return -ETIMEDOUT;
-               }
-               schedule_timeout_uninterruptible(1);
-       } while (1);
-
-       // If the command was successful, fill the fifo with our reply
-       // message packets
-       if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) {
-               dma_free_coherent(&pHba->pDev->dev, 4, status, addr);
-               return -2;
-       }
-       dma_free_coherent(&pHba->pDev->dev, 4, status, addr);
-
-       if(pHba->reply_pool != NULL) {
-               dma_free_coherent(&pHba->pDev->dev,
-                       pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4,
-                       pHba->reply_pool, pHba->reply_pool_pa);
-       }
-
-       pHba->reply_pool = dma_alloc_coherent(&pHba->pDev->dev,
-                               pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4,
-                               &pHba->reply_pool_pa, GFP_KERNEL);
-       if (!pHba->reply_pool) {
-               printk(KERN_ERR "%s: Could not allocate reply pool\n", pHba->name);
-               return -ENOMEM;
-       }
-
-       for(i = 0; i < pHba->reply_fifo_size; i++) {
-               writel(pHba->reply_pool_pa + (i * REPLY_FRAME_SIZE * 4),
-                       pHba->reply_port);
-               wmb();
-       }
-       adpt_i2o_status_get(pHba);
-       return 0;
-}
-
-
-/*
- * I2O System Table.  Contains information about
- * all the IOPs in the system.  Used to inform IOPs
- * about each other's existence.
- *
- * sys_tbl_ver is the CurrentChangeIndicator that is
- * used by IOPs to track changes.
- */
-
-
-
-static s32 adpt_i2o_status_get(adpt_hba* pHba)
-{
-       ulong timeout;
-       u32 m;
-       u32 __iomem *msg;
-       u8 *status_block=NULL;
-
-       if(pHba->status_block == NULL) {
-               pHba->status_block = dma_alloc_coherent(&pHba->pDev->dev,
-                                       sizeof(i2o_status_block),
-                                       &pHba->status_block_pa, GFP_KERNEL);
-               if(pHba->status_block == NULL) {
-                       printk(KERN_ERR
-                       "dpti%d: Get Status Block failed; Out of memory. \n", 
-                       pHba->unit);
-                       return -ENOMEM;
-               }
-       }
-       memset(pHba->status_block, 0, sizeof(i2o_status_block));
-       status_block = (u8*)(pHba->status_block);
-       timeout = jiffies+TMOUT_GETSTATUS*HZ;
-       do {
-               rmb();
-               m = readl(pHba->post_port);
-               if (m != EMPTY_QUEUE) {
-                       break;
-               }
-               if(time_after(jiffies,timeout)){
-                       printk(KERN_ERR "%s: Timeout waiting for message !\n",
-                                       pHba->name);
-                       return -ETIMEDOUT;
-               }
-               schedule_timeout_uninterruptible(1);
-       } while(m==EMPTY_QUEUE);
-
-       
-       msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
-
-       writel(NINE_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]);
-       writel(I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID, &msg[1]);
-       writel(1, &msg[2]);
-       writel(0, &msg[3]);
-       writel(0, &msg[4]);
-       writel(0, &msg[5]);
-       writel( dma_low(pHba->status_block_pa), &msg[6]);
-       writel( dma_high(pHba->status_block_pa), &msg[7]);
-       writel(sizeof(i2o_status_block), &msg[8]); // 88 bytes
-
-       //post message
-       writel(m, pHba->post_port);
-       wmb();
-
-       while(status_block[87]!=0xff){
-               if(time_after(jiffies,timeout)){
-                       printk(KERN_ERR"dpti%d: Get status timeout.\n",
-                               pHba->unit);
-                       return -ETIMEDOUT;
-               }
-               rmb();
-               schedule_timeout_uninterruptible(1);
-       }
-
-       // Set up our number of outbound and inbound messages
-       pHba->post_fifo_size = pHba->status_block->max_inbound_frames;
-       if (pHba->post_fifo_size > MAX_TO_IOP_MESSAGES) {
-               pHba->post_fifo_size = MAX_TO_IOP_MESSAGES;
-       }
-
-       pHba->reply_fifo_size = pHba->status_block->max_outbound_frames;
-       if (pHba->reply_fifo_size > MAX_FROM_IOP_MESSAGES) {
-               pHba->reply_fifo_size = MAX_FROM_IOP_MESSAGES;
-       }
-
-       // Calculate the Scatter Gather list size
-       if (dpt_dma64(pHba)) {
-               pHba->sg_tablesize
-                 = ((pHba->status_block->inbound_frame_size * 4
-                 - 14 * sizeof(u32))
-                 / (sizeof(struct sg_simple_element) + sizeof(u32)));
-       } else {
-               pHba->sg_tablesize
-                 = ((pHba->status_block->inbound_frame_size * 4
-                 - 12 * sizeof(u32))
-                 / sizeof(struct sg_simple_element));
-       }
-       if (pHba->sg_tablesize > SG_LIST_ELEMENTS) {
-               pHba->sg_tablesize = SG_LIST_ELEMENTS;
-       }
-
-
-#ifdef DEBUG
-       printk("dpti%d: State = ",pHba->unit);
-       switch(pHba->status_block->iop_state) {
-               case 0x01:
-                       printk("INIT\n");
-                       break;
-               case 0x02:
-                       printk("RESET\n");
-                       break;
-               case 0x04:
-                       printk("HOLD\n");
-                       break;
-               case 0x05:
-                       printk("READY\n");
-                       break;
-               case 0x08:
-                       printk("OPERATIONAL\n");
-                       break;
-               case 0x10:
-                       printk("FAILED\n");
-                       break;
-               case 0x11:
-                       printk("FAULTED\n");
-                       break;
-               default:
-                       printk("%x (unknown!!)\n",pHba->status_block->iop_state);
-       }
-#endif
-       return 0;
-}
-
-/*
- * Get the IOP's Logical Configuration Table
- */
-static int adpt_i2o_lct_get(adpt_hba* pHba)
-{
-       u32 msg[8];
-       int ret;
-       u32 buf[16];
-
-       if ((pHba->lct_size == 0) || (pHba->lct == NULL)){
-               pHba->lct_size = pHba->status_block->expected_lct_size;
-       }
-       do {
-               if (pHba->lct == NULL) {
-                       pHba->lct = dma_alloc_coherent(&pHba->pDev->dev,
-                                       pHba->lct_size, &pHba->lct_pa,
-                                       GFP_ATOMIC);
-                       if(pHba->lct == NULL) {
-                               printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n",
-                                       pHba->name);
-                               return -ENOMEM;
-                       }
-               }
-               memset(pHba->lct, 0, pHba->lct_size);
-
-               msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6;
-               msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
-               msg[2] = 0;
-               msg[3] = 0;
-               msg[4] = 0xFFFFFFFF;    /* All devices */
-               msg[5] = 0x00000000;    /* Report now */
-               msg[6] = 0xD0000000|pHba->lct_size;
-               msg[7] = (u32)pHba->lct_pa;
-
-               if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 360))) {
-                       printk(KERN_ERR "%s: LCT Get failed (status=%#10x.\n", 
-                               pHba->name, ret);       
-                       printk(KERN_ERR"Adaptec: Error Reading Hardware.\n");
-                       return ret;
-               }
-
-               if ((pHba->lct->table_size << 2) > pHba->lct_size) {
-                       pHba->lct_size = pHba->lct->table_size << 2;
-                       dma_free_coherent(&pHba->pDev->dev, pHba->lct_size,
-                                       pHba->lct, pHba->lct_pa);
-                       pHba->lct = NULL;
-               }
-       } while (pHba->lct == NULL);
-
-       PDEBUG("%s: Hardware resource table read.\n", pHba->name);
-
-
-       // I2O_DPT_EXEC_IOP_BUFFERS_GROUP_NO;
-       if(adpt_i2o_query_scalar(pHba, 0 , 0x8000, -1, buf, sizeof(buf))>=0) {
-               pHba->FwDebugBufferSize = buf[1];
-               pHba->FwDebugBuffer_P = ioremap(pHba->base_addr_phys + buf[0],
-                                               pHba->FwDebugBufferSize);
-               if (pHba->FwDebugBuffer_P) {
-                       pHba->FwDebugFlags_P     = pHba->FwDebugBuffer_P +
-                                                       FW_DEBUG_FLAGS_OFFSET;
-                       pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P +
-                                                       FW_DEBUG_BLED_OFFSET;
-                       pHba->FwDebugBLEDflag_P  = pHba->FwDebugBLEDvalue_P + 1;
-                       pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P +
-                                               FW_DEBUG_STR_LENGTH_OFFSET;
-                       pHba->FwDebugBuffer_P += buf[2]; 
-                       pHba->FwDebugFlags = 0;
-               }
-       }
-
-       return 0;
-}
-
-static int adpt_i2o_build_sys_table(void)
-{
-       adpt_hba* pHba = hba_chain;
-       int count = 0;
-
-       if (sys_tbl)
-               dma_free_coherent(&pHba->pDev->dev, sys_tbl_len,
-                                       sys_tbl, sys_tbl_pa);
-
-       sys_tbl_len = sizeof(struct i2o_sys_tbl) +      // Header + IOPs
-                               (hba_count) * sizeof(struct i2o_sys_tbl_entry);
-
-       sys_tbl = dma_alloc_coherent(&pHba->pDev->dev,
-                               sys_tbl_len, &sys_tbl_pa, GFP_KERNEL);
-       if (!sys_tbl) {
-               printk(KERN_WARNING "SysTab Set failed. Out of memory.\n");     
-               return -ENOMEM;
-       }
-
-       sys_tbl->num_entries = hba_count;
-       sys_tbl->version = I2OVERSION;
-       sys_tbl->change_ind = sys_tbl_ind++;
-
-       for(pHba = hba_chain; pHba; pHba = pHba->next) {
-               u64 addr;
-               // Get updated Status Block so we have the latest information
-               if (adpt_i2o_status_get(pHba)) {
-                       sys_tbl->num_entries--;
-                       continue; // try next one       
-               }
-
-               sys_tbl->iops[count].org_id = pHba->status_block->org_id;
-               sys_tbl->iops[count].iop_id = pHba->unit + 2;
-               sys_tbl->iops[count].seg_num = 0;
-               sys_tbl->iops[count].i2o_version = pHba->status_block->i2o_version;
-               sys_tbl->iops[count].iop_state = pHba->status_block->iop_state;
-               sys_tbl->iops[count].msg_type = pHba->status_block->msg_type;
-               sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size;
-               sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
-               sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities;
-               addr = pHba->base_addr_phys + 0x40;
-               sys_tbl->iops[count].inbound_low = dma_low(addr);
-               sys_tbl->iops[count].inbound_high = dma_high(addr);
-
-               count++;
-       }
-
-#ifdef DEBUG
-{
-       u32 *table = (u32*)sys_tbl;
-       printk(KERN_DEBUG"sys_tbl_len=%d in 32bit words\n",(sys_tbl_len >>2));
-       for(count = 0; count < (sys_tbl_len >>2); count++) {
-               printk(KERN_INFO "sys_tbl[%d] = %0#10x\n", 
-                       count, table[count]);
-       }
-}
-#endif
-
-       return 0;
-}
-
-
-/*
- *      Dump the information block associated with a given unit (TID)
- */
-static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d)
-{
-       char buf[64];
-       int unit = d->lct_data.tid;
-
-       printk(KERN_INFO "TID %3.3d ", unit);
-
-       if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 3, buf, 16)>=0)
-       {
-               buf[16]=0;
-               printk(" Vendor: %-12.12s", buf);
-       }
-       if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 4, buf, 16)>=0)
-       {
-               buf[16]=0;
-               printk(" Device: %-12.12s", buf);
-       }
-       if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 6, buf, 8)>=0)
-       {
-               buf[8]=0;
-               printk(" Rev: %-12.12s\n", buf);
-       }
-#ifdef DEBUG
-        printk(KERN_INFO "\tClass: %.21s\n", adpt_i2o_get_class_name(d->lct_data.class_id));
-        printk(KERN_INFO "\tSubclass: 0x%04X\n", d->lct_data.sub_class);
-        printk(KERN_INFO "\tFlags: ");
-
-        if(d->lct_data.device_flags&(1<<0))
-                 printk("C");       // ConfigDialog requested
-        if(d->lct_data.device_flags&(1<<1))
-                 printk("U");       // Multi-user capable
-        if(!(d->lct_data.device_flags&(1<<4)))
-                 printk("P");       // Peer service enabled!
-        if(!(d->lct_data.device_flags&(1<<5)))
-                 printk("M");       // Mgmt service enabled!
-        printk("\n");
-#endif
-}
-
-#ifdef DEBUG
-/*
- *     Do i2o class name lookup
- */
-static const char *adpt_i2o_get_class_name(int class)
-{
-       int idx = 16;
-       static char *i2o_class_name[] = {
-               "Executive",
-               "Device Driver Module",
-               "Block Device",
-               "Tape Device",
-               "LAN Interface",
-               "WAN Interface",
-               "Fibre Channel Port",
-               "Fibre Channel Device",
-               "SCSI Device",
-               "ATE Port",
-               "ATE Device",
-               "Floppy Controller",
-               "Floppy Device",
-               "Secondary Bus Port",
-               "Peer Transport Agent",
-               "Peer Transport",
-               "Unknown"
-       };
-       
-       switch(class&0xFFF) {
-       case I2O_CLASS_EXECUTIVE:
-               idx = 0; break;
-       case I2O_CLASS_DDM:
-               idx = 1; break;
-       case I2O_CLASS_RANDOM_BLOCK_STORAGE:
-               idx = 2; break;
-       case I2O_CLASS_SEQUENTIAL_STORAGE:
-               idx = 3; break;
-       case I2O_CLASS_LAN:
-               idx = 4; break;
-       case I2O_CLASS_WAN:
-               idx = 5; break;
-       case I2O_CLASS_FIBRE_CHANNEL_PORT:
-               idx = 6; break;
-       case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL:
-               idx = 7; break;
-       case I2O_CLASS_SCSI_PERIPHERAL:
-               idx = 8; break;
-       case I2O_CLASS_ATE_PORT:
-               idx = 9; break;
-       case I2O_CLASS_ATE_PERIPHERAL:
-               idx = 10; break;
-       case I2O_CLASS_FLOPPY_CONTROLLER:
-               idx = 11; break;
-       case I2O_CLASS_FLOPPY_DEVICE:
-               idx = 12; break;
-       case I2O_CLASS_BUS_ADAPTER_PORT:
-               idx = 13; break;
-       case I2O_CLASS_PEER_TRANSPORT_AGENT:
-               idx = 14; break;
-       case I2O_CLASS_PEER_TRANSPORT:
-               idx = 15; break;
-       }
-       return i2o_class_name[idx];
-}
-#endif
-
-
-static s32 adpt_i2o_hrt_get(adpt_hba* pHba)
-{
-       u32 msg[6];
-       int ret, size = sizeof(i2o_hrt);
-
-       do {
-               if (pHba->hrt == NULL) {
-                       pHba->hrt = dma_alloc_coherent(&pHba->pDev->dev,
-                                       size, &pHba->hrt_pa, GFP_KERNEL);
-                       if (pHba->hrt == NULL) {
-                               printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", pHba->name);
-                               return -ENOMEM;
-                       }
-               }
-
-               msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4;
-               msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID;
-               msg[2]= 0;
-               msg[3]= 0;
-               msg[4]= (0xD0000000 | size);    /* Simple transaction */
-               msg[5]= (u32)pHba->hrt_pa;      /* Dump it here */
-
-               if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg),20))) {
-                       printk(KERN_ERR "%s: Unable to get HRT (status=%#10x)\n", pHba->name, ret);
-                       return ret;
-               }
-
-               if (pHba->hrt->num_entries * pHba->hrt->entry_len << 2 > size) {
-                       int newsize = pHba->hrt->num_entries * pHba->hrt->entry_len << 2;
-                       dma_free_coherent(&pHba->pDev->dev, size,
-                               pHba->hrt, pHba->hrt_pa);
-                       size = newsize;
-                       pHba->hrt = NULL;
-               }
-       } while(pHba->hrt == NULL);
-       return 0;
-}                                                                                                                                       
-
-/*
- *      Query one scalar group value or a whole scalar group.
- */                    
-static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, 
-                       int group, int field, void *buf, int buflen)
-{
-       u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
-       u8 *opblk_va;
-       dma_addr_t opblk_pa;
-       u8 *resblk_va;
-       dma_addr_t resblk_pa;
-
-       int size;
-
-       /* 8 bytes for header */
-       resblk_va = dma_alloc_coherent(&pHba->pDev->dev,
-                       sizeof(u8) * (8 + buflen), &resblk_pa, GFP_KERNEL);
-       if (resblk_va == NULL) {
-               printk(KERN_CRIT "%s: query scalar failed; Out of memory.\n", pHba->name);
-               return -ENOMEM;
-       }
-
-       opblk_va = dma_alloc_coherent(&pHba->pDev->dev,
-                       sizeof(opblk), &opblk_pa, GFP_KERNEL);
-       if (opblk_va == NULL) {
-               dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
-                       resblk_va, resblk_pa);
-               printk(KERN_CRIT "%s: query operation failed; Out of memory.\n",
-                       pHba->name);
-               return -ENOMEM;
-       }
-       if (field == -1)                /* whole group */
-                       opblk[4] = -1;
-
-       memcpy(opblk_va, opblk, sizeof(opblk));
-       size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid, 
-               opblk_va, opblk_pa, sizeof(opblk),
-               resblk_va, resblk_pa, sizeof(u8)*(8+buflen));
-       dma_free_coherent(&pHba->pDev->dev, sizeof(opblk), opblk_va, opblk_pa);
-       if (size == -ETIME) {
-               dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
-                                                       resblk_va, resblk_pa);
-               printk(KERN_WARNING "%s: issue params failed; Timed out.\n", pHba->name);
-               return -ETIME;
-       } else if (size == -EINTR) {
-               dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
-                                                       resblk_va, resblk_pa);
-               printk(KERN_WARNING "%s: issue params failed; Interrupted.\n", pHba->name);
-               return -EINTR;
-       }
-                       
-       memcpy(buf, resblk_va+8, buflen);  /* cut off header */
-
-       dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
-                                               resblk_va, resblk_pa);
-       if (size < 0)
-               return size;    
-
-       return buflen;
-}
-
-
-/*     Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
- *
- *     This function can be used for all UtilParamsGet/Set operations.
- *     The OperationBlock is given in opblk-buffer, 
- *     and results are returned in resblk-buffer.
- *     Note that the minimum sized resblk is 8 bytes and contains
- *     ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
- */
-static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, 
-                 void *opblk_va,  dma_addr_t opblk_pa, int oplen,
-               void *resblk_va, dma_addr_t resblk_pa, int reslen)
-{
-       u32 msg[9]; 
-       u32 *res = (u32 *)resblk_va;
-       int wait_status;
-
-       msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;
-       msg[1] = cmd << 24 | HOST_TID << 12 | tid; 
-       msg[2] = 0;
-       msg[3] = 0;
-       msg[4] = 0;
-       msg[5] = 0x54000000 | oplen;    /* OperationBlock */
-       msg[6] = (u32)opblk_pa;
-       msg[7] = 0xD0000000 | reslen;   /* ResultBlock */
-       msg[8] = (u32)resblk_pa;
-
-       if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) {
-               printk("adpt_i2o_issue_params: post_wait failed (%p)\n", resblk_va);
-               return wait_status;     /* -DetailedStatus */
-       }
-
-       if (res[1]&0x00FF0000) {        /* BlockStatus != SUCCESS */
-               printk(KERN_WARNING "%s: %s - Error:\n  ErrorInfoSize = 0x%02x, "
-                       "BlockStatus = 0x%02x, BlockSize = 0x%04x\n",
-                       pHba->name,
-                       (cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET"
-                                                        : "PARAMS_GET",   
-                       res[1]>>24, (res[1]>>16)&0xFF, res[1]&0xFFFF);
-               return -((res[1] >> 16) & 0xFF); /* -BlockStatus */
-       }
-
-       return 4 + ((res[1] & 0x0000FFFF) << 2); /* bytes used in resblk */
-}
-
-
-static s32 adpt_i2o_quiesce_hba(adpt_hba* pHba)
-{
-       u32 msg[4];
-       int ret;
-
-       adpt_i2o_status_get(pHba);
-
-       /* SysQuiesce discarded if IOP not in READY or OPERATIONAL state */
-
-       if((pHba->status_block->iop_state != ADAPTER_STATE_READY) &&
-          (pHba->status_block->iop_state != ADAPTER_STATE_OPERATIONAL)){
-               return 0;
-       }
-
-       msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
-       msg[1] = I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID;
-       msg[2] = 0;
-       msg[3] = 0;
-
-       if((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
-               printk(KERN_INFO"dpti%d: Unable to quiesce (status=%#x).\n",
-                               pHba->unit, -ret);
-       } else {
-               printk(KERN_INFO"dpti%d: Quiesced.\n",pHba->unit);
-       }
-
-       adpt_i2o_status_get(pHba);
-       return ret;
-}
-
-
-/* 
- * Enable IOP. Allows the IOP to resume external operations.
- */
-static int adpt_i2o_enable_hba(adpt_hba* pHba)
-{
-       u32 msg[4];
-       int ret;
-       
-       adpt_i2o_status_get(pHba);
-       if(!pHba->status_block){
-               return -ENOMEM;
-       }
-       /* Enable only allowed on READY state */
-       if(pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL)
-               return 0;
-
-       if(pHba->status_block->iop_state != ADAPTER_STATE_READY)
-               return -EINVAL;
-
-       msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
-       msg[1]=I2O_CMD_SYS_ENABLE<<24|HOST_TID<<12|ADAPTER_TID;
-       msg[2]= 0;
-       msg[3]= 0;
-
-       if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
-               printk(KERN_WARNING"%s: Could not enable (status=%#10x).\n", 
-                       pHba->name, ret);
-       } else {
-               PDEBUG("%s: Enabled.\n", pHba->name);
-       }
-
-       adpt_i2o_status_get(pHba);
-       return ret;
-}
-
-
-static int adpt_i2o_systab_send(adpt_hba* pHba)
-{
-       u32 msg[12];
-       int ret;
-
-       msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6;
-       msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID;
-       msg[2] = 0;
-       msg[3] = 0;
-       msg[4] = (0<<16) | ((pHba->unit+2) << 12); /* Host 0 IOP ID (unit + 2) */
-       msg[5] = 0;                                /* Segment 0 */
-
-       /* 
-        * Provide three SGL-elements:
-        * System table (SysTab), Private memory space declaration and 
-        * Private i/o space declaration  
-        */
-       msg[6] = 0x54000000 | sys_tbl_len;
-       msg[7] = (u32)sys_tbl_pa;
-       msg[8] = 0x54000000 | 0;
-       msg[9] = 0;
-       msg[10] = 0xD4000000 | 0;
-       msg[11] = 0;
-
-       if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 120))) {
-               printk(KERN_INFO "%s: Unable to set SysTab (status=%#10x).\n", 
-                       pHba->name, ret);
-       }
-#ifdef DEBUG
-       else {
-               PINFO("%s: SysTab set.\n", pHba->name);
-       }
-#endif
-
-       return ret;     
-}
-
-
-/*============================================================================
- *
- *============================================================================
- */
-
-
-#ifdef UARTDELAY 
-
-static static void adpt_delay(int millisec)
-{
-       int i;
-       for (i = 0; i < millisec; i++) {
-               udelay(1000);   /* delay for one millisecond */
-       }
-}
-
-#endif
-
-static struct scsi_host_template driver_template = {
-       .module                 = THIS_MODULE,
-       .name                   = "dpt_i2o",
-       .proc_name              = "dpt_i2o",
-       .show_info              = adpt_show_info,
-       .info                   = adpt_info,
-       .queuecommand           = adpt_queue,
-       .eh_abort_handler       = adpt_abort,
-       .eh_device_reset_handler = adpt_device_reset,
-       .eh_bus_reset_handler   = adpt_bus_reset,
-       .eh_host_reset_handler  = adpt_reset,
-       .bios_param             = adpt_bios_param,
-       .slave_configure        = adpt_slave_configure,
-       .can_queue              = MAX_TO_IOP_MESSAGES,
-       .this_id                = 7,
-};
-
-static int __init adpt_init(void)
-{
-       int             error;
-       adpt_hba        *pHba, *next;
-
-       printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
-
-       error = adpt_detect(&driver_template);
-       if (error < 0)
-               return error;
-       if (hba_chain == NULL)
-               return -ENODEV;
-
-       for (pHba = hba_chain; pHba; pHba = pHba->next) {
-               error = scsi_add_host(pHba->host, &pHba->pDev->dev);
-               if (error)
-                       goto fail;
-               scsi_scan_host(pHba->host);
-       }
-       return 0;
-fail:
-       for (pHba = hba_chain; pHba; pHba = next) {
-               next = pHba->next;
-               scsi_remove_host(pHba->host);
-       }
-       return error;
-}
-
-static void __exit adpt_exit(void)
-{
-       adpt_hba        *pHba, *next;
-
-       for (pHba = hba_chain; pHba; pHba = next) {
-               next = pHba->next;
-               adpt_release(pHba);
-       }
-}
-
-module_init(adpt_init);
-module_exit(adpt_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
deleted file mode 100644 (file)
index 8a079e8..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/***************************************************************************
-                          dpti.h  -  description
-                             -------------------
-    begin                : Thu Sep 7 2000
-    copyright            : (C) 2001 by Adaptec
-
-    See Documentation/scsi/dpti.rst for history, notes, license info
-    and credits
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *                                                                         *
- ***************************************************************************/
-
-#ifndef _DPT_H
-#define _DPT_H
-
-#define MAX_TO_IOP_MESSAGES   (255)
-#define MAX_FROM_IOP_MESSAGES (255)
-
-
-/*
- * SCSI interface function Prototypes
- */
-
-static int adpt_detect(struct scsi_host_template * sht);
-static int adpt_queue(struct Scsi_Host *h, struct scsi_cmnd * cmd);
-static int adpt_abort(struct scsi_cmnd * cmd);
-static int adpt_reset(struct scsi_cmnd* cmd);
-static int adpt_slave_configure(struct scsi_device *);
-
-static const char *adpt_info(struct Scsi_Host *pSHost);
-static int adpt_bios_param(struct scsi_device * sdev, struct block_device *dev,
-               sector_t, int geom[]);
-
-static int adpt_bus_reset(struct scsi_cmnd* cmd);
-static int adpt_device_reset(struct scsi_cmnd* cmd);
-
-
-/*
- * struct scsi_host_template (see scsi/scsi_host.h)
- */
-
-#define DPT_DRIVER_NAME        "Adaptec I2O RAID"
-
-#ifndef HOSTS_C
-
-#include "dpt/sys_info.h"
-#include <linux/wait.h>
-#include "dpt/dpti_i2o.h"
-#include "dpt/dpti_ioctl.h"
-
-#define DPT_I2O_VERSION "2.4 Build 5go"
-#define DPT_VERSION     2
-#define DPT_REVISION    '4'
-#define DPT_SUBREVISION '5'
-#define DPT_BETA       ""
-#define DPT_MONTH      8 
-#define DPT_DAY        7
-#define DPT_YEAR        (2001-1980)
-
-#define DPT_DRIVER     "dpt_i2o"
-#define DPTI_I2O_MAJOR (151)
-#define DPT_ORGANIZATION_ID (0x1B)        /* For Private Messages */
-#define DPTI_MAX_HBA   (16)
-#define MAX_CHANNEL     (5)    // Maximum Channel # Supported
-#define MAX_ID         (128)   // Maximum Target ID Supported
-
-/* Sizes in 4 byte words */
-#define REPLY_FRAME_SIZE  (17)
-#define MAX_MESSAGE_SIZE  (128)
-#define SG_LIST_ELEMENTS  (56)
-
-#define EMPTY_QUEUE           0xffffffff
-#define I2O_INTERRUPT_PENDING_B   (0x08)
-
-#define PCI_DPT_VENDOR_ID         (0x1044)     // DPT PCI Vendor ID
-#define PCI_DPT_DEVICE_ID         (0xA501)     // DPT PCI I2O Device ID
-#define PCI_DPT_RAPTOR_DEVICE_ID  (0xA511)     
-
-/* Debugging macro from Linux Device Drivers - Rubini */
-#undef PDEBUG
-#ifdef DEBUG
-//TODO add debug level switch
-#  define PDEBUG(fmt, args...)  printk(KERN_DEBUG "dpti: " fmt, ##args)
-#  define PDEBUGV(fmt, args...) printk(KERN_DEBUG "dpti: " fmt, ##args)
-#else
-# define PDEBUG(fmt, args...) /* not debugging: nothing */
-# define PDEBUGV(fmt, args...) /* not debugging: nothing */
-#endif
-
-#define PERROR(fmt, args...) printk(KERN_ERR fmt, ##args)
-#define PWARN(fmt, args...) printk(KERN_WARNING fmt, ##args)
-#define PINFO(fmt, args...) printk(KERN_INFO fmt, ##args)
-#define PCRIT(fmt, args...) printk(KERN_CRIT fmt, ##args)
-
-#define SHUTDOWN_SIGS  (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM))
-
-// Command timeouts
-#define FOREVER                        (0)
-#define TMOUT_INQUIRY          (20)
-#define TMOUT_FLUSH            (360/45)
-#define TMOUT_ABORT            (30)
-#define TMOUT_SCSI             (300)
-#define TMOUT_IOPRESET         (360)
-#define TMOUT_GETSTATUS                (15)
-#define TMOUT_INITOUTBOUND     (15)
-#define TMOUT_LCT              (360)
-
-
-#define I2O_SCSI_DEVICE_DSC_MASK                0x00FF
-
-#define I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION  0x000A
-
-#define I2O_SCSI_DSC_MASK                   0xFF00
-#define I2O_SCSI_DSC_SUCCESS                0x0000
-#define I2O_SCSI_DSC_REQUEST_ABORTED        0x0200
-#define I2O_SCSI_DSC_UNABLE_TO_ABORT        0x0300
-#define I2O_SCSI_DSC_COMPLETE_WITH_ERROR    0x0400
-#define I2O_SCSI_DSC_ADAPTER_BUSY           0x0500
-#define I2O_SCSI_DSC_REQUEST_INVALID        0x0600
-#define I2O_SCSI_DSC_PATH_INVALID           0x0700
-#define I2O_SCSI_DSC_DEVICE_NOT_PRESENT     0x0800
-#define I2O_SCSI_DSC_UNABLE_TO_TERMINATE    0x0900
-#define I2O_SCSI_DSC_SELECTION_TIMEOUT      0x0A00
-#define I2O_SCSI_DSC_COMMAND_TIMEOUT        0x0B00
-#define I2O_SCSI_DSC_MR_MESSAGE_RECEIVED    0x0D00
-#define I2O_SCSI_DSC_SCSI_BUS_RESET         0x0E00
-#define I2O_SCSI_DSC_PARITY_ERROR_FAILURE   0x0F00
-#define I2O_SCSI_DSC_AUTOSENSE_FAILED       0x1000
-#define I2O_SCSI_DSC_NO_ADAPTER             0x1100
-#define I2O_SCSI_DSC_DATA_OVERRUN           0x1200
-#define I2O_SCSI_DSC_UNEXPECTED_BUS_FREE    0x1300
-#define I2O_SCSI_DSC_SEQUENCE_FAILURE       0x1400
-#define I2O_SCSI_DSC_REQUEST_LENGTH_ERROR   0x1500
-#define I2O_SCSI_DSC_PROVIDE_FAILURE        0x1600
-#define I2O_SCSI_DSC_BDR_MESSAGE_SENT       0x1700
-#define I2O_SCSI_DSC_REQUEST_TERMINATED     0x1800
-#define I2O_SCSI_DSC_IDE_MESSAGE_SENT       0x3300
-#define I2O_SCSI_DSC_RESOURCE_UNAVAILABLE   0x3400
-#define I2O_SCSI_DSC_UNACKNOWLEDGED_EVENT   0x3500
-#define I2O_SCSI_DSC_MESSAGE_RECEIVED       0x3600
-#define I2O_SCSI_DSC_INVALID_CDB            0x3700
-#define I2O_SCSI_DSC_LUN_INVALID            0x3800
-#define I2O_SCSI_DSC_SCSI_TID_INVALID       0x3900
-#define I2O_SCSI_DSC_FUNCTION_UNAVAILABLE   0x3A00
-#define I2O_SCSI_DSC_NO_NEXUS               0x3B00
-#define I2O_SCSI_DSC_SCSI_IID_INVALID       0x3C00
-#define I2O_SCSI_DSC_CDB_RECEIVED           0x3D00
-#define I2O_SCSI_DSC_LUN_ALREADY_ENABLED    0x3E00
-#define I2O_SCSI_DSC_BUS_BUSY               0x3F00
-#define I2O_SCSI_DSC_QUEUE_FROZEN           0x4000
-
-
-#ifndef TRUE
-#define TRUE                  1
-#define FALSE                 0
-#endif
-
-#define HBA_FLAGS_INSTALLED_B       0x00000001 // Adapter Was Installed
-#define HBA_FLAGS_BLINKLED_B        0x00000002 // Adapter In Blink LED State
-#define HBA_FLAGS_IN_RESET     0x00000040      /* in reset */
-#define HBA_HOSTRESET_FAILED   0x00000080      /* adpt_resethost failed */
-
-
-// Device state flags
-#define DPTI_DEV_ONLINE    0x00
-#define DPTI_DEV_UNSCANNED 0x01
-#define DPTI_DEV_RESET    0x02
-#define DPTI_DEV_OFFLINE   0x04
-
-
-struct adpt_device {
-       struct adpt_device* next_lun;
-       u32     flags;
-       u32     type;
-       u32     capacity;
-       u32     block_size;
-       u8      scsi_channel;
-       u8      scsi_id;
-       u64     scsi_lun;
-       u8      state;
-       u16     tid;
-       struct i2o_device* pI2o_dev;
-       struct scsi_device *pScsi_dev;
-};
-
-struct adpt_channel {
-       struct adpt_device* device[MAX_ID];     /* used as an array of 128 scsi ids */
-       u8      scsi_id;
-       u8      type;
-       u16     tid;
-       u32     state;
-       struct i2o_device* pI2o_dev;
-};
-
-// HBA state flags
-#define DPTI_STATE_RESET       (0x01)
-
-typedef struct _adpt_hba {
-       struct _adpt_hba *next;
-       struct pci_dev *pDev;
-       struct Scsi_Host *host;
-       u32 state;
-       spinlock_t state_lock;
-       int unit;
-       int host_no;            /* SCSI host number */
-       u8 initialized;
-       u8 in_use;              /* is the management node open*/
-
-       char name[32];
-       char detail[55];
-
-       void __iomem *base_addr_virt;
-       void __iomem *msg_addr_virt;
-       ulong base_addr_phys;
-       void __iomem *post_port;
-       void __iomem *reply_port;
-       void __iomem *irq_mask;
-       u16  post_count;
-       u32  post_fifo_size;
-       u32  reply_fifo_size;
-       u32* reply_pool;
-       dma_addr_t reply_pool_pa;
-       u32  sg_tablesize;      // Scatter/Gather List Size.       
-       u8  top_scsi_channel;
-       u8  top_scsi_id;
-       u64  top_scsi_lun;
-       u8  dma64;
-
-       i2o_status_block* status_block;
-       dma_addr_t status_block_pa;
-       i2o_hrt* hrt;
-       dma_addr_t hrt_pa;
-       i2o_lct* lct;
-       dma_addr_t lct_pa;
-       uint lct_size;
-       struct i2o_device* devices;
-       struct adpt_channel channel[MAX_CHANNEL];
-       struct proc_dir_entry* proc_entry;      /* /proc dir */
-
-       void __iomem *FwDebugBuffer_P;  // Virtual Address Of FW Debug Buffer
-       u32   FwDebugBufferSize;        // FW Debug Buffer Size In Bytes
-       void __iomem *FwDebugStrLength_P;// Virtual Addr Of FW Debug String Len
-       void __iomem *FwDebugFlags_P;   // Virtual Address Of FW Debug Flags 
-       void __iomem *FwDebugBLEDflag_P;// Virtual Addr Of FW Debug BLED
-       void __iomem *FwDebugBLEDvalue_P;// Virtual Addr Of FW Debug BLED
-       u32 FwDebugFlags;
-       u32 *ioctl_reply_context[4];
-} adpt_hba;
-
-struct sg_simple_element {
-   u32  flag_count;
-   u32 addr_bus;
-}; 
-
-/*
- * Function Prototypes
- */
-
-static void adpt_i2o_sys_shutdown(void);
-static int adpt_init(void);
-static int adpt_i2o_build_sys_table(void);
-static irqreturn_t adpt_isr(int irq, void *dev_id);
-
-static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d);
-static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, 
-                       int group, int field, void *buf, int buflen);
-#ifdef DEBUG
-static const char *adpt_i2o_get_class_name(int class);
-#endif
-static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, 
-                 void *opblk, dma_addr_t opblk_pa, int oplen,
-                 void *resblk, dma_addr_t resblk_pa, int reslen);
-static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout);
-static int adpt_i2o_lct_get(adpt_hba* pHba);
-static int adpt_i2o_parse_lct(adpt_hba* pHba);
-static int adpt_i2o_activate_hba(adpt_hba* pHba);
-static int adpt_i2o_enable_hba(adpt_hba* pHba);
-static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d);
-static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len);
-static s32 adpt_i2o_quiesce_hba(adpt_hba* pHba);
-static s32 adpt_i2o_status_get(adpt_hba* pHba);
-static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba);
-static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
-static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice);
-static void adpt_i2o_scsi_complete(void __iomem *reply, struct scsi_cmnd *cmd);
-static s32 adpt_scsi_host_alloc(adpt_hba* pHba,struct scsi_host_template * sht);
-static s32 adpt_hba_reset(adpt_hba* pHba);
-static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
-static s32 adpt_rescan(adpt_hba* pHba);
-static s32 adpt_i2o_reparse_lct(adpt_hba* pHba);
-static s32 adpt_send_nop(adpt_hba*pHba,u32 m);
-static void adpt_i2o_delete_hba(adpt_hba* pHba);
-static void adpt_inquiry(adpt_hba* pHba);
-static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u64 lun);
-static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) ;
-static int adpt_i2o_online_hba(adpt_hba* pHba);
-static void adpt_i2o_post_wait_complete(u32, int);
-static int adpt_i2o_systab_send(adpt_hba* pHba);
-
-static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg);
-static int adpt_open(struct inode *inode, struct file *file);
-static int adpt_close(struct inode *inode, struct file *file);
-
-
-#ifdef UARTDELAY
-static void adpt_delay(int millisec);
-#endif
-
-#define PRINT_BUFFER_SIZE     512
-
-#define HBA_FLAGS_DBG_FLAGS_MASK         0xffff0000    // Mask for debug flags
-#define HBA_FLAGS_DBG_KERNEL_PRINT_B     0x00010000    // Kernel Debugger Print
-#define HBA_FLAGS_DBG_FW_PRINT_B         0x00020000    // Firmware Debugger Print
-#define HBA_FLAGS_DBG_FUNCTION_ENTRY_B   0x00040000    // Function Entry Point
-#define HBA_FLAGS_DBG_FUNCTION_EXIT_B    0x00080000    // Function Exit
-#define HBA_FLAGS_DBG_ERROR_B            0x00100000    // Error Conditions
-#define HBA_FLAGS_DBG_INIT_B             0x00200000    // Init Prints
-#define HBA_FLAGS_DBG_OS_COMMANDS_B      0x00400000    // OS Command Info
-#define HBA_FLAGS_DBG_SCAN_B             0x00800000    // Device Scan
-
-#define FW_DEBUG_STR_LENGTH_OFFSET 0
-#define FW_DEBUG_FLAGS_OFFSET      4
-#define FW_DEBUG_BLED_OFFSET       8
-
-#define FW_DEBUG_FLAGS_NO_HEADERS_B    0x01
-#endif                         /* !HOSTS_C */
-#endif                         /* _DPT_H */
index c2a5910..6ec2963 100644 (file)
@@ -1488,7 +1488,6 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
 
        fh = fc_frame_header_get(fp);
        skb = fp_skb(fp);
-       wlen = skb->len / FCOE_WORD_TO_BYTE;
 
        if (!lport->link_up) {
                kfree_skb(skb);
index 2f6c56a..e8b7a09 100644 (file)
 struct gvp11_hostdata {
        struct WD33C93_hostdata wh;
        struct gvp11_scsiregs *regs;
+       struct device *dev;
 };
 
+#define DMA_DIR(d)   ((d == DATA_OUT_DIR) ? DMA_TO_DEVICE : DMA_FROM_DEVICE)
+#define TO_DMA_MASK(m) ((~(m & 0xfffffff0))-1)
+
 static irqreturn_t gvp11_intr(int irq, void *data)
 {
        struct Scsi_Host *instance = data;
@@ -54,17 +58,33 @@ void gvp11_setup(char *str, int *ints)
 static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
 {
        struct scsi_pointer *scsi_pointer = WD33C93_scsi_pointer(cmd);
+       unsigned long len = scsi_pointer->this_residual;
        struct Scsi_Host *instance = cmd->device->host;
        struct gvp11_hostdata *hdata = shost_priv(instance);
        struct WD33C93_hostdata *wh = &hdata->wh;
        struct gvp11_scsiregs *regs = hdata->regs;
        unsigned short cntr = GVP11_DMAC_INT_ENABLE;
-       unsigned long addr = virt_to_bus(scsi_pointer->ptr);
+       dma_addr_t addr;
        int bank_mask;
        static int scsi_alloc_out_of_range = 0;
 
+       addr = dma_map_single(hdata->dev, scsi_pointer->ptr,
+                             len, DMA_DIR(dir_in));
+       if (dma_mapping_error(hdata->dev, addr)) {
+               dev_warn(hdata->dev, "cannot map SCSI data block %p\n",
+                        scsi_pointer->ptr);
+               return 1;
+       }
+       scsi_pointer->dma_handle = addr;
+
        /* use bounce buffer if the physical address is bad */
        if (addr & wh->dma_xfer_mask) {
+               /* drop useless mapping */
+               dma_unmap_single(hdata->dev, scsi_pointer->dma_handle,
+                                scsi_pointer->this_residual,
+                                DMA_DIR(dir_in));
+               scsi_pointer->dma_handle = (dma_addr_t) NULL;
+
                wh->dma_bounce_len = (scsi_pointer->this_residual + 511) & ~0x1ff;
 
                if (!scsi_alloc_out_of_range) {
@@ -87,10 +107,32 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
                        wh->dma_buffer_pool = BUF_CHIP_ALLOCED;
                }
 
-               /* check if the address of the bounce buffer is OK */
-               addr = virt_to_bus(wh->dma_bounce_buffer);
+               if (!dir_in) {
+                       /* copy to bounce buffer for a write */
+                       memcpy(wh->dma_bounce_buffer, scsi_pointer->ptr,
+                              scsi_pointer->this_residual);
+               }
+
+               if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED) {
+               /* will flush/invalidate cache for us */
+                       addr = dma_map_single(hdata->dev,
+                                             wh->dma_bounce_buffer,
+                                             wh->dma_bounce_len,
+                                             DMA_DIR(dir_in));
+                       /* can't map buffer; use PIO */
+                       if (dma_mapping_error(hdata->dev, addr)) {
+                               dev_warn(hdata->dev,
+                                        "cannot map bounce buffer %p\n",
+                                        wh->dma_bounce_buffer);
+                               return 1;
+                       }
+               }
 
                if (addr & wh->dma_xfer_mask) {
+                       /* drop useless mapping */
+                       dma_unmap_single(hdata->dev, scsi_pointer->dma_handle,
+                                        scsi_pointer->this_residual,
+                                        DMA_DIR(dir_in));
                        /* fall back to Chip RAM if address out of range */
                        if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED) {
                                kfree(wh->dma_bounce_buffer);
@@ -108,15 +150,19 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
                                return 1;
                        }
 
-                       addr = virt_to_bus(wh->dma_bounce_buffer);
+                       if (!dir_in) {
+                               /* copy to bounce buffer for a write */
+                               memcpy(wh->dma_bounce_buffer, scsi_pointer->ptr,
+                                      scsi_pointer->this_residual);
+                       }
+                       /* chip RAM can be mapped to phys. address directly */
+                       addr = virt_to_phys(wh->dma_bounce_buffer);
+                       /* no need to flush/invalidate cache */
                        wh->dma_buffer_pool = BUF_CHIP_ALLOCED;
                }
+               /* finally, have OK mapping (punted for PIO else) */
+               scsi_pointer->dma_handle = addr;
 
-               if (!dir_in) {
-                       /* copy to bounce buffer for a write */
-                       memcpy(wh->dma_bounce_buffer, scsi_pointer->ptr,
-                              scsi_pointer->this_residual);
-               }
        }
 
        /* setup dma direction */
@@ -129,13 +175,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
        /* setup DMA *physical* address */
        regs->ACR = addr;
 
-       if (dir_in) {
-               /* invalidate any cache */
-               cache_clear(addr, scsi_pointer->this_residual);
-       } else {
-               /* push any dirty cache */
-               cache_push(addr, scsi_pointer->this_residual);
-       }
+       /* no more cache flush here - dma_map_single() takes care */
 
        bank_mask = (~wh->dma_xfer_mask >> 18) & 0x01c0;
        if (bank_mask)
@@ -161,6 +201,11 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
        /* remove write bit from CONTROL bits */
        regs->CNTR = GVP11_DMAC_INT_ENABLE;
 
+       if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED)
+               dma_unmap_single(hdata->dev, scsi_pointer->dma_handle,
+                                scsi_pointer->this_residual,
+                                DMA_DIR(wh->dma_dir));
+
        /* copy from a bounce buffer, if necessary */
        if (status && wh->dma_bounce_buffer) {
                if (wh->dma_dir && SCpnt)
@@ -287,6 +332,13 @@ static int gvp11_probe(struct zorro_dev *z, const struct zorro_device_id *ent)
 
        default_dma_xfer_mask = ent->driver_data;
 
+       if (dma_set_mask_and_coherent(&z->dev,
+               TO_DMA_MASK(default_dma_xfer_mask))) {
+               dev_warn(&z->dev, "cannot use DMA mask %x\n",
+                        TO_DMA_MASK(default_dma_xfer_mask));
+               return -ENODEV;
+       }
+
        /*
         * Rumors state that some GVP ram boards use the same product
         * code as the SCSI controllers. Therefore if the board-size
@@ -327,9 +379,16 @@ static int gvp11_probe(struct zorro_dev *z, const struct zorro_device_id *ent)
        wdregs.SCMD = &regs->SCMD;
 
        hdata = shost_priv(instance);
-       if (gvp11_xfer_mask)
+       if (gvp11_xfer_mask) {
                hdata->wh.dma_xfer_mask = gvp11_xfer_mask;
-       else
+               if (dma_set_mask_and_coherent(&z->dev,
+                       TO_DMA_MASK(gvp11_xfer_mask))) {
+                       dev_warn(&z->dev, "cannot use DMA mask %x\n",
+                                TO_DMA_MASK(gvp11_xfer_mask));
+                       error = -ENODEV;
+                       goto fail_check_or_alloc;
+               }
+       } else
                hdata->wh.dma_xfer_mask = default_dma_xfer_mask;
 
        hdata->wh.no_sync = 0xff;
index 455d492..18297ab 100644 (file)
@@ -805,8 +805,8 @@ slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba,
                        return -SAS_QUEUE_FULL;
                }
                /*
-                 * SAS IPTT bit0 should be 1, and SATA IPTT bit0 should be 0.
-                 */
+                * SAS IPTT bit0 should be 1, and SATA IPTT bit0 should be 0.
+                */
                if (sata_dev ^ (start & 1))
                        break;
                start++;
index 8352f90..ef6c0e3 100644 (file)
@@ -350,7 +350,7 @@ static void scsi_host_dev_release(struct device *dev)
 
        kfree(shost->shost_data);
 
-       ida_simple_remove(&host_index_ida, shost->host_no);
+       ida_free(&host_index_ida, shost->host_no);
 
        if (shost->shost_state != SHOST_CREATED)
                put_device(parent);
@@ -395,7 +395,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
        init_waitqueue_head(&shost->host_wait);
        mutex_init(&shost->scan_mutex);
 
-       index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL);
+       index = ida_alloc(&host_index_ida, GFP_KERNEL);
        if (index < 0) {
                kfree(shost);
                return NULL;
index 9fee70d..29b1bd7 100644 (file)
@@ -52,6 +52,10 @@ static struct iscsi_transport iscsi_sw_tcp_transport;
 static unsigned int iscsi_max_lun = ~0;
 module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
 
+static bool iscsi_recv_from_iscsi_q;
+module_param_named(recv_from_iscsi_q, iscsi_recv_from_iscsi_q, bool, 0644);
+MODULE_PARM_DESC(recv_from_iscsi_q, "Set to true to read iSCSI data/headers from the iscsi_q workqueue. The default is false which will perform reads from the network softirq context.");
+
 static int iscsi_sw_tcp_dbg;
 module_param_named(debug_iscsi_tcp, iscsi_sw_tcp_dbg, int,
                   S_IRUGO | S_IWUSR);
@@ -122,20 +126,13 @@ static inline int iscsi_sw_sk_state_check(struct sock *sk)
        return 0;
 }
 
-static void iscsi_sw_tcp_data_ready(struct sock *sk)
+static void iscsi_sw_tcp_recv_data(struct iscsi_conn *conn)
 {
-       struct iscsi_conn *conn;
-       struct iscsi_tcp_conn *tcp_conn;
+       struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+       struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
+       struct sock *sk = tcp_sw_conn->sock->sk;
        read_descriptor_t rd_desc;
 
-       read_lock_bh(&sk->sk_callback_lock);
-       conn = sk->sk_user_data;
-       if (!conn) {
-               read_unlock_bh(&sk->sk_callback_lock);
-               return;
-       }
-       tcp_conn = conn->dd_data;
-
        /*
         * Use rd_desc to pass 'conn' to iscsi_tcp_recv.
         * We set count to 1 because we want the network layer to
@@ -144,13 +141,48 @@ static void iscsi_sw_tcp_data_ready(struct sock *sk)
         */
        rd_desc.arg.data = conn;
        rd_desc.count = 1;
-       tcp_read_sock(sk, &rd_desc, iscsi_sw_tcp_recv);
 
-       iscsi_sw_sk_state_check(sk);
+       tcp_read_sock(sk, &rd_desc, iscsi_sw_tcp_recv);
 
        /* If we had to (atomically) map a highmem page,
         * unmap it now. */
        iscsi_tcp_segment_unmap(&tcp_conn->in.segment);
+
+       iscsi_sw_sk_state_check(sk);
+}
+
+static void iscsi_sw_tcp_recv_data_work(struct work_struct *work)
+{
+       struct iscsi_conn *conn = container_of(work, struct iscsi_conn,
+                                              recvwork);
+       struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+       struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
+       struct sock *sk = tcp_sw_conn->sock->sk;
+
+       lock_sock(sk);
+       iscsi_sw_tcp_recv_data(conn);
+       release_sock(sk);
+}
+
+static void iscsi_sw_tcp_data_ready(struct sock *sk)
+{
+       struct iscsi_sw_tcp_conn *tcp_sw_conn;
+       struct iscsi_tcp_conn *tcp_conn;
+       struct iscsi_conn *conn;
+
+       read_lock_bh(&sk->sk_callback_lock);
+       conn = sk->sk_user_data;
+       if (!conn) {
+               read_unlock_bh(&sk->sk_callback_lock);
+               return;
+       }
+       tcp_conn = conn->dd_data;
+       tcp_sw_conn = tcp_conn->dd_data;
+
+       if (tcp_sw_conn->queue_recv)
+               iscsi_conn_queue_recv(conn);
+       else
+               iscsi_sw_tcp_recv_data(conn);
        read_unlock_bh(&sk->sk_callback_lock);
 }
 
@@ -205,7 +237,7 @@ static void iscsi_sw_tcp_write_space(struct sock *sk)
        old_write_space(sk);
 
        ISCSI_SW_TCP_DBG(conn, "iscsi_write_space\n");
-       iscsi_conn_queue_work(conn);
+       iscsi_conn_queue_xmit(conn);
 }
 
 static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn)
@@ -274,7 +306,10 @@ static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn,
                copy = segment->size - offset;
 
                if (segment->total_copied + segment->size < segment->total_size)
-                       flags |= MSG_MORE;
+                       flags |= MSG_MORE | MSG_SENDPAGE_NOTLAST;
+
+               if (tcp_sw_conn->queue_recv)
+                       flags |= MSG_DONTWAIT;
 
                /* Use sendpage if we can; else fall back to sendmsg */
                if (!segment->data) {
@@ -557,6 +592,8 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session,
        conn = cls_conn->dd_data;
        tcp_conn = conn->dd_data;
        tcp_sw_conn = tcp_conn->dd_data;
+       INIT_WORK(&conn->recvwork, iscsi_sw_tcp_recv_data_work);
+       tcp_sw_conn->queue_recv = iscsi_recv_from_iscsi_q;
 
        tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC);
        if (IS_ERR(tfm))
@@ -610,6 +647,8 @@ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)
        iscsi_sw_tcp_conn_restore_callbacks(conn);
        sock_put(sock->sk);
 
+       iscsi_suspend_rx(conn);
+
        spin_lock_bh(&session->frwd_lock);
        tcp_sw_conn->sock = NULL;
        spin_unlock_bh(&session->frwd_lock);
@@ -898,7 +937,7 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
 remove_session:
        iscsi_session_teardown(cls_session);
 remove_host:
-       iscsi_host_remove(shost);
+       iscsi_host_remove(shost, false);
 free_host:
        iscsi_host_free(shost);
        return NULL;
@@ -915,7 +954,7 @@ static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
        iscsi_tcp_r2tpool_free(cls_session->dd_data);
        iscsi_session_teardown(cls_session);
 
-       iscsi_host_remove(shost);
+       iscsi_host_remove(shost, false);
        iscsi_host_free(shost);
 }
 
@@ -1003,7 +1042,6 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
        .eh_target_reset_handler = iscsi_eh_recover_target,
        .dma_boundary           = PAGE_SIZE - 1,
        .slave_configure        = iscsi_sw_tcp_slave_configure,
-       .target_alloc           = iscsi_target_alloc,
        .proc_name              = "iscsi_tcp",
        .this_id                = -1,
        .track_queue_depth      = 1,
index 7914531..850a018 100644 (file)
@@ -28,6 +28,8 @@ struct iscsi_sw_tcp_send {
 
 struct iscsi_sw_tcp_conn {
        struct socket           *sock;
+       struct work_struct      recvwork;
+       bool                    queue_recv;
 
        struct iscsi_sw_tcp_send out;
        /* old values for socket callbacks */
index 797abf4..d95f4bc 100644 (file)
@@ -83,7 +83,9 @@ MODULE_PARM_DESC(debug_libiscsi_eh,
                                "%s " dbg_fmt, __func__, ##arg);        \
        } while (0);
 
-inline void iscsi_conn_queue_work(struct iscsi_conn *conn)
+#define ISCSI_CMD_COMPL_WAIT 5
+
+inline void iscsi_conn_queue_xmit(struct iscsi_conn *conn)
 {
        struct Scsi_Host *shost = conn->session->host;
        struct iscsi_host *ihost = shost_priv(shost);
@@ -91,7 +93,17 @@ inline void iscsi_conn_queue_work(struct iscsi_conn *conn)
        if (ihost->workq)
                queue_work(ihost->workq, &conn->xmitwork);
 }
-EXPORT_SYMBOL_GPL(iscsi_conn_queue_work);
+EXPORT_SYMBOL_GPL(iscsi_conn_queue_xmit);
+
+inline void iscsi_conn_queue_recv(struct iscsi_conn *conn)
+{
+       struct Scsi_Host *shost = conn->session->host;
+       struct iscsi_host *ihost = shost_priv(shost);
+
+       if (ihost->workq && !test_bit(ISCSI_CONN_FLAG_SUSPEND_RX, &conn->flags))
+               queue_work(ihost->workq, &conn->recvwork);
+}
+EXPORT_SYMBOL_GPL(iscsi_conn_queue_recv);
 
 static void __iscsi_update_cmdsn(struct iscsi_session *session,
                                 uint32_t exp_cmdsn, uint32_t max_cmdsn)
@@ -472,12 +484,18 @@ static void iscsi_free_task(struct iscsi_task *task)
        }
 }
 
-void __iscsi_get_task(struct iscsi_task *task)
+bool iscsi_get_task(struct iscsi_task *task)
 {
-       refcount_inc(&task->refcount);
+       return refcount_inc_not_zero(&task->refcount);
 }
-EXPORT_SYMBOL_GPL(__iscsi_get_task);
+EXPORT_SYMBOL_GPL(iscsi_get_task);
 
+/**
+ * __iscsi_put_task - drop the refcount on a task
+ * @task: iscsi_task to drop the refcount on
+ *
+ * The back_lock must be held when calling in case it frees the task.
+ */
 void __iscsi_put_task(struct iscsi_task *task)
 {
        if (refcount_dec_and_test(&task->refcount))
@@ -489,10 +507,11 @@ void iscsi_put_task(struct iscsi_task *task)
 {
        struct iscsi_session *session = task->conn->session;
 
-       /* regular RX path uses back_lock */
-       spin_lock_bh(&session->back_lock);
-       __iscsi_put_task(task);
-       spin_unlock_bh(&session->back_lock);
+       if (refcount_dec_and_test(&task->refcount)) {
+               spin_lock_bh(&session->back_lock);
+               iscsi_free_task(task);
+               spin_unlock_bh(&session->back_lock);
+       }
 }
 EXPORT_SYMBOL_GPL(iscsi_put_task);
 
@@ -557,16 +576,19 @@ static bool cleanup_queued_task(struct iscsi_task *task)
        struct iscsi_conn *conn = task->conn;
        bool early_complete = false;
 
-       /* Bad target might have completed task while it was still running */
+       /*
+        * We might have raced where we handled a R2T early and got a response
+        * but have not yet taken the task off the requeue list, then a TMF or
+        * recovery happened and so we can still see it here.
+        */
        if (task->state == ISCSI_TASK_COMPLETED)
                early_complete = true;
 
        if (!list_empty(&task->running)) {
                list_del_init(&task->running);
                /*
-                * If it's on a list but still running, this could be from
-                * a bad target sending a rsp early, cleanup from a TMF, or
-                * session recovery.
+                * If it's on a list but still running this could be cleanup
+                * from a TMF or session recovery.
                 */
                if (task->state == ISCSI_TASK_RUNNING ||
                    task->state == ISCSI_TASK_COMPLETED)
@@ -587,20 +609,17 @@ static bool cleanup_queued_task(struct iscsi_task *task)
 }
 
 /*
- * session frwd lock must be held and if not called for a task that is still
- * pending or from the xmit thread, then xmit thread must be suspended
+ * session back and frwd lock must be held and if not called for a task that
+ * is still pending or from the xmit thread, then xmit thread must be suspended
  */
-static void fail_scsi_task(struct iscsi_task *task, int err)
+static void __fail_scsi_task(struct iscsi_task *task, int err)
 {
        struct iscsi_conn *conn = task->conn;
        struct scsi_cmnd *sc;
        int state;
 
-       spin_lock_bh(&conn->session->back_lock);
-       if (cleanup_queued_task(task)) {
-               spin_unlock_bh(&conn->session->back_lock);
+       if (cleanup_queued_task(task))
                return;
-       }
 
        if (task->state == ISCSI_TASK_PENDING) {
                /*
@@ -619,7 +638,15 @@ static void fail_scsi_task(struct iscsi_task *task, int err)
        sc->result = err << 16;
        scsi_set_resid(sc, scsi_bufflen(sc));
        iscsi_complete_task(task, state);
-       spin_unlock_bh(&conn->session->back_lock);
+}
+
+static void fail_scsi_task(struct iscsi_task *task, int err)
+{
+       struct iscsi_session *session = task->conn->session;
+
+       spin_lock_bh(&session->back_lock);
+       __fail_scsi_task(task, err);
+       spin_unlock_bh(&session->back_lock);
 }
 
 static int iscsi_prep_mgmt_task(struct iscsi_conn *conn,
@@ -668,12 +695,18 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn,
        return 0;
 }
 
+/**
+ * iscsi_alloc_mgmt_task - allocate and setup a mgmt task.
+ * @conn: iscsi conn that the task will be sent on.
+ * @hdr: iscsi pdu that will be sent.
+ * @data: buffer for data segment if needed.
+ * @data_size: length of data in bytes.
+ */
 static struct iscsi_task *
-__iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+iscsi_alloc_mgmt_task(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                      char *data, uint32_t data_size)
 {
        struct iscsi_session *session = conn->session;
-       struct iscsi_host *ihost = shost_priv(session->host);
        uint8_t opcode = hdr->opcode & ISCSI_OPCODE_MASK;
        struct iscsi_task *task;
        itt_t itt;
@@ -754,28 +787,57 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                                                   task->conn->session->age);
        }
 
-       if (unlikely(READ_ONCE(conn->ping_task) == INVALID_SCSI_TASK))
-               WRITE_ONCE(conn->ping_task, task);
+       return task;
+
+free_task:
+       iscsi_put_task(task);
+       return NULL;
+}
+
+/**
+ * iscsi_send_mgmt_task - Send task created with iscsi_alloc_mgmt_task.
+ * @task: iscsi task to send.
+ *
+ * On failure this returns a non-zero error code, and the driver must free
+ * the task with iscsi_put_task;
+ */
+static int iscsi_send_mgmt_task(struct iscsi_task *task)
+{
+       struct iscsi_conn *conn = task->conn;
+       struct iscsi_session *session = conn->session;
+       struct iscsi_host *ihost = shost_priv(conn->session->host);
+       int rc = 0;
 
        if (!ihost->workq) {
-               if (iscsi_prep_mgmt_task(conn, task))
-                       goto free_task;
+               rc = iscsi_prep_mgmt_task(conn, task);
+               if (rc)
+                       return rc;
 
-               if (session->tt->xmit_task(task))
-                       goto free_task;
+               rc = session->tt->xmit_task(task);
+               if (rc)
+                       return rc;
        } else {
                list_add_tail(&task->running, &conn->mgmtqueue);
-               iscsi_conn_queue_work(conn);
+               iscsi_conn_queue_xmit(conn);
        }
 
-       return task;
+       return 0;
+}
 
-free_task:
-       /* regular RX path uses back_lock */
-       spin_lock(&session->back_lock);
-       __iscsi_put_task(task);
-       spin_unlock(&session->back_lock);
-       return NULL;
+static int __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+                                char *data, uint32_t data_size)
+{
+       struct iscsi_task *task;
+       int rc;
+
+       task = iscsi_alloc_mgmt_task(conn, hdr, data, data_size);
+       if (!task)
+               return -ENOMEM;
+
+       rc = iscsi_send_mgmt_task(task);
+       if (rc)
+               iscsi_put_task(task);
+       return rc;
 }
 
 int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr,
@@ -786,7 +848,7 @@ int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr,
        int err = 0;
 
        spin_lock_bh(&session->frwd_lock);
-       if (!__iscsi_conn_send_pdu(conn, hdr, data, data_size))
+       if (__iscsi_conn_send_pdu(conn, hdr, data, data_size))
                err = -EPERM;
        spin_unlock_bh(&session->frwd_lock);
        return err;
@@ -959,7 +1021,6 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
        if (!rhdr) {
                if (READ_ONCE(conn->ping_task))
                        return -EINVAL;
-               WRITE_ONCE(conn->ping_task, INVALID_SCSI_TASK);
        }
 
        memset(&hdr, 0, sizeof(struct iscsi_nopout));
@@ -973,10 +1034,18 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
        } else
                hdr.ttt = RESERVED_ITT;
 
-       task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
-       if (!task) {
+       task = iscsi_alloc_mgmt_task(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
+       if (!task)
+               return -ENOMEM;
+
+       if (!rhdr)
+               WRITE_ONCE(conn->ping_task, task);
+
+       if (iscsi_send_mgmt_task(task)) {
                if (!rhdr)
                        WRITE_ONCE(conn->ping_task, NULL);
+               iscsi_put_task(task);
+
                iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
                return -EIO;
        } else if (!rhdr) {
@@ -1434,11 +1503,17 @@ static int iscsi_xmit_task(struct iscsi_conn *conn, struct iscsi_task *task,
 {
        int rc;
 
-       spin_lock_bh(&conn->session->back_lock);
-
        if (!conn->task) {
-               /* Take a ref so we can access it after xmit_task() */
-               __iscsi_get_task(task);
+               /*
+                * Take a ref so we can access it after xmit_task().
+                *
+                * This should never fail because the failure paths will have
+                * stopped the xmit thread.
+                */
+               if (!iscsi_get_task(task)) {
+                       WARN_ON_ONCE(1);
+                       return 0;
+               }
        } else {
                /* Already have a ref from when we failed to send it last call */
                conn->task = NULL;
@@ -1449,7 +1524,7 @@ static int iscsi_xmit_task(struct iscsi_conn *conn, struct iscsi_task *task,
         * case a bad target sends a cmd rsp before we have handled the task.
         */
        if (was_requeue)
-               __iscsi_put_task(task);
+               iscsi_put_task(task);
 
        /*
         * Do this after dropping the extra ref because if this was a requeue
@@ -1461,10 +1536,8 @@ static int iscsi_xmit_task(struct iscsi_conn *conn, struct iscsi_task *task,
                 * task and get woken up again.
                 */
                conn->task = task;
-               spin_unlock_bh(&conn->session->back_lock);
                return -ENODATA;
        }
-       spin_unlock_bh(&conn->session->back_lock);
 
        spin_unlock_bh(&conn->session->frwd_lock);
        rc = conn->session->tt->xmit_task(task);
@@ -1472,20 +1545,16 @@ static int iscsi_xmit_task(struct iscsi_conn *conn, struct iscsi_task *task,
        if (!rc) {
                /* done with this task */
                task->last_xfer = jiffies;
-       }
-       /* regular RX path uses back_lock */
-       spin_lock(&conn->session->back_lock);
-       if (rc && task->state == ISCSI_TASK_RUNNING) {
+       } else {
                /*
                 * get an extra ref that is released next time we access it
                 * as conn->task above.
                 */
-               __iscsi_get_task(task);
+               iscsi_get_task(task);
                conn->task = task;
        }
 
-       __iscsi_put_task(task);
-       spin_unlock(&conn->session->back_lock);
+       iscsi_put_task(task);
        return rc;
 }
 
@@ -1513,7 +1582,7 @@ void iscsi_requeue_task(struct iscsi_task *task)
                 */
                iscsi_put_task(task);
        }
-       iscsi_conn_queue_work(conn);
+       iscsi_conn_queue_xmit(conn);
        spin_unlock_bh(&conn->session->frwd_lock);
 }
 EXPORT_SYMBOL_GPL(iscsi_requeue_task);
@@ -1567,6 +1636,28 @@ check_mgmt:
                        goto done;
        }
 
+check_requeue:
+       while (!list_empty(&conn->requeue)) {
+               /*
+                * we always do fastlogout - conn stop code will clean up.
+                */
+               if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
+                       break;
+
+               task = list_entry(conn->requeue.next, struct iscsi_task,
+                                 running);
+
+               if (iscsi_check_tmf_restrictions(task, ISCSI_OP_SCSI_DATA_OUT))
+                       break;
+
+               list_del_init(&task->running);
+               rc = iscsi_xmit_task(conn, task, true);
+               if (rc)
+                       goto done;
+               if (!list_empty(&conn->mgmtqueue))
+                       goto check_mgmt;
+       }
+
        /* process pending command queue */
        while (!list_empty(&conn->cmdqueue)) {
                task = list_entry(conn->cmdqueue.next, struct iscsi_task,
@@ -1594,28 +1685,10 @@ check_mgmt:
                 */
                if (!list_empty(&conn->mgmtqueue))
                        goto check_mgmt;
+               if (!list_empty(&conn->requeue))
+                       goto check_requeue;
        }
 
-       while (!list_empty(&conn->requeue)) {
-               /*
-                * we always do fastlogout - conn stop code will clean up.
-                */
-               if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
-                       break;
-
-               task = list_entry(conn->requeue.next, struct iscsi_task,
-                                 running);
-
-               if (iscsi_check_tmf_restrictions(task, ISCSI_OP_SCSI_DATA_OUT))
-                       break;
-
-               list_del_init(&task->running);
-               rc = iscsi_xmit_task(conn, task, true);
-               if (rc)
-                       goto done;
-               if (!list_empty(&conn->mgmtqueue))
-                       goto check_mgmt;
-       }
        spin_unlock_bh(&conn->session->frwd_lock);
        return -ENODATA;
 
@@ -1782,7 +1855,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc)
                }
        } else {
                list_add_tail(&task->running, &conn->cmdqueue);
-               iscsi_conn_queue_work(conn);
+               iscsi_conn_queue_xmit(conn);
        }
 
        session->queued_cmdsn++;
@@ -1843,11 +1916,8 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
        __must_hold(&session->frwd_lock)
 {
        struct iscsi_session *session = conn->session;
-       struct iscsi_task *task;
 
-       task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr,
-                                     NULL, 0);
-       if (!task) {
+       if (__iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0)) {
                spin_unlock_bh(&session->frwd_lock);
                iscsi_conn_printk(KERN_ERR, conn, "Could not send TMF.\n");
                iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
@@ -1895,6 +1965,7 @@ static void fail_scsi_tasks(struct iscsi_conn *conn, u64 lun, int error)
        struct iscsi_task *task;
        int i;
 
+restart_cmd_loop:
        spin_lock_bh(&session->back_lock);
        for (i = 0; i < session->cmds_max; i++) {
                task = session->cmds[i];
@@ -1903,22 +1974,25 @@ static void fail_scsi_tasks(struct iscsi_conn *conn, u64 lun, int error)
 
                if (lun != -1 && lun != task->sc->device->lun)
                        continue;
-
-               __iscsi_get_task(task);
-               spin_unlock_bh(&session->back_lock);
+               /*
+                * The cmd is completing but if this is called from an eh
+                * callout path then when we return scsi-ml owns the cmd. Wait
+                * for the completion path to finish freeing the cmd.
+                */
+               if (!iscsi_get_task(task)) {
+                       spin_unlock_bh(&session->back_lock);
+                       spin_unlock_bh(&session->frwd_lock);
+                       udelay(ISCSI_CMD_COMPL_WAIT);
+                       spin_lock_bh(&session->frwd_lock);
+                       goto restart_cmd_loop;
+               }
 
                ISCSI_DBG_SESSION(session,
                                  "failing sc %p itt 0x%x state %d\n",
                                  task->sc, task->itt, task->state);
-               fail_scsi_task(task, error);
-
-               spin_unlock_bh(&session->frwd_lock);
-               iscsi_put_task(task);
-               spin_lock_bh(&session->frwd_lock);
-
-               spin_lock_bh(&session->back_lock);
+               __fail_scsi_task(task, error);
+               __iscsi_put_task(task);
        }
-
        spin_unlock_bh(&session->back_lock);
 }
 
@@ -1943,7 +2017,7 @@ EXPORT_SYMBOL_GPL(iscsi_suspend_queue);
 
 /**
  * iscsi_suspend_tx - suspend iscsi_data_xmit
- * @conn: iscsi conn tp stop processing IO on.
+ * @conn: iscsi conn to stop processing IO on.
  *
  * This function sets the suspend bit to prevent iscsi_data_xmit
  * from sending new IO, and if work is queued on the xmit thread
@@ -1956,15 +2030,30 @@ void iscsi_suspend_tx(struct iscsi_conn *conn)
 
        set_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags);
        if (ihost->workq)
-               flush_workqueue(ihost->workq);
+               flush_work(&conn->xmitwork);
 }
 EXPORT_SYMBOL_GPL(iscsi_suspend_tx);
 
 static void iscsi_start_tx(struct iscsi_conn *conn)
 {
        clear_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags);
-       iscsi_conn_queue_work(conn);
+       iscsi_conn_queue_xmit(conn);
+}
+
+/**
+ * iscsi_suspend_rx - Prevent recvwork from running again.
+ * @conn: iscsi conn to stop.
+ */
+void iscsi_suspend_rx(struct iscsi_conn *conn)
+{
+       struct Scsi_Host *shost = conn->session->host;
+       struct iscsi_host *ihost = shost_priv(shost);
+
+       set_bit(ISCSI_CONN_FLAG_SUSPEND_RX, &conn->flags);
+       if (ihost->workq)
+               flush_work(&conn->recvwork);
 }
+EXPORT_SYMBOL_GPL(iscsi_suspend_rx);
 
 /*
  * We want to make sure a ping is in flight. It has timed out.
@@ -2008,7 +2097,16 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
                spin_unlock(&session->back_lock);
                goto done;
        }
-       __iscsi_get_task(task);
+       if (!iscsi_get_task(task)) {
+               /*
+                * Racing with the completion path right now, so give it more
+                * time so that path can complete it like normal.
+                */
+               rc = BLK_EH_RESET_TIMER;
+               task = NULL;
+               spin_unlock(&session->back_lock);
+               goto done;
+       }
        spin_unlock(&session->back_lock);
 
        if (session->state != ISCSI_STATE_LOGGED_IN) {
@@ -2257,6 +2355,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
 
        ISCSI_DBG_EH(session, "aborting sc %p\n", sc);
 
+completion_check:
        mutex_lock(&session->eh_mutex);
        spin_lock_bh(&session->frwd_lock);
        /*
@@ -2296,13 +2395,20 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
                return SUCCESS;
        }
 
+       if (!iscsi_get_task(task)) {
+               spin_unlock(&session->back_lock);
+               spin_unlock_bh(&session->frwd_lock);
+               mutex_unlock(&session->eh_mutex);
+               /* We are just about to call iscsi_free_task so wait for it. */
+               udelay(ISCSI_CMD_COMPL_WAIT);
+               goto completion_check;
+       }
+
+       ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt);
        conn = session->leadconn;
        iscsi_get_conn(conn->cls_conn);
        conn->eh_abort_cnt++;
        age = session->age;
-
-       ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt);
-       __iscsi_get_task(task);
        spin_unlock(&session->back_lock);
 
        if (task->state == ISCSI_TASK_PENDING) {
@@ -2828,11 +2934,12 @@ static void iscsi_notify_host_removed(struct iscsi_cls_session *cls_session)
 /**
  * iscsi_host_remove - remove host and sessions
  * @shost: scsi host
+ * @is_shutdown: true if called from a driver shutdown callout
  *
  * If there are any sessions left, this will initiate the removal and wait
  * for the completion.
  */
-void iscsi_host_remove(struct Scsi_Host *shost)
+void iscsi_host_remove(struct Scsi_Host *shost, bool is_shutdown)
 {
        struct iscsi_host *ihost = shost_priv(shost);
        unsigned long flags;
@@ -2841,7 +2948,11 @@ void iscsi_host_remove(struct Scsi_Host *shost)
        ihost->state = ISCSI_HOST_REMOVED;
        spin_unlock_irqrestore(&ihost->lock, flags);
 
-       iscsi_host_for_each_session(shost, iscsi_notify_host_removed);
+       if (!is_shutdown)
+               iscsi_host_for_each_session(shost, iscsi_notify_host_removed);
+       else
+               iscsi_host_for_each_session(shost, iscsi_force_destroy_session);
+
        wait_event_interruptible(ihost->session_removal_wq,
                                 ihost->num_sessions == 0);
        if (signal_pending(current))
index 8830057..c182aa8 100644 (file)
@@ -558,7 +558,11 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
                return 0;
        }
        task->last_xfer = jiffies;
-       __iscsi_get_task(task);
+       if (!iscsi_get_task(task)) {
+               spin_unlock(&session->back_lock);
+               /* Let the path that got the early rsp complete it */
+               return 0;
+       }
 
        tcp_conn = conn->dd_data;
        rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr;
index 260e735..fa22090 100644 (file)
@@ -175,13 +175,13 @@ static enum sas_device_type to_dev_type(struct discover_resp *dr)
                return dr->attached_dev_type;
 }
 
-static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
+static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
+                          struct smp_disc_resp *disc_resp)
 {
        enum sas_device_type dev_type;
        enum sas_linkrate linkrate;
        u8 sas_addr[SAS_ADDR_SIZE];
-       struct smp_resp *resp = rsp;
-       struct discover_resp *dr = &resp->disc;
+       struct discover_resp *dr = &disc_resp->disc;
        struct sas_ha_struct *ha = dev->port->ha;
        struct expander_device *ex = &dev->ex_dev;
        struct ex_phy *phy = &ex->ex_phy[phy_id];
@@ -198,7 +198,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
                BUG_ON(!phy->phy);
        }
 
-       switch (resp->result) {
+       switch (disc_resp->result) {
        case SMP_RESP_PHY_VACANT:
                phy->phy_state = PHY_VACANT;
                break;
@@ -347,12 +347,13 @@ struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id)
 }
 
 #define DISCOVER_REQ_SIZE  16
-#define DISCOVER_RESP_SIZE 56
+#define DISCOVER_RESP_SIZE sizeof(struct smp_disc_resp)
 
 static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req,
-                                     u8 *disc_resp, int single)
+                                     struct smp_disc_resp *disc_resp,
+                                     int single)
 {
-       struct discover_resp *dr;
+       struct discover_resp *dr = &disc_resp->disc;
        int res;
 
        disc_req[9] = single;
@@ -361,7 +362,6 @@ static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req,
                               disc_resp, DISCOVER_RESP_SIZE);
        if (res)
                return res;
-       dr = &((struct smp_resp *)disc_resp)->disc;
        if (memcmp(dev->sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE) == 0) {
                pr_notice("Found loopback topology, just ignore it!\n");
                return 0;
@@ -375,7 +375,7 @@ int sas_ex_phy_discover(struct domain_device *dev, int single)
        struct expander_device *ex = &dev->ex_dev;
        int  res = 0;
        u8   *disc_req;
-       u8   *disc_resp;
+       struct smp_disc_resp *disc_resp;
 
        disc_req = alloc_smp_req(DISCOVER_REQ_SIZE);
        if (!disc_req)
@@ -429,27 +429,14 @@ static int sas_expander_discover(struct domain_device *dev)
 
 #define MAX_EXPANDER_PHYS 128
 
-static void ex_assign_report_general(struct domain_device *dev,
-                                           struct smp_resp *resp)
-{
-       struct report_general_resp *rg = &resp->rg;
-
-       dev->ex_dev.ex_change_count = be16_to_cpu(rg->change_count);
-       dev->ex_dev.max_route_indexes = be16_to_cpu(rg->route_indexes);
-       dev->ex_dev.num_phys = min(rg->num_phys, (u8)MAX_EXPANDER_PHYS);
-       dev->ex_dev.t2t_supp = rg->t2t_supp;
-       dev->ex_dev.conf_route_table = rg->conf_route_table;
-       dev->ex_dev.configuring = rg->configuring;
-       memcpy(dev->ex_dev.enclosure_logical_id, rg->enclosure_logical_id, 8);
-}
-
 #define RG_REQ_SIZE   8
-#define RG_RESP_SIZE 32
+#define RG_RESP_SIZE  sizeof(struct smp_rg_resp)
 
 static int sas_ex_general(struct domain_device *dev)
 {
        u8 *rg_req;
-       struct smp_resp *rg_resp;
+       struct smp_rg_resp *rg_resp;
+       struct report_general_resp *rg;
        int res;
        int i;
 
@@ -480,7 +467,15 @@ static int sas_ex_general(struct domain_device *dev)
                        goto out;
                }
 
-               ex_assign_report_general(dev, rg_resp);
+               rg = &rg_resp->rg;
+               dev->ex_dev.ex_change_count = be16_to_cpu(rg->change_count);
+               dev->ex_dev.max_route_indexes = be16_to_cpu(rg->route_indexes);
+               dev->ex_dev.num_phys = min(rg->num_phys, (u8)MAX_EXPANDER_PHYS);
+               dev->ex_dev.t2t_supp = rg->t2t_supp;
+               dev->ex_dev.conf_route_table = rg->conf_route_table;
+               dev->ex_dev.configuring = rg->configuring;
+               memcpy(dev->ex_dev.enclosure_logical_id,
+                      rg->enclosure_logical_id, 8);
 
                if (dev->ex_dev.configuring) {
                        pr_debug("RG: ex %016llx self-configuring...\n",
@@ -681,10 +676,10 @@ int sas_smp_get_phy_events(struct sas_phy *phy)
 #ifdef CONFIG_SCSI_SAS_ATA
 
 #define RPS_REQ_SIZE  16
-#define RPS_RESP_SIZE 60
+#define RPS_RESP_SIZE sizeof(struct smp_rps_resp)
 
 int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
-                           struct smp_resp *rps_resp)
+                           struct smp_rps_resp *rps_resp)
 {
        int res;
        u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE);
@@ -1657,7 +1652,7 @@ out_err:
 /* ---------- Domain revalidation ---------- */
 
 static int sas_get_phy_discover(struct domain_device *dev,
-                               int phy_id, struct smp_resp *disc_resp)
+                               int phy_id, struct smp_disc_resp *disc_resp)
 {
        int res;
        u8 *disc_req;
@@ -1673,10 +1668,8 @@ static int sas_get_phy_discover(struct domain_device *dev,
                               disc_resp, DISCOVER_RESP_SIZE);
        if (res)
                goto out;
-       else if (disc_resp->result != SMP_RESP_FUNC_ACC) {
+       if (disc_resp->result != SMP_RESP_FUNC_ACC)
                res = disc_resp->result;
-               goto out;
-       }
 out:
        kfree(disc_req);
        return res;
@@ -1686,7 +1679,7 @@ static int sas_get_phy_change_count(struct domain_device *dev,
                                    int phy_id, int *pcc)
 {
        int res;
-       struct smp_resp *disc_resp;
+       struct smp_disc_resp *disc_resp;
 
        disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
        if (!disc_resp)
@@ -1704,19 +1697,17 @@ static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
                                    u8 *sas_addr, enum sas_device_type *type)
 {
        int res;
-       struct smp_resp *disc_resp;
-       struct discover_resp *dr;
+       struct smp_disc_resp *disc_resp;
 
        disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
        if (!disc_resp)
                return -ENOMEM;
-       dr = &disc_resp->disc;
 
        res = sas_get_phy_discover(dev, phy_id, disc_resp);
        if (res == 0) {
                memcpy(sas_addr, disc_resp->disc.attached_sas_addr,
                       SAS_ADDR_SIZE);
-               *type = to_dev_type(dr);
+               *type = to_dev_type(&disc_resp->disc);
                if (*type == 0)
                        memset(sas_addr, 0, SAS_ADDR_SIZE);
        }
@@ -1760,7 +1751,7 @@ static int sas_get_ex_change_count(struct domain_device *dev, int *ecc)
 {
        int res;
        u8  *rg_req;
-       struct smp_resp  *rg_resp;
+       struct smp_rg_resp  *rg_resp;
 
        rg_req = alloc_smp_req(RG_REQ_SIZE);
        if (!rg_req)
index 13d0ffa..8d0ad3a 100644 (file)
@@ -83,7 +83,7 @@ struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy);
 struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id);
 int sas_ex_phy_discover(struct domain_device *dev, int single);
 int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
-                           struct smp_resp *rps_resp);
+                           struct smp_rps_resp *rps_resp);
 int sas_try_ata_reset(struct asd_sas_phy *phy);
 void sas_hae_reset(struct work_struct *work);
 
index c0ee0b3..c3cb7e8 100644 (file)
@@ -722,7 +722,7 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
        struct lpfc_nvmet_tgtport *tgtp;
        struct nvmefc_tgt_fcp_req *rsp;
        struct lpfc_async_xchg_ctx *ctxp;
-       uint32_t status, result, op, start_clean, logerr;
+       uint32_t status, result, op, logerr;
        struct lpfc_wcqe_complete *wcqe = &rspwqe->wcqe_cmpl;
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
        int id;
@@ -820,9 +820,7 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
                /* lpfc_nvmet_xmt_fcp_release() will recycle the context */
        } else {
                ctxp->entry_cnt++;
-               start_clean = offsetof(struct lpfc_iocbq, cmd_flag);
-               memset(((char *)cmdwqe) + start_clean, 0,
-                      (sizeof(struct lpfc_iocbq) - start_clean));
+               memset_startat(cmdwqe, 0, cmd_flag);
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
                if (ctxp->ts_cmd_nvme) {
                        ctxp->ts_isr_data = cmdwqe->isr_timestamp;
index c95360a..fb28c81 100644 (file)
@@ -3947,9 +3947,9 @@ process_fw_state_change_wq(struct work_struct *work)
        u32 wait;
        unsigned long flags;
 
-    if (atomic_read(&instance->adprecovery) != MEGASAS_ADPRESET_SM_INFAULT) {
+       if (atomic_read(&instance->adprecovery) != MEGASAS_ADPRESET_SM_INFAULT) {
                dev_notice(&instance->pdev->dev, "error, recovery st %x\n",
-                               atomic_read(&instance->adprecovery));
+                          atomic_read(&instance->adprecovery));
                return ;
        }
 
index 0e1cb4a..0557dbf 100644 (file)
@@ -71,7 +71,7 @@ extern atomic64_t event_counter;
 #define MPI3MR_SG_DEPTH                (MPI3MR_PAGE_SIZE_4K / sizeof(struct mpi3_sge_common))
 
 /* Definitions for MAX values for shost */
-#define MPI3MR_MAX_CMDS_LUN    7
+#define MPI3MR_MAX_CMDS_LUN    128
 #define MPI3MR_MAX_CDB_LENGTH  32
 
 /* Admin queue management definitions */
index d8c195b..da85eda 100644 (file)
@@ -4321,6 +4321,8 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        shost->max_channel = 0;
        shost->max_id = 0xFFFFFFFF;
 
+       shost->host_tagset = 1;
+
        if (prot_mask >= 0)
                scsi_host_set_prot(shost, prot_mask);
        else {
index 9a1ae52..565339a 100644 (file)
@@ -873,7 +873,7 @@ mpt3sas_base_stop_watchdog(struct MPT3SAS_ADAPTER *ioc)
  * @fault_code: fault code
  */
 void
-mpt3sas_base_fault_info(struct MPT3SAS_ADAPTER *ioc , u16 fault_code)
+mpt3sas_base_fault_info(struct MPT3SAS_ADAPTER *ioc, u16 fault_code)
 {
        ioc_err(ioc, "fault_state(0x%04x)!\n", fault_code);
 }
@@ -1057,7 +1057,7 @@ _base_sas_ioc_info(struct MPT3SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply,
                desc = "config no defaults";
                break;
        case MPI2_IOCSTATUS_CONFIG_CANT_COMMIT:
-               desc = "config cant commit";
+               desc = "config can't commit";
                break;
 
 /****************************************************************************
@@ -1321,7 +1321,7 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
  * @log_info: log info
  */
 static void
-_base_sas_log_info(struct MPT3SAS_ADAPTER *ioc , u32 log_info)
+_base_sas_log_info(struct MPT3SAS_ADAPTER *ioc, u32 log_info)
 {
        union loginfo_type {
                u32     loginfo;
@@ -1393,7 +1393,7 @@ _base_display_reply_info(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
 
        if ((ioc_status & MPI2_IOCSTATUS_MASK) &&
            (ioc->logging_level & MPT_DEBUG_REPLY)) {
-               _base_sas_ioc_info(ioc , mpi_reply,
+               _base_sas_ioc_info(ioc, mpi_reply,
                   mpt3sas_base_get_msg_frame(ioc, smid));
        }
 
index b519f4b..f321733 100644 (file)
@@ -5294,7 +5294,7 @@ _scsih_normalize_sense(char *sense_buffer, struct sense_info *data)
 }
 
 /**
- * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request
+ * _scsih_scsi_ioc_info - translated non-successful SCSI_IO request
  * @ioc: per adapter object
  * @scmd: pointer to scsi command object
  * @mpi_reply: reply mf payload returned from firmware
@@ -12409,7 +12409,6 @@ scsih_suspend(struct device *dev)
                return rc;
 
        mpt3sas_base_stop_watchdog(ioc);
-       flush_scheduled_work();
        scsi_block_requests(shost);
        _scsih_nvme_shutdown(ioc);
        ioc_info(ioc, "pdev=0x%p, slot=%s, entering operating state\n",
index f7466a8..a375956 100644 (file)
@@ -699,6 +699,10 @@ static int pm8001_chip_init(struct pm8001_hba_info *pm8001_ha)
        return 0;
 }
 
+static void pm8001_chip_post_init(struct pm8001_hba_info *pm8001_ha)
+{
+}
+
 static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)
 {
        u32 max_wait_count;
@@ -4947,6 +4951,7 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)
 const struct pm8001_dispatch pm8001_8001_dispatch = {
        .name                   = "pmc8001",
        .chip_init              = pm8001_chip_init,
+       .chip_post_init         = pm8001_chip_post_init,
        .chip_soft_rst          = pm8001_chip_soft_rst,
        .chip_rst               = pm8001_hw_chip_rst,
        .chip_iounmap           = pm8001_chip_iounmap,
index 9b04f1a..a3a972c 100644 (file)
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(link_rate, "Enable link rate.\n"
                " 8: Link rate 12.0G\n");
 
 static struct scsi_transport_template *pm8001_stt;
-static int pm8001_init_ccb_tag(struct pm8001_hba_info *, struct Scsi_Host *, struct pci_dev *);
+static int pm8001_init_ccb_tag(struct pm8001_hba_info *);
 
 /*
  * chip info structure to identify chip key functionality as
@@ -81,6 +81,18 @@ LIST_HEAD(hba_list);
 
 struct workqueue_struct *pm8001_wq;
 
+static int pm8001_map_queues(struct Scsi_Host *shost)
+{
+       struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+       struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+       struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT];
+
+       if (pm8001_ha->number_of_intr > 1)
+               blk_mq_pci_map_queues(qmap, pm8001_ha->pdev, 1);
+
+       return blk_mq_map_queues(qmap);
+}
+
 /*
  * The main structure which LLDD must register for scsi core.
  */
@@ -109,6 +121,8 @@ static struct scsi_host_template pm8001_sht = {
 #endif
        .shost_groups           = pm8001_host_groups,
        .track_queue_depth      = 1,
+       .cmd_per_lun            = 32,
+       .map_queues             = pm8001_map_queues,
 };
 
 /*
@@ -605,12 +619,8 @@ static int pm8001_prep_sas_ha_init(struct Scsi_Host *shost,
 
        shost->transportt = pm8001_stt;
        shost->max_id = PM8001_MAX_DEVICES;
-       shost->max_lun = 8;
-       shost->max_channel = 0;
        shost->unique_id = pm8001_id;
        shost->max_cmd_len = 16;
-       shost->can_queue = PM8001_CAN_QUEUE;
-       shost->cmd_per_lun = 32;
        return 0;
 exit_free1:
        kfree(arr_port);
@@ -931,31 +941,35 @@ static int pm8001_configure_phy_settings(struct pm8001_hba_info *pm8001_ha)
  */
 static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha)
 {
-       u32 number_of_intr;
-       int rc, cpu_online_count;
        unsigned int allocated_irq_vectors;
+       int rc;
 
        /* SPCv controllers supports 64 msi-x */
        if (pm8001_ha->chip_id == chip_8001) {
-               number_of_intr = 1;
+               rc = pci_alloc_irq_vectors(pm8001_ha->pdev, 1, 1,
+                                          PCI_IRQ_MSIX);
        } else {
-               number_of_intr = PM8001_MAX_MSIX_VEC;
+               /*
+                * Queue index #0 is used always for housekeeping, so don't
+                * include in the affinity spreading.
+                */
+               struct irq_affinity desc = {
+                       .pre_vectors = 1,
+               };
+               rc = pci_alloc_irq_vectors_affinity(
+                               pm8001_ha->pdev, 2, PM8001_MAX_MSIX_VEC,
+                               PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, &desc);
        }
 
-       cpu_online_count = num_online_cpus();
-       number_of_intr = min_t(int, cpu_online_count, number_of_intr);
-       rc = pci_alloc_irq_vectors(pm8001_ha->pdev, number_of_intr,
-                       number_of_intr, PCI_IRQ_MSIX);
        allocated_irq_vectors = rc;
        if (rc < 0)
                return rc;
 
        /* Assigns the number of interrupts */
-       number_of_intr = min_t(int, allocated_irq_vectors, number_of_intr);
-       pm8001_ha->number_of_intr = number_of_intr;
+       pm8001_ha->number_of_intr = allocated_irq_vectors;
 
        /* Maximum queue number updating in HBA structure */
-       pm8001_ha->max_q_num = number_of_intr;
+       pm8001_ha->max_q_num = allocated_irq_vectors;
 
        pm8001_dbg(pm8001_ha, INIT,
                   "pci_alloc_irq_vectors request ret:%d no of intr %d\n",
@@ -1122,10 +1136,23 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
                goto err_out_ha_free;
        }
 
-       rc = pm8001_init_ccb_tag(pm8001_ha, shost, pdev);
+       rc = pm8001_init_ccb_tag(pm8001_ha);
        if (rc)
                goto err_out_enable;
 
+
+       PM8001_CHIP_DISP->chip_post_init(pm8001_ha);
+
+       if (pm8001_ha->number_of_intr > 1) {
+               shost->nr_hw_queues = pm8001_ha->number_of_intr - 1;
+               /*
+                * For now, ensure we're not sent too many commands by setting
+                * host_tagset. This is also required if we start using request
+                * tag.
+                */
+               shost->host_tagset = 1;
+       }
+
        rc = scsi_add_host(shost, &pdev->dev);
        if (rc)
                goto err_out_ha_free;
@@ -1175,16 +1202,14 @@ err_out_enable:
 /**
  * pm8001_init_ccb_tag - allocate memory to CCB and tag.
  * @pm8001_ha: our hba card information.
- * @shost: scsi host which has been allocated outside.
- * @pdev: pci device.
  */
-static int
-pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost,
-                       struct pci_dev *pdev)
+static int pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha)
 {
-       int i = 0;
+       struct Scsi_Host *shost = pm8001_ha->shost;
+       struct device *dev = pm8001_ha->dev;
        u32 max_out_io, ccb_count;
        u32 can_queue;
+       int i;
 
        max_out_io = pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io;
        ccb_count = min_t(int, PM8001_MAX_CCB, max_out_io);
@@ -1207,7 +1232,7 @@ pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost,
                goto err_out_noccb;
        }
        for (i = 0; i < ccb_count; i++) {
-               pm8001_ha->ccb_info[i].buf_prd = dma_alloc_coherent(&pdev->dev,
+               pm8001_ha->ccb_info[i].buf_prd = dma_alloc_coherent(dev,
                                sizeof(struct pm8001_prd) * PM8001_MAX_DMA_SG,
                                &pm8001_ha->ccb_info[i].ccb_dma_handle,
                                GFP_KERNEL);
index 3a863d7..8e3f2f9 100644 (file)
@@ -66,7 +66,11 @@ static int pm8001_find_tag(struct sas_task *task, u32 *tag)
 void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag)
 {
        void *bitmap = pm8001_ha->tags;
-       clear_bit(tag, bitmap);
+       unsigned long flags;
+
+       spin_lock_irqsave(&pm8001_ha->bitmap_lock, flags);
+       __clear_bit(tag, bitmap);
+       spin_unlock_irqrestore(&pm8001_ha->bitmap_lock, flags);
 }
 
 /**
@@ -76,9 +80,9 @@ void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag)
   */
 int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out)
 {
-       unsigned int tag;
        void *bitmap = pm8001_ha->tags;
        unsigned long flags;
+       unsigned int tag;
 
        spin_lock_irqsave(&pm8001_ha->bitmap_lock, flags);
        tag = find_first_zero_bit(bitmap, pm8001_ha->tags_num);
@@ -86,7 +90,7 @@ int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out)
                spin_unlock_irqrestore(&pm8001_ha->bitmap_lock, flags);
                return -SAS_QUEUE_FULL;
        }
-       set_bit(tag, bitmap);
+       __set_bit(tag, bitmap);
        spin_unlock_irqrestore(&pm8001_ha->bitmap_lock, flags);
        *tag_out = tag;
        return 0;
index 060ab68..c5e3f38 100644 (file)
@@ -55,6 +55,8 @@
 #include <scsi/scsi_tcq.h>
 #include <scsi/sas_ata.h>
 #include <linux/atomic.h>
+#include <linux/blk-mq.h>
+#include <linux/blk-mq-pci.h>
 #include "pm8001_defs.h"
 
 #define DRV_NAME               "pm80xx"
@@ -172,6 +174,7 @@ struct forensic_data {
 struct pm8001_dispatch {
        char *name;
        int (*chip_init)(struct pm8001_hba_info *pm8001_ha);
+       void (*chip_post_init)(struct pm8001_hba_info *pm8001_ha);
        int (*chip_soft_rst)(struct pm8001_hba_info *pm8001_ha);
        void (*chip_rst)(struct pm8001_hba_info *pm8001_ha);
        int (*chip_ioremap)(struct pm8001_hba_info *pm8001_ha);
index 01c5e8f..3893f70 100644 (file)
@@ -1469,11 +1469,18 @@ static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha)
        } else
                return -EBUSY;
 
+       return 0;
+}
+
+static void pm80xx_chip_post_init(struct pm8001_hba_info *pm8001_ha)
+{
        /* send SAS protocol timer configuration page to FW */
-       ret = pm80xx_set_sas_protocol_timer_config(pm8001_ha);
+       pm80xx_set_sas_protocol_timer_config(pm8001_ha);
 
        /* Check for encryption */
        if (pm8001_ha->chip->encrypt) {
+               int ret;
+
                pm8001_dbg(pm8001_ha, INIT, "Checking for encryption\n");
                ret = pm80xx_get_encrypt_info(pm8001_ha);
                if (ret == -1) {
@@ -1485,7 +1492,6 @@ static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha)
                        }
                }
        }
-       return 0;
 }
 
 static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)
@@ -4345,6 +4351,29 @@ static int check_enc_sat_cmd(struct sas_task *task)
        return ret;
 }
 
+static u32 pm80xx_chip_get_q_index(struct sas_task *task)
+{
+       struct scsi_cmnd *scmd = NULL;
+       u32 blk_tag;
+
+       if (task->uldd_task) {
+               struct ata_queued_cmd *qc;
+
+               if (dev_is_sata(task->dev)) {
+                       qc = task->uldd_task;
+                       scmd = qc->scsicmd;
+               } else {
+                       scmd = task->uldd_task;
+               }
+       }
+
+       if (!scmd)
+               return 0;
+
+       blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd));
+       return blk_mq_unique_tag_to_hwq(blk_tag);
+}
+
 /**
  * pm80xx_chip_ssp_io_req - send an SSP task to FW
  * @pm8001_ha: our hba card information.
@@ -4360,7 +4389,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
        u32 tag = ccb->ccb_tag;
        u64 phys_addr, end_addr;
        u32 end_addr_high, end_addr_low;
-       u32 q_index, cpu_id;
+       u32 q_index;
        u32 opc = OPC_INB_SSPINIIOSTART;
 
        memset(&ssp_cmd, 0, sizeof(ssp_cmd));
@@ -4381,8 +4410,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
        ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
        memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd,
                       task->ssp_task.cmd->cmd_len);
-       cpu_id = smp_processor_id();
-       q_index = (u32) (cpu_id) % (pm8001_ha->max_q_num);
+       q_index = pm80xx_chip_get_q_index(task);
 
        /* Check if encryption is set */
        if (pm8001_ha->chip->encrypt &&
@@ -4511,8 +4539,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
        struct domain_device *dev = task->dev;
        struct pm8001_device *pm8001_ha_dev = dev->lldd_dev;
        struct ata_queued_cmd *qc = task->uldd_task;
-       u32 tag = ccb->ccb_tag;
-       u32 q_index, cpu_id;
+       u32 tag = ccb->ccb_tag, q_index;
        struct sata_start_req sata_cmd;
        u32 hdr_tag, ncg_tag = 0;
        u64 phys_addr, end_addr;
@@ -4522,8 +4549,8 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
        unsigned long flags;
        u32 opc = OPC_INB_SATA_HOST_OPSTART;
        memset(&sata_cmd, 0, sizeof(sata_cmd));
-       cpu_id = smp_processor_id();
-       q_index = (u32) (cpu_id) % (pm8001_ha->max_q_num);
+
+       q_index = pm80xx_chip_get_q_index(task);
 
        if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {
                ATAP = 0x04; /* no data*/
@@ -5007,6 +5034,7 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
 const struct pm8001_dispatch pm8001_80xx_dispatch = {
        .name                   = "pmc80xx",
        .chip_init              = pm80xx_chip_init,
+       .chip_post_init         = pm80xx_chip_post_init,
        .chip_soft_rst          = pm80xx_chip_soft_rst,
        .chip_rst               = pm80xx_hw_chip_rst,
        .chip_iounmap           = pm8001_chip_iounmap,
index 83ffba7..cecfb2c 100644 (file)
@@ -2414,9 +2414,12 @@ static void __qedi_remove(struct pci_dev *pdev, int mode)
        int rval;
        u16 retry = 10;
 
-       if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) {
-               iscsi_host_remove(qedi->shost);
+       if (mode == QEDI_MODE_NORMAL)
+               iscsi_host_remove(qedi->shost, false);
+       else if (mode == QEDI_MODE_SHUTDOWN)
+               iscsi_host_remove(qedi->shost, true);
 
+       if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) {
                if (qedi->tmf_thread) {
                        destroy_workqueue(qedi->tmf_thread);
                        qedi->tmf_thread = NULL;
@@ -2491,7 +2494,7 @@ static void qedi_board_disable_work(struct work_struct *work)
        if (test_and_set_bit(QEDI_IN_SHUTDOWN, &qedi->flags))
                return;
 
-       __qedi_remove(qedi->pdev, QEDI_MODE_SHUTDOWN);
+       __qedi_remove(qedi->pdev, QEDI_MODE_NORMAL);
 }
 
 static void qedi_shutdown(struct pci_dev *pdev)
@@ -2791,7 +2794,7 @@ remove_host:
 #ifdef CONFIG_DEBUG_FS
        qedi_dbg_host_exit(&qedi->dbg_ctx);
 #endif
-       iscsi_host_remove(qedi->shost);
+       iscsi_host_remove(qedi->shost, false);
 stop_iscsi_func:
        qedi_ops->stop(qedi->cdev);
 stop_slowpath:
index 3b3e423..fa1fcbf 100644 (file)
@@ -2476,7 +2476,6 @@ static DEVICE_ATTR(port_speed, 0644, qla2x00_port_speed_show,
     qla2x00_port_speed_store);
 static DEVICE_ATTR(port_no, 0444, qla2x00_port_no_show, NULL);
 static DEVICE_ATTR(fw_attr, 0444, qla2x00_fw_attr_show, NULL);
-static DEVICE_ATTR_RO(edif_doorbell);
 
 static struct attribute *qla2x00_host_attrs[] = {
        &dev_attr_driver_version.attr,
@@ -2521,7 +2520,6 @@ static struct attribute *qla2x00_host_attrs[] = {
        &dev_attr_port_no.attr,
        &dev_attr_fw_attr.attr,
        &dev_attr_dport_diagnostics.attr,
-       &dev_attr_edif_doorbell.attr,
        &dev_attr_mpi_pause.attr,
        &dev_attr_qlini_mode.attr,
        &dev_attr_ql2xiniexchg.attr,
@@ -2716,17 +2714,27 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
        if (!fcport)
                return;
 
-       /* Now that the rport has been deleted, set the fcport state to
-          FCS_DEVICE_DEAD */
-       qla2x00_set_fcport_state(fcport, FCS_DEVICE_DEAD);
+       ql_dbg(ql_dbg_async, fcport->vha, 0x5101,
+              DBG_FCPORT_PRFMT(fcport, "dev_loss_tmo expiry, rport_state=%d",
+                               rport->port_state));
+
+       /*
+        * Now that the rport has been deleted, set the fcport state to
+        * FCS_DEVICE_DEAD, if the fcport is still lost.
+        */
+       if (fcport->scan_state != QLA_FCPORT_FOUND)
+               qla2x00_set_fcport_state(fcport, FCS_DEVICE_DEAD);
 
        /*
         * Transport has effectively 'deleted' the rport, clear
         * all local references.
         */
        spin_lock_irqsave(host->host_lock, flags);
-       fcport->rport = fcport->drport = NULL;
-       *((fc_port_t **)rport->dd_data) = NULL;
+       /* Confirm port has not reappeared before clearing pointers. */
+       if (rport->port_state != FC_PORTSTATE_ONLINE) {
+               fcport->rport = fcport->drport = NULL;
+               *((fc_port_t **)rport->dd_data) = NULL;
+       }
        spin_unlock_irqrestore(host->host_lock, flags);
 
        if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags))
@@ -2759,9 +2767,12 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
        /*
         * At this point all fcport's software-states are cleared.  Perform any
         * final cleanup of firmware resources (PCBs and XCBs).
+        *
+        * Attempt to cleanup only lost devices.
         */
        if (fcport->loop_id != FC_NO_LOOP_ID) {
-               if (IS_FWI2_CAPABLE(fcport->vha->hw)) {
+               if (IS_FWI2_CAPABLE(fcport->vha->hw) &&
+                   fcport->scan_state != QLA_FCPORT_FOUND) {
                        if (fcport->loop_id != FC_NO_LOOP_ID)
                                fcport->logout_on_delete = 1;
 
@@ -2771,7 +2782,7 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
                                       __LINE__);
                                qlt_schedule_sess_for_deletion(fcport);
                        }
-               } else {
+               } else if (!IS_FWI2_CAPABLE(fcport->vha->hw)) {
                        qla2x00_port_logout(fcport->vha, fcport);
                }
        }
index c2f00f0..299c5cb 100644 (file)
@@ -2425,6 +2425,89 @@ qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job)
 }
 
 static int
+qla2x00_do_dport_diagnostics_v2(struct bsg_job *bsg_job)
+{
+       struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+       struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
+       scsi_qla_host_t *vha = shost_priv(host);
+       int rval;
+       struct qla_dport_diag_v2 *dd;
+       mbx_cmd_t mc;
+       mbx_cmd_t *mcp = &mc;
+       uint16_t options;
+
+       if (!IS_DPORT_CAPABLE(vha->hw))
+               return -EPERM;
+
+       dd = kzalloc(sizeof(*dd), GFP_KERNEL);
+       if (!dd)
+               return -ENOMEM;
+
+       sg_copy_to_buffer(bsg_job->request_payload.sg_list,
+                       bsg_job->request_payload.sg_cnt, dd, sizeof(*dd));
+
+       options  = dd->options;
+
+       /*  Check dport Test in progress */
+       if (options == QLA_GET_DPORT_RESULT_V2 &&
+           vha->dport_status & DPORT_DIAG_IN_PROGRESS) {
+               bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
+                                       EXT_STATUS_DPORT_DIAG_IN_PROCESS;
+               goto dportcomplete;
+       }
+
+       /*  Check chip reset in progress and start/restart requests arrive */
+       if (vha->dport_status & DPORT_DIAG_CHIP_RESET_IN_PROGRESS &&
+           (options == QLA_START_DPORT_TEST_V2 ||
+            options == QLA_RESTART_DPORT_TEST_V2)) {
+               vha->dport_status &= ~DPORT_DIAG_CHIP_RESET_IN_PROGRESS;
+       }
+
+       /*  Check chip reset in progress and get result request arrive */
+       if (vha->dport_status & DPORT_DIAG_CHIP_RESET_IN_PROGRESS &&
+           options == QLA_GET_DPORT_RESULT_V2) {
+               bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
+                                       EXT_STATUS_DPORT_DIAG_NOT_RUNNING;
+               goto dportcomplete;
+       }
+
+       rval = qla26xx_dport_diagnostics_v2(vha, dd, mcp);
+
+       if (rval == QLA_SUCCESS) {
+               bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
+                                       EXT_STATUS_OK;
+               if (options == QLA_START_DPORT_TEST_V2 ||
+                   options == QLA_RESTART_DPORT_TEST_V2) {
+                       dd->mbx1 = mcp->mb[0];
+                       dd->mbx2 = mcp->mb[1];
+                       vha->dport_status |=  DPORT_DIAG_IN_PROGRESS;
+               } else if (options == QLA_GET_DPORT_RESULT_V2) {
+                       dd->mbx1 = vha->dport_data[1];
+                       dd->mbx2 = vha->dport_data[2];
+               }
+       } else {
+               dd->mbx1 = mcp->mb[0];
+               dd->mbx2 = mcp->mb[1];
+               bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
+                               EXT_STATUS_DPORT_DIAG_ERR;
+       }
+
+dportcomplete:
+       sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
+                           bsg_job->reply_payload.sg_cnt, dd, sizeof(*dd));
+
+       bsg_reply->reply_payload_rcv_len = sizeof(*dd);
+       bsg_job->reply_len = sizeof(*bsg_reply);
+       bsg_reply->result = DID_OK << 16;
+       bsg_job_done(bsg_job, bsg_reply->result,
+                    bsg_reply->reply_payload_rcv_len);
+
+       kfree(dd);
+
+       return 0;
+}
+
+static int
 qla2x00_get_flash_image_status(struct bsg_job *bsg_job)
 {
        scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
@@ -2860,6 +2943,9 @@ qla2x00_process_vendor_specific(struct scsi_qla_host *vha, struct bsg_job *bsg_j
        case QL_VND_DPORT_DIAGNOSTICS:
                return qla2x00_do_dport_diagnostics(bsg_job);
 
+       case QL_VND_DPORT_DIAGNOSTICS_V2:
+               return qla2x00_do_dport_diagnostics_v2(bsg_job);
+
        case QL_VND_EDIF_MGMT:
                return qla_edif_app_mgmt(bsg_job);
 
@@ -2975,6 +3061,13 @@ qla24xx_bsg_timeout(struct bsg_job *bsg_job)
 
        ql_log(ql_log_info, vha, 0x708b, "%s CMD timeout. bsg ptr %p.\n",
            __func__, bsg_job);
+
+       if (qla2x00_isp_reg_stat(ha)) {
+               ql_log(ql_log_info, vha, 0x9007,
+                   "PCI/Register disconnect.\n");
+               qla_pci_set_eeh_busy(vha);
+       }
+
        /* find the bsg job from the active list of commands */
        spin_lock_irqsave(&ha->hardware_lock, flags);
        for (que = 0; que < ha->max_req_queues; que++) {
@@ -2992,7 +3085,8 @@ qla24xx_bsg_timeout(struct bsg_job *bsg_job)
                            sp->u.bsg_job == bsg_job) {
                                req->outstanding_cmds[cnt] = NULL;
                                spin_unlock_irqrestore(&ha->hardware_lock, flags);
-                               if (ha->isp_ops->abort_command(sp)) {
+
+                               if (!ha->flags.eeh_busy && ha->isp_ops->abort_command(sp)) {
                                        ql_log(ql_log_warn, vha, 0x7089,
                                            "mbx abort_command failed.\n");
                                        bsg_reply->result = -EIO;
index 6d2b0a7..bb64b9c 100644 (file)
@@ -37,6 +37,7 @@
 #define QL_VND_GET_TGT_STATS           0x25
 #define QL_VND_MANAGE_HOST_PORT                0x26
 #define QL_VND_MBX_PASSTHRU            0x2B
+#define QL_VND_DPORT_DIAGNOSTICS_V2    0x2C
 
 /* BSG Vendor specific subcode returns */
 #define EXT_STATUS_OK                  0
@@ -60,6 +61,9 @@
 #define EXT_STATUS_TIMEOUT             30
 #define EXT_STATUS_THREAD_FAILED       31
 #define EXT_STATUS_DATA_CMP_FAILED     32
+#define EXT_STATUS_DPORT_DIAG_ERR      40
+#define EXT_STATUS_DPORT_DIAG_IN_PROCESS       41
+#define EXT_STATUS_DPORT_DIAG_NOT_RUNNING      42
 
 /* BSG definations for interpreting CommandSent field */
 #define INT_DEF_LB_LOOPBACK_CMD         0
@@ -288,6 +292,17 @@ struct qla_dport_diag {
        uint8_t  unused[62];
 } __packed;
 
+#define QLA_GET_DPORT_RESULT_V2                0  /* Get Result */
+#define QLA_RESTART_DPORT_TEST_V2      1  /* Restart test */
+#define QLA_START_DPORT_TEST_V2                2  /* Start test */
+struct qla_dport_diag_v2 {
+       uint16_t options;
+       uint16_t mbx1;
+       uint16_t mbx2;
+       uint8_t  unused[58];
+       uint8_t buf[1024]; /* Test Result */
+} __packed;
+
 /* D_Port options */
 #define QLA_DPORT_RESULT       0x0
 #define QLA_DPORT_START                0x2
index f1f6c74..feeb166 100644 (file)
@@ -383,5 +383,5 @@ ql_mask_match(uint level)
        if (ql2xextended_error_logging == 1)
                ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK;
 
-       return (level & ql2xextended_error_logging) == level;
+       return level && ((level & ql2xextended_error_logging) == level);
 }
index e8f69c4..1bdc7a2 100644 (file)
@@ -1173,6 +1173,12 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
 
 /* ISP mailbox loopback echo diagnostic error code */
 #define MBS_LB_RESET   0x17
+
+/* AEN mailbox Port Diagnostics test */
+#define AEN_START_DIAG_TEST            0x0     /* start the diagnostics */
+#define AEN_DONE_DIAG_TEST_WITH_NOERR  0x1     /* Done with no errors */
+#define AEN_DONE_DIAG_TEST_WITH_ERR    0x2     /* Done with error.*/
+
 /*
  * Firmware options 1, 2, 3.
  */
@@ -2158,6 +2164,11 @@ typedef struct {
 #define CS_IOCB_ERROR          0x31    /* Generic error for IOCB request
                                           failure */
 #define CS_REJECT_RECEIVED     0x4E    /* Reject received */
+#define CS_EDIF_AUTH_ERROR     0x63    /* decrypt error */
+#define CS_EDIF_PAD_LEN_ERROR  0x65    /* pad > frame size, not 4byte align */
+#define CS_EDIF_INV_REQ                0x66    /* invalid request */
+#define CS_EDIF_SPI_ERROR      0x67    /* rx frame unable to locate sa */
+#define CS_EDIF_HDR_ERROR      0x69    /* data frame != expected len */
 #define CS_BAD_PAYLOAD         0x80    /* Driver defined */
 #define CS_UNKNOWN             0x81    /* Driver defined */
 #define CS_RETRY               0x82    /* Driver defined */
@@ -2626,7 +2637,6 @@ typedef struct fc_port {
        struct {
                uint32_t        enable:1;       /* device is edif enabled/req'd */
                uint32_t        app_stop:2;
-               uint32_t        app_started:1;
                uint32_t        aes_gmac:1;
                uint32_t        app_sess_online:1;
                uint32_t        tx_sa_set:1;
@@ -2637,6 +2647,7 @@ typedef struct fc_port {
                uint32_t        rx_rekey_cnt;
                uint64_t        tx_bytes;
                uint64_t        rx_bytes;
+               uint8_t         sess_down_acked;
                uint8_t         auth_state;
                uint16_t        authok:1;
                uint16_t        rekey_cnt;
@@ -3204,6 +3215,8 @@ struct ct_sns_rsp {
 #define GFF_NVME_OFFSET                23 /* type = 28h */
                struct {
                        uint8_t fc4_features[128];
+#define FC4_FF_TARGET    BIT_0
+#define FC4_FF_INITIATOR BIT_1
                } gff_id;
                struct {
                        uint8_t reserved;
@@ -4040,6 +4053,9 @@ struct qla_hw_data {
                uint32_t        n2n_fw_acc_sec:1;
                uint32_t        plogi_template_valid:1;
                uint32_t        port_isolated:1;
+               uint32_t        eeh_flush:2;
+#define EEH_FLUSH_RDY  1
+#define EEH_FLUSH_DONE 2
        } flags;
 
        uint16_t max_exchg;
@@ -4074,6 +4090,7 @@ struct qla_hw_data {
        uint32_t                rsp_que_len;
        uint32_t                req_que_off;
        uint32_t                rsp_que_off;
+       unsigned long           eeh_jif;
 
        /* Multi queue data structs */
        device_reg_t *mqiobase;
@@ -4256,8 +4273,8 @@ struct qla_hw_data {
 #define IS_OEM_001(ha)          ((ha)->device_type & DT_OEM_001)
 #define HAS_EXTENDED_IDS(ha)    ((ha)->device_type & DT_EXTENDED_IDS)
 #define IS_CT6_SUPPORTED(ha)   ((ha)->device_type & DT_CT6_SUPPORTED)
-#define IS_MQUE_CAPABLE(ha)    ((ha)->mqenable || IS_QLA83XX(ha) || \
-                               IS_QLA27XX(ha) || IS_QLA28XX(ha))
+#define IS_MQUE_CAPABLE(ha)    (IS_QLA83XX(ha) || IS_QLA27XX(ha) || \
+                                IS_QLA28XX(ha))
 #define IS_BIDI_CAPABLE(ha) \
     (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
 /* Bit 21 of fw_attributes decides the MCTP capabilities */
@@ -5012,6 +5029,10 @@ typedef struct scsi_qla_host {
        u64 short_link_down_cnt;
        struct edif_dbell e_dbell;
        struct pur_core pur_cinfo;
+
+#define DPORT_DIAG_IN_PROGRESS                 BIT_0
+#define DPORT_DIAG_CHIP_RESET_IN_PROGRESS      BIT_1
+       uint16_t dport_status;
 } scsi_qla_host_t;
 
 struct qla27xx_image_status {
@@ -5443,4 +5464,10 @@ struct ql_vnd_tgt_stats_resp {
 #define IS_SESSION_DELETED(_fcport) (_fcport->disc_state == DSC_DELETE_PEND || \
                                      _fcport->disc_state == DSC_DELETED)
 
+#define DBG_FCPORT_PRFMT(_fp, _fmt, _args...) \
+       "%s: %8phC: " _fmt " (state=%d disc_state=%d scan_state=%d loopid=0x%x deleted=%d flags=0x%x)\n", \
+       __func__, _fp->port_name, ##_args, atomic_read(&_fp->state), \
+       _fp->disc_state, _fp->scan_state, _fp->loop_id, _fp->deleted, \
+       _fp->flags
+
 #endif
index cb8145a..400a8b6 100644 (file)
@@ -52,6 +52,31 @@ const char *sc_to_str(uint16_t cmd)
        return "unknown";
 }
 
+static struct edb_node *qla_edb_getnext(scsi_qla_host_t *vha)
+{
+       unsigned long   flags;
+       struct edb_node *edbnode = NULL;
+
+       spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
+
+       /* db nodes are fifo - no qualifications done */
+       if (!list_empty(&vha->e_dbell.head)) {
+               edbnode = list_first_entry(&vha->e_dbell.head,
+                                          struct edb_node, list);
+               list_del_init(&edbnode->list);
+       }
+
+       spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
+
+       return edbnode;
+}
+
+static void qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node)
+{
+       list_del_init(&node->list);
+       kfree(node);
+}
+
 static struct edif_list_entry *qla_edif_list_find_sa_index(fc_port_t *fcport,
                uint16_t handle)
 {
@@ -257,14 +282,8 @@ qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id)
 
        f = NULL;
        list_for_each_entry_safe(f, tf, &vha->vp_fcports, list) {
-               if ((f->flags & FCF_FCSP_DEVICE)) {
-                       ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x2058,
-                           "Found secure fcport - nn %8phN pn %8phN portid=0x%x, 0x%x.\n",
-                           f->node_name, f->port_name,
-                           f->d_id.b24, id->b24);
-                       if (f->d_id.b24 == id->b24)
-                               return f;
-               }
+               if (f->d_id.b24 == id->b24)
+                       return f;
        }
        return NULL;
 }
@@ -280,14 +299,19 @@ qla_edif_app_check(scsi_qla_host_t *vha, struct app_id appid)
 {
        /* check that the app is allow/known to the driver */
 
-       if (appid.app_vid == EDIF_APP_ID) {
-               ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x911d, "%s app id ok\n", __func__);
-               return true;
+       if (appid.app_vid != EDIF_APP_ID) {
+               ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app id not ok (%x)",
+                   __func__, appid.app_vid);
+               return false;
+       }
+
+       if (appid.version != EDIF_VERSION1) {
+               ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app version is not ok (%x)",
+                   __func__, appid.version);
+               return false;
        }
-       ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app id not ok (%x)",
-           __func__, appid.app_vid);
 
-       return false;
+       return true;
 }
 
 static void
@@ -486,16 +510,35 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
                /* mark doorbell as active since an app is now present */
                vha->e_dbell.db_flags |= EDB_ACTIVE;
        } else {
-               ql_dbg(ql_dbg_edif, vha, 0x911e, "%s doorbell already active\n",
-                    __func__);
+               goto out;
        }
 
        if (N2N_TOPO(vha->hw)) {
-               if (vha->hw->flags.n2n_fw_acc_sec)
-                       set_bit(N2N_LINK_RESET, &vha->dpc_flags);
-               else
+               list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list)
+                       fcport->n2n_link_reset_cnt = 0;
+
+               if (vha->hw->flags.n2n_fw_acc_sec) {
+                       list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list)
+                               qla_edif_sa_ctl_init(vha, fcport);
+
+                       /*
+                        * While authentication app was not running, remote device
+                        * could still try to login with this local port.  Let's
+                        * clear the state and try again.
+                        */
+                       qla2x00_wait_for_sess_deletion(vha);
+
+                       /* bounce the link to get the other guy to relogin */
+                       if (!vha->hw->flags.n2n_bigger) {
+                               set_bit(N2N_LINK_RESET, &vha->dpc_flags);
+                               qla2xxx_wake_dpc(vha);
+                       }
+               } else {
+                       qla2x00_wait_for_hba_online(vha);
                        set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
-               qla2xxx_wake_dpc(vha);
+                       qla2xxx_wake_dpc(vha);
+                       qla2x00_wait_for_hba_online(vha);
+               }
        } else {
                list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
                        ql_dbg(ql_dbg_edif, vha, 0x2058,
@@ -517,19 +560,31 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
                        if (atomic_read(&vha->loop_state) == LOOP_DOWN)
                                break;
 
-                       fcport->edif.app_started = 1;
                        fcport->login_retry = vha->hw->login_retry_count;
 
-                       /* no activity */
                        fcport->edif.app_stop = 0;
+                       fcport->edif.app_sess_online = 0;
+
+                       if (fcport->scan_state != QLA_FCPORT_FOUND)
+                               continue;
+
+                       if (fcport->port_type == FCT_UNKNOWN &&
+                           !fcport->fc4_features)
+                               rval = qla24xx_async_gffid(vha, fcport, true);
+
+                       if (!rval && !(fcport->fc4_features & FC4_FF_TARGET ||
+                           fcport->port_type & (FCT_TARGET|FCT_NVME_TARGET)))
+                               continue;
+
+                       rval = 0;
 
                        ql_dbg(ql_dbg_edif, vha, 0x911e,
                               "%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
                               __func__, fcport->port_name);
-                       fcport->edif.app_sess_online = 0;
                        qlt_schedule_sess_for_deletion(fcport);
                        qla_edif_sa_ctl_init(vha, fcport);
                }
+               set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
        }
 
        if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
@@ -540,9 +595,11 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
                     __func__);
        }
 
+out:
        appreply.host_support_edif = vha->hw->flags.edif_enabled;
        appreply.edif_enode_active = vha->pur_cinfo.enode_flags;
        appreply.edif_edb_active = vha->e_dbell.db_flags;
+       appreply.version = EDIF_VERSION1;
 
        bsg_job->reply_len = sizeof(struct fc_bsg_reply);
 
@@ -610,9 +667,6 @@ qla_edif_app_stop(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
 
                        fcport->send_els_logo = 1;
                        qlt_schedule_sess_for_deletion(fcport);
-
-                       /* qla_edif_flush_sa_ctl_lists(fcport); */
-                       fcport->edif.app_started = 0;
                }
        }
 
@@ -672,6 +726,7 @@ qla_edif_app_authok(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
        portid.b.area   = appplogiok.u.d_id.b.area;
        portid.b.al_pa  = appplogiok.u.d_id.b.al_pa;
 
+       appplogireply.version = EDIF_VERSION1;
        switch (appplogiok.type) {
        case PL_TYPE_WWPN:
                fcport = qla2x00_find_fcport_by_wwpn(vha,
@@ -864,6 +919,8 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
        } else {
                struct fc_port  *fcport = NULL, *tf;
 
+               app_reply->version = EDIF_VERSION1;
+
                list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
                        if (!(fcport->flags & FCF_FCSP_DEVICE))
                                continue;
@@ -880,9 +937,25 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
                        if (tdid.b24 != 0 && tdid.b24 != fcport->d_id.b24)
                                continue;
 
-                       app_reply->ports[pcnt].rekey_count =
-                               fcport->edif.rekey_cnt;
+                       if (!N2N_TOPO(vha->hw)) {
+                               if (fcport->scan_state != QLA_FCPORT_FOUND)
+                                       continue;
+
+                               if (fcport->port_type == FCT_UNKNOWN &&
+                                   !fcport->fc4_features)
+                                       rval = qla24xx_async_gffid(vha, fcport,
+                                                                  true);
 
+                               if (!rval &&
+                                   !(fcport->fc4_features & FC4_FF_TARGET ||
+                                     fcport->port_type &
+                                     (FCT_TARGET | FCT_NVME_TARGET)))
+                                       continue;
+                       }
+
+                       rval = 0;
+
+                       app_reply->ports[pcnt].version = EDIF_VERSION1;
                        app_reply->ports[pcnt].remote_type =
                                VND_CMD_RTYPE_UNKNOWN;
                        if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET))
@@ -979,6 +1052,8 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
        } else {
                struct fc_port  *fcport = NULL, *tf;
 
+               app_reply->version = EDIF_VERSION1;
+
                list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
                        if (fcport->edif.enable) {
                                if (pcnt > app_req.num_ports)
@@ -1012,6 +1087,164 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
        return rval;
 }
 
+static int32_t
+qla_edif_ack(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+{
+       struct fc_port *fcport;
+       struct aen_complete_cmd ack;
+       struct fc_bsg_reply     *bsg_reply = bsg_job->reply;
+
+       sg_copy_to_buffer(bsg_job->request_payload.sg_list,
+                         bsg_job->request_payload.sg_cnt, &ack, sizeof(ack));
+
+       ql_dbg(ql_dbg_edif, vha, 0x70cf,
+              "%s: %06x event_code %x\n",
+              __func__, ack.port_id.b24, ack.event_code);
+
+       fcport = qla2x00_find_fcport_by_pid(vha, &ack.port_id);
+       SET_DID_STATUS(bsg_reply->result, DID_OK);
+
+       if (!fcport) {
+               ql_dbg(ql_dbg_edif, vha, 0x70cf,
+                      "%s: unable to find fcport %06x \n",
+                      __func__, ack.port_id.b24);
+               return 0;
+       }
+
+       switch (ack.event_code) {
+       case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
+               fcport->edif.sess_down_acked = 1;
+               break;
+       default:
+               break;
+       }
+       return 0;
+}
+
+static int qla_edif_consume_dbell(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+{
+       struct fc_bsg_reply     *bsg_reply = bsg_job->reply;
+       u32 sg_skip, reply_payload_len;
+       bool keep;
+       struct edb_node *dbnode = NULL;
+       struct edif_app_dbell ap;
+       int dat_size = 0;
+
+       sg_skip = 0;
+       reply_payload_len = bsg_job->reply_payload.payload_len;
+
+       while ((reply_payload_len - sg_skip) >= sizeof(struct edb_node)) {
+               dbnode = qla_edb_getnext(vha);
+               if (dbnode) {
+                       keep = true;
+                       dat_size = 0;
+                       ap.event_code = dbnode->ntype;
+                       switch (dbnode->ntype) {
+                       case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
+                       case VND_CMD_AUTH_STATE_NEEDED:
+                               ap.port_id = dbnode->u.plogi_did;
+                               dat_size += sizeof(ap.port_id);
+                               break;
+                       case VND_CMD_AUTH_STATE_ELS_RCVD:
+                               ap.port_id = dbnode->u.els_sid;
+                               dat_size += sizeof(ap.port_id);
+                               break;
+                       case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
+                               ap.port_id = dbnode->u.sa_aen.port_id;
+                               memcpy(&ap.event_data, &dbnode->u,
+                                   sizeof(struct edif_sa_update_aen));
+                               dat_size += sizeof(struct edif_sa_update_aen);
+                               break;
+                       default:
+                               keep = false;
+                               ql_log(ql_log_warn, vha, 0x09102,
+                                       "%s unknown DB type=%d %p\n",
+                                       __func__, dbnode->ntype, dbnode);
+                               break;
+                       }
+                       ap.event_data_size = dat_size;
+                       /* 8 = sizeof(ap.event_code + ap.event_data_size) */
+                       dat_size += 8;
+                       if (keep)
+                               sg_skip += sg_copy_buffer(bsg_job->reply_payload.sg_list,
+                                               bsg_job->reply_payload.sg_cnt,
+                                               &ap, dat_size, sg_skip, false);
+
+                       ql_dbg(ql_dbg_edif, vha, 0x09102,
+                               "%s Doorbell consumed : type=%d %p\n",
+                               __func__, dbnode->ntype, dbnode);
+
+                       kfree(dbnode);
+               } else {
+                       break;
+               }
+       }
+
+       SET_DID_STATUS(bsg_reply->result, DID_OK);
+       bsg_reply->reply_payload_rcv_len = sg_skip;
+       bsg_job->reply_len = sizeof(struct fc_bsg_reply);
+
+       return 0;
+}
+
+static void __qla_edif_dbell_bsg_done(scsi_qla_host_t *vha, struct bsg_job *bsg_job,
+       u32 delay)
+{
+       struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+
+       /* small sleep for doorbell events to accumulate */
+       if (delay)
+               msleep(delay);
+
+       qla_edif_consume_dbell(vha, bsg_job);
+
+       bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len);
+}
+
+static void qla_edif_dbell_bsg_done(scsi_qla_host_t *vha)
+{
+       unsigned long flags;
+       struct bsg_job *prev_bsg_job = NULL;
+
+       spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
+       if (vha->e_dbell.dbell_bsg_job) {
+               prev_bsg_job = vha->e_dbell.dbell_bsg_job;
+               vha->e_dbell.dbell_bsg_job = NULL;
+       }
+       spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
+
+       if (prev_bsg_job)
+               __qla_edif_dbell_bsg_done(vha, prev_bsg_job, 0);
+}
+
+static int
+qla_edif_dbell_bsg(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+{
+       unsigned long flags;
+       bool return_bsg = false;
+
+       /* flush previous dbell bsg */
+       qla_edif_dbell_bsg_done(vha);
+
+       spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
+       if (list_empty(&vha->e_dbell.head) && DBELL_ACTIVE(vha)) {
+               /*
+                * when the next db event happens, bsg_job will return.
+                * Otherwise, timer will return it.
+                */
+               vha->e_dbell.dbell_bsg_job = bsg_job;
+               vha->e_dbell.bsg_expire = jiffies + 10 * HZ;
+       } else {
+               return_bsg = true;
+       }
+       spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
+
+       if (return_bsg)
+               __qla_edif_dbell_bsg_done(vha, bsg_job, 1);
+
+       return 0;
+}
+
 int32_t
 qla_edif_app_mgmt(struct bsg_job *bsg_job)
 {
@@ -1023,8 +1256,13 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
        bool done = true;
        int32_t         rval = 0;
        uint32_t        vnd_sc = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
+       u32 level = ql_dbg_edif;
+
+       /* doorbell is high traffic */
+       if (vnd_sc == QL_VND_SC_READ_DBELL)
+               level = 0;
 
-       ql_dbg(ql_dbg_edif, vha, 0x911d, "%s vnd subcmd=%x\n",
+       ql_dbg(level, vha, 0x911d, "%s vnd subcmd=%x\n",
            __func__, vnd_sc);
 
        sg_copy_to_buffer(bsg_job->request_payload.sg_list,
@@ -1033,7 +1271,7 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
 
        if (!vha->hw->flags.edif_enabled ||
                test_bit(VPORT_DELETE, &vha->dpc_flags)) {
-               ql_dbg(ql_dbg_edif, vha, 0x911d,
+               ql_dbg(level, vha, 0x911d,
                    "%s edif not enabled or vp delete. bsg ptr done %p. dpc_flags %lx\n",
                    __func__, bsg_job, vha->dpc_flags);
 
@@ -1042,7 +1280,7 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
        }
 
        if (!qla_edif_app_check(vha, appcheck)) {
-               ql_dbg(ql_dbg_edif, vha, 0x911d,
+               ql_dbg(level, vha, 0x911d,
                    "%s app checked failed.\n",
                    __func__);
 
@@ -1074,6 +1312,13 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
        case QL_VND_SC_GET_STATS:
                rval = qla_edif_app_getstats(vha, bsg_job);
                break;
+       case QL_VND_SC_AEN_COMPLETE:
+               rval = qla_edif_ack(vha, bsg_job);
+               break;
+       case QL_VND_SC_READ_DBELL:
+               rval = qla_edif_dbell_bsg(vha, bsg_job);
+               done = false;
+               break;
        default:
                ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n",
                    __func__,
@@ -1085,7 +1330,7 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
 
 done:
        if (done) {
-               ql_dbg(ql_dbg_user, vha, 0x7009,
+               ql_dbg(level, vha, 0x7009,
                    "%s: %d  bsg ptr done %p\n", __func__, __LINE__, bsg_job);
                bsg_job_done(bsg_job, bsg_reply->result,
                    bsg_reply->reply_payload_rcv_len);
@@ -1247,6 +1492,8 @@ qla24xx_check_sadb_avail_slot(struct bsg_job *bsg_job, fc_port_t *fcport,
 
 #define QLA_SA_UPDATE_FLAGS_RX_KEY      0x0
 #define QLA_SA_UPDATE_FLAGS_TX_KEY      0x2
+#define EDIF_MSLEEP_INTERVAL 100
+#define EDIF_RETRY_COUNT  50
 
 int
 qla24xx_sadb_update(struct bsg_job *bsg_job)
@@ -1259,7 +1506,7 @@ qla24xx_sadb_update(struct bsg_job *bsg_job)
        struct edif_list_entry *edif_entry = NULL;
        int                     found = 0;
        int                     rval = 0;
-       int result = 0;
+       int result = 0, cnt;
        struct qla_sa_update_frame sa_frame;
        struct srb_iocb *iocb_cmd;
        port_id_t portid;
@@ -1500,11 +1747,23 @@ force_rx_delete:
        sp->done = qla2x00_bsg_job_done;
        iocb_cmd = &sp->u.iocb_cmd;
        iocb_cmd->u.sa_update.sa_frame  = sa_frame;
-
+       cnt = 0;
+retry:
        rval = qla2x00_start_sp(sp);
-       if (rval != QLA_SUCCESS) {
+       switch (rval) {
+       case QLA_SUCCESS:
+               break;
+       case EAGAIN:
+               msleep(EDIF_MSLEEP_INTERVAL);
+               cnt++;
+               if (cnt < EDIF_RETRY_COUNT)
+                       goto retry;
+
+               fallthrough;
+       default:
                ql_log(ql_dbg_edif, vha, 0x70e3,
-                   "qla2x00_start_sp failed=%d.\n", rval);
+                      "%s qla2x00_start_sp failed=%d.\n",
+                      __func__, rval);
 
                qla2x00_rel_sp(sp);
                rval = -EIO;
@@ -1797,30 +2056,6 @@ qla_edb_init(scsi_qla_host_t *vha)
        /* initialize lock which protects doorbell & init list */
        spin_lock_init(&vha->e_dbell.db_lock);
        INIT_LIST_HEAD(&vha->e_dbell.head);
-
-       /* create and initialize doorbell */
-       init_completion(&vha->e_dbell.dbell);
-}
-
-static void
-qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node)
-{
-       /*
-        * releases the space held by this edb node entry
-        * this function does _not_ free the edb node itself
-        * NB: the edb node entry passed should not be on any list
-        *
-        * currently for doorbell there's no additional cleanup
-        * needed, but here as a placeholder for furture use.
-        */
-
-       if (!node) {
-               ql_dbg(ql_dbg_edif, vha, 0x09122,
-                   "%s error - no valid node passed\n", __func__);
-               return;
-       }
-
-       node->ntype = N_UNDEF;
 }
 
 static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid)
@@ -1867,11 +2102,8 @@ static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid)
        }
        spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
 
-       list_for_each_entry_safe(e, tmp, &edb_list, list) {
+       list_for_each_entry_safe(e, tmp, &edb_list, list)
                qla_edb_node_free(vha, e);
-               list_del_init(&e->list);
-               kfree(e);
-       }
 }
 
 /* function called when app is stopping */
@@ -1899,14 +2131,10 @@ qla_edb_stop(scsi_qla_host_t *vha)
                    "%s freeing edb_node type=%x\n",
                    __func__, node->ntype);
                qla_edb_node_free(vha, node);
-               list_del(&node->list);
-
-               kfree(node);
        }
        spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
 
-       /* wake up doorbell waiters - they'll be dismissed with error code */
-       complete_all(&vha->e_dbell.dbell);
+       qla_edif_dbell_bsg_done(vha);
 }
 
 static struct edb_node *
@@ -1944,9 +2172,6 @@ qla_edb_node_add(scsi_qla_host_t *vha, struct edb_node *ptr)
        list_add_tail(&ptr->list, &vha->e_dbell.head);
        spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
 
-       /* ring doorbell for waiters */
-       complete(&vha->e_dbell.dbell);
-
        return true;
 }
 
@@ -2010,47 +2235,29 @@ qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype,
                edbnode->u.sa_aen.port_id = fcport->d_id;
                edbnode->u.sa_aen.status =  data;
                edbnode->u.sa_aen.key_type =  data2;
+               edbnode->u.sa_aen.version = EDIF_VERSION1;
                break;
        default:
                ql_dbg(ql_dbg_edif, vha, 0x09102,
                        "%s unknown type: %x\n", __func__, dbtype);
-               qla_edb_node_free(vha, edbnode);
                kfree(edbnode);
                edbnode = NULL;
                break;
        }
 
-       if (edbnode && (!qla_edb_node_add(vha, edbnode))) {
+       if (edbnode) {
+               if (!qla_edb_node_add(vha, edbnode)) {
+                       ql_dbg(ql_dbg_edif, vha, 0x09102,
+                           "%s unable to add dbnode\n", __func__);
+                       kfree(edbnode);
+                       return;
+               }
                ql_dbg(ql_dbg_edif, vha, 0x09102,
-                   "%s unable to add dbnode\n", __func__);
-               qla_edb_node_free(vha, edbnode);
-               kfree(edbnode);
-               return;
-       }
-       if (edbnode && fcport)
-               fcport->edif.auth_state = dbtype;
-       ql_dbg(ql_dbg_edif, vha, 0x09102,
-           "%s Doorbell produced : type=%d %p\n", __func__, dbtype, edbnode);
-}
-
-static struct edb_node *
-qla_edb_getnext(scsi_qla_host_t *vha)
-{
-       unsigned long   flags;
-       struct edb_node *edbnode = NULL;
-
-       spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
-
-       /* db nodes are fifo - no qualifications done */
-       if (!list_empty(&vha->e_dbell.head)) {
-               edbnode = list_first_entry(&vha->e_dbell.head,
-                   struct edb_node, list);
-               list_del(&edbnode->list);
+                   "%s Doorbell produced : type=%d %p\n", __func__, dbtype, edbnode);
+               qla_edif_dbell_bsg_done(vha);
+               if (fcport)
+                       fcport->edif.auth_state = dbtype;
        }
-
-       spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
-
-       return edbnode;
 }
 
 void
@@ -2078,89 +2285,14 @@ qla_edif_timer(scsi_qla_host_t *vha)
                        ha->edif_post_stop_cnt_down = 60;
                }
        }
-}
 
-/*
- * app uses separate thread to read this. It'll wait until the doorbell
- * is rung by the driver or the max wait time has expired
- */
-ssize_t
-edif_doorbell_show(struct device *dev, struct device_attribute *attr,
-               char *buf)
-{
-       scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
-       struct edb_node *dbnode = NULL;
-       struct edif_app_dbell *ap = (struct edif_app_dbell *)buf;
-       uint32_t dat_siz, buf_size, sz;
-
-       /* TODO: app currently hardcoded to 256. Will transition to bsg */
-       sz = 256;
-
-       /* stop new threads from waiting if we're not init'd */
-       if (DBELL_INACTIVE(vha)) {
-               ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x09122,
-                   "%s error - edif db not enabled\n", __func__);
-               return 0;
-       }
-
-       if (!vha->hw->flags.edif_enabled) {
-               /* edif not enabled */
-               ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x09122,
-                   "%s error - edif not enabled\n", __func__);
-               return -1;
-       }
-
-       buf_size = 0;
-       while ((sz - buf_size) >= sizeof(struct edb_node)) {
-               /* remove the next item from the doorbell list */
-               dat_siz = 0;
-               dbnode = qla_edb_getnext(vha);
-               if (dbnode) {
-                       ap->event_code = dbnode->ntype;
-                       switch (dbnode->ntype) {
-                       case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
-                       case VND_CMD_AUTH_STATE_NEEDED:
-                               ap->port_id = dbnode->u.plogi_did;
-                               dat_siz += sizeof(ap->port_id);
-                               break;
-                       case VND_CMD_AUTH_STATE_ELS_RCVD:
-                               ap->port_id = dbnode->u.els_sid;
-                               dat_siz += sizeof(ap->port_id);
-                               break;
-                       case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
-                               ap->port_id = dbnode->u.sa_aen.port_id;
-                               memcpy(ap->event_data, &dbnode->u,
-                                               sizeof(struct edif_sa_update_aen));
-                               dat_siz += sizeof(struct edif_sa_update_aen);
-                               break;
-                       default:
-                               /* unknown node type, rtn unknown ntype */
-                               ap->event_code = VND_CMD_AUTH_STATE_UNDEF;
-                               memcpy(ap->event_data, &dbnode->ntype, 4);
-                               dat_siz += 4;
-                               break;
-                       }
-
-                       ql_dbg(ql_dbg_edif, vha, 0x09102,
-                               "%s Doorbell consumed : type=%d %p\n",
-                               __func__, dbnode->ntype, dbnode);
-                       /* we're done with the db node, so free it up */
-                       qla_edb_node_free(vha, dbnode);
-                       kfree(dbnode);
-               } else {
-                       break;
-               }
-
-               ap->event_data_size = dat_siz;
-               /* 8bytes = ap->event_code + ap->event_data_size */
-               buf_size += dat_siz + 8;
-               ap = (struct edif_app_dbell *)(buf + buf_size);
-       }
-       return buf_size;
+       if (vha->e_dbell.dbell_bsg_job && time_after_eq(jiffies, vha->e_dbell.bsg_expire))
+               qla_edif_dbell_bsg_done(vha);
 }
 
 static void qla_noop_sp_done(srb_t *sp, int res)
 {
+       sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
        /* ref: INIT */
        kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
@@ -2185,7 +2317,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
        if (!sa_ctl) {
                ql_dbg(ql_dbg_edif, vha, 0x70e6,
                    "sa_ctl allocation failed\n");
-               return -ENOMEM;
+               rval =  -ENOMEM;
+               goto done;
        }
 
        fcport = sa_ctl->fcport;
@@ -2195,7 +2328,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
        if (!sp) {
                ql_dbg(ql_dbg_edif, vha, 0x70e6,
                 "SRB allocation failed\n");
-               return -ENOMEM;
+               rval = -ENOMEM;
+               goto done;
        }
 
        fcport->flags |= FCF_ASYNC_SENT;
@@ -2224,10 +2358,17 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
 
        rval = qla2x00_start_sp(sp);
 
-       if (rval != QLA_SUCCESS)
-               rval = QLA_FUNCTION_FAILED;
+       if (rval != QLA_SUCCESS) {
+               goto done_free_sp;
+       }
 
        return rval;
+done_free_sp:
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
+       fcport->flags &= ~FCF_ASYNC_SENT;
+done:
+       fcport->flags &= ~FCF_ASYNC_ACTIVE;
+       return rval;
 }
 
 void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb)
@@ -2446,8 +2587,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
 
        fcport = qla2x00_find_fcport_by_pid(host, &purex->pur_info.pur_sid);
 
-       if (DBELL_INACTIVE(vha) ||
-           (fcport && EDIF_SESSION_DOWN(fcport))) {
+       if (DBELL_INACTIVE(vha)) {
                ql_dbg(ql_dbg_edif, host, 0x0910c, "%s e_dbell.db_flags =%x %06x\n",
                    __func__, host->e_dbell.db_flags,
                    fcport ? fcport->d_id.b24 : 0);
@@ -2457,6 +2597,22 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
                return;
        }
 
+       if (fcport && EDIF_SESSION_DOWN(fcport)) {
+               ql_dbg(ql_dbg_edif, host, 0x13b6,
+                   "%s terminate exchange. Send logo to 0x%x\n",
+                   __func__, a.did.b24);
+
+               a.tx_byte_count = a.tx_len = 0;
+               a.tx_addr = 0;
+               a.control_flags = EPD_RX_XCHG;  /* EPD_RX_XCHG = terminate cmd */
+               qla_els_reject_iocb(host, (*rsp)->qpair, &a);
+               qla_enode_free(host, ptr);
+               /* send logo to let remote port knows to tear down session */
+               fcport->send_els_logo = 1;
+               qlt_schedule_sess_for_deletion(fcport);
+               return;
+       }
+
        /* add the local enode to the list */
        qla_enode_add(host, ptr);
 
@@ -2832,6 +2988,12 @@ qla28xx_start_scsi_edif(srb_t *sp)
 
        tot_dsds = nseg;
        req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
+
+       sp->iores.res_type = RESOURCE_INI;
+       sp->iores.iocb_cnt = req_cnt;
+       if (qla_get_iocbs(sp->qpair, &sp->iores))
+               goto queuing_error;
+
        if (req->cnt < (req_cnt + 2)) {
                cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
                    rd_reg_dword(req->req_q_out);
@@ -3023,6 +3185,7 @@ queuing_error:
                mempool_free(sp->u.scmd.ct6_ctx, ha->ctx_mempool);
                sp->u.scmd.ct6_ctx = NULL;
        }
+       qla_put_iocbs(sp->qpair, &sp->iores);
        spin_unlock_irqrestore(lock, flags);
 
        return QLA_FUNCTION_FAILED;
@@ -3349,10 +3512,14 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
        fc_port_t *fcport = NULL;
        struct qla_hw_data *ha = vha->hw;
        srb_t *sp;
-       int rval =  (DID_ERROR << 16);
+       int rval =  (DID_ERROR << 16), cnt;
        port_id_t d_id;
        struct qla_bsg_auth_els_request *p =
            (struct qla_bsg_auth_els_request *)bsg_job->request;
+       struct qla_bsg_auth_els_reply *rpl =
+           (struct qla_bsg_auth_els_reply *)bsg_job->reply;
+
+       rpl->version = EDIF_VERSION1;
 
        d_id.b.al_pa = bsg_request->rqst_data.h_els.port_id[2];
        d_id.b.area = bsg_request->rqst_data.h_els.port_id[1];
@@ -3371,7 +3538,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
        if (qla_bsg_check(vha, bsg_job, fcport))
                return 0;
 
-       if (fcport->loop_id == FC_NO_LOOP_ID) {
+       if (EDIF_SESS_DELETE(fcport)) {
                ql_dbg(ql_dbg_edif, vha, 0x910d,
                    "%s ELS code %x, no loop id.\n", __func__,
                    bsg_request->rqst_data.r_els.els_code);
@@ -3440,17 +3607,26 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
        sp->free = qla2x00_bsg_sp_free;
        sp->done = qla2x00_bsg_job_done;
 
+       cnt = 0;
+retry:
        rval = qla2x00_start_sp(sp);
-
-       ql_dbg(ql_dbg_edif, vha, 0x700a,
-           "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n",
-           __func__, sc_to_str(p->e.sub_cmd), fcport->port_name,
-           p->e.extra_rx_xchg_address, p->e.extra_control_flags,
-           sp->handle, sp->remap.req.len, bsg_job);
-
-       if (rval != QLA_SUCCESS) {
+       switch (rval) {
+       case QLA_SUCCESS:
+               ql_dbg(ql_dbg_edif, vha, 0x700a,
+                      "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n",
+                      __func__, sc_to_str(p->e.sub_cmd), fcport->port_name,
+                      p->e.extra_rx_xchg_address, p->e.extra_control_flags,
+                      sp->handle, sp->remap.req.len, bsg_job);
+               break;
+       case EAGAIN:
+               msleep(EDIF_MSLEEP_INTERVAL);
+               cnt++;
+               if (cnt < EDIF_RETRY_COUNT)
+                       goto retry;
+               fallthrough;
+       default:
                ql_log(ql_log_warn, vha, 0x700e,
-                   "qla2x00_start_sp failed = %d\n", rval);
+                   "%s qla2x00_start_sp failed = %d\n", __func__, rval);
                SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
                rval = -EIO;
                goto done_free_remap_rsp;
@@ -3472,14 +3648,29 @@ done:
 
 void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess)
 {
+       u16 cnt = 0;
+
        if (sess->edif.app_sess_online && DBELL_ACTIVE(vha)) {
                ql_dbg(ql_dbg_disc, vha, 0xf09c,
                        "%s: sess %8phN send port_offline event\n",
                        __func__, sess->port_name);
                sess->edif.app_sess_online = 0;
+               sess->edif.sess_down_acked = 0;
                qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SESSION_SHUTDOWN,
                    sess->d_id.b24, 0, sess);
                qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24);
+
+               while (!READ_ONCE(sess->edif.sess_down_acked) &&
+                      !test_bit(VPORT_DELETE, &vha->dpc_flags)) {
+                       msleep(100);
+                       cnt++;
+                       if (cnt > 100)
+                               break;
+               }
+               sess->edif.sess_down_acked = 0;
+               ql_dbg(ql_dbg_disc, vha, 0xf09c,
+                      "%s: sess %8phN port_offline event completed\n",
+                      __func__, sess->port_name);
        }
 }
 
index a965ca8..7cdb89c 100644 (file)
@@ -51,7 +51,8 @@ struct edif_dbell {
        enum db_flags_t         db_flags;
        spinlock_t              db_lock;
        struct  list_head       head;
-       struct  completion      dbell;
+       struct bsg_job *dbell_bsg_job;
+       unsigned long bsg_expire;
 };
 
 #define SA_UPDATE_IOCB_TYPE            0x71    /* Security Association Update IOCB entry */
@@ -140,4 +141,8 @@ struct enode {
        (DBELL_ACTIVE(_fcport->vha) && \
         (_fcport->disc_state == DSC_LOGIN_AUTH_PEND))
 
+#define EDIF_SESS_DELETE(_s) \
+       (qla_ini_mode_enabled(_s->vha) && (_s->disc_state == DSC_DELETE_PEND || \
+        _s->disc_state == DSC_DELETED))
+
 #endif /* __QLA_EDIF_H */
index 5a26c77..0931f4e 100644 (file)
@@ -7,13 +7,15 @@
 #ifndef __QLA_EDIF_BSG_H
 #define __QLA_EDIF_BSG_H
 
+#define EDIF_VERSION1 1
+
 /* BSG Vendor specific commands */
 #define        ELS_MAX_PAYLOAD         2112
 #ifndef        WWN_SIZE
 #define WWN_SIZE               8
 #endif
-#define        VND_CMD_APP_RESERVED_SIZE       32
-
+#define VND_CMD_APP_RESERVED_SIZE      28
+#define VND_CMD_PAD_SIZE                3
 enum auth_els_sub_cmd {
        SEND_ELS = 0,
        SEND_ELS_REPLY,
@@ -28,7 +30,9 @@ struct extra_auth_els {
 #define BSG_CTL_FLAG_LS_ACC     1
 #define BSG_CTL_FLAG_LS_RJT     2
 #define BSG_CTL_FLAG_TRM        3
-       uint8_t         extra_rsvd[3];
+       uint8_t         version;
+       uint8_t         pad[2];
+       uint8_t         reserved[VND_CMD_APP_RESERVED_SIZE];
 } __packed;
 
 struct qla_bsg_auth_els_request {
@@ -39,51 +43,46 @@ struct qla_bsg_auth_els_request {
 struct qla_bsg_auth_els_reply {
        struct fc_bsg_reply r;
        uint32_t rx_xchg_address;
+       uint8_t version;
+       uint8_t pad[VND_CMD_PAD_SIZE];
+       uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
 };
 
 struct app_id {
        int             app_vid;
-       uint8_t         app_key[32];
+       uint8_t         version;
+       uint8_t         pad[VND_CMD_PAD_SIZE];
+       uint8_t         reserved[VND_CMD_APP_RESERVED_SIZE];
 } __packed;
 
 struct app_start_reply {
        uint32_t        host_support_edif;
        uint32_t        edif_enode_active;
        uint32_t        edif_edb_active;
-       uint32_t        reserved[VND_CMD_APP_RESERVED_SIZE];
+       uint8_t         version;
+       uint8_t         pad[VND_CMD_PAD_SIZE];
+       uint8_t         reserved[VND_CMD_APP_RESERVED_SIZE];
 } __packed;
 
 struct app_start {
        struct app_id   app_info;
-       uint32_t        prli_to;
-       uint32_t        key_shred;
        uint8_t         app_start_flags;
-       uint8_t         reserved[VND_CMD_APP_RESERVED_SIZE - 1];
+       uint8_t         version;
+       uint8_t         pad[2];
+       uint8_t         reserved[VND_CMD_APP_RESERVED_SIZE];
 } __packed;
 
 struct app_stop {
        struct app_id   app_info;
-       char            buf[16];
+       uint8_t         version;
+       uint8_t         pad[VND_CMD_PAD_SIZE];
+       uint8_t         reserved[VND_CMD_APP_RESERVED_SIZE];
 } __packed;
 
 struct app_plogi_reply {
        uint32_t        prli_status;
-       uint8_t         reserved[VND_CMD_APP_RESERVED_SIZE];
-} __packed;
-
-#define        RECFG_TIME      1
-#define        RECFG_BYTES     2
-
-struct app_rekey_cfg {
-       struct app_id app_info;
-       uint8_t  rekey_mode;
-       port_id_t d_id;
-       uint8_t  force;
-       union {
-               int64_t bytes;
-               int64_t time;
-       } rky_units;
-
+       uint8_t         version;
+       uint8_t         pad[VND_CMD_PAD_SIZE];
        uint8_t         reserved[VND_CMD_APP_RESERVED_SIZE];
 } __packed;
 
@@ -91,7 +90,9 @@ struct app_pinfo_req {
        struct app_id app_info;
        uint8_t  num_ports;
        port_id_t remote_pid;
-       uint8_t  reserved[VND_CMD_APP_RESERVED_SIZE];
+       uint8_t         version;
+       uint8_t         pad[VND_CMD_PAD_SIZE];
+       uint8_t         reserved[VND_CMD_APP_RESERVED_SIZE];
 } __packed;
 
 struct app_pinfo {
@@ -103,11 +104,8 @@ struct app_pinfo {
 #define        VND_CMD_RTYPE_INITIATOR         2
        uint8_t remote_state;
        uint8_t auth_state;
-       uint8_t rekey_mode;
-       int64_t rekey_count;
-       int64_t rekey_config_value;
-       int64_t rekey_consumed_value;
-
+       uint8_t version;
+       uint8_t pad[VND_CMD_PAD_SIZE];
        uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
 } __packed;
 
@@ -120,6 +118,8 @@ struct app_pinfo {
 
 struct app_pinfo_reply {
        uint8_t         port_count;
+       uint8_t         version;
+       uint8_t         pad[VND_CMD_PAD_SIZE];
        uint8_t         reserved[VND_CMD_APP_RESERVED_SIZE];
        struct app_pinfo ports[];
 } __packed;
@@ -127,6 +127,8 @@ struct app_pinfo_reply {
 struct app_sinfo_req {
        struct app_id   app_info;
        uint8_t         num_ports;
+       uint8_t         version;
+       uint8_t         pad[VND_CMD_PAD_SIZE];
        uint8_t         reserved[VND_CMD_APP_RESERVED_SIZE];
 } __packed;
 
@@ -140,6 +142,9 @@ struct app_sinfo {
 
 struct app_stats_reply {
        uint8_t         elem_count;
+       uint8_t         version;
+       uint8_t         pad[VND_CMD_PAD_SIZE];
+       uint8_t         reserved[VND_CMD_APP_RESERVED_SIZE];
        struct app_sinfo elem[];
 } __packed;
 
@@ -163,9 +168,11 @@ struct qla_sa_update_frame {
        uint8_t         node_name[WWN_SIZE];
        uint8_t         port_name[WWN_SIZE];
        port_id_t       port_id;
+       uint8_t         version;
+       uint8_t         pad[VND_CMD_PAD_SIZE];
+       uint8_t         reserved2[VND_CMD_APP_RESERVED_SIZE];
 } __packed;
 
-// used for edif mgmt bsg interface
 #define        QL_VND_SC_UNDEF         0
 #define        QL_VND_SC_SA_UPDATE     1
 #define        QL_VND_SC_APP_START     2
@@ -175,6 +182,22 @@ struct qla_sa_update_frame {
 #define        QL_VND_SC_REKEY_CONFIG  6
 #define        QL_VND_SC_GET_FCINFO    7
 #define        QL_VND_SC_GET_STATS     8
+#define QL_VND_SC_AEN_COMPLETE  9
+#define QL_VND_SC_READ_DBELL   10
+
+/*
+ * bsg caller to provide empty buffer for doorbell events.
+ *
+ * sg_io_v4.din_xferp  = empty buffer for door bell events
+ * sg_io_v4.dout_xferp = struct edif_read_dbell *buf
+ */
+struct edif_read_dbell {
+       struct app_id app_info;
+       uint8_t version;
+       uint8_t pad[VND_CMD_PAD_SIZE];
+       uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+};
+
 
 /* Application interface data structure for rtn data */
 #define        EXT_DEF_EVENT_DATA_SIZE 64
@@ -191,7 +214,9 @@ struct edif_sa_update_aen {
        port_id_t port_id;
        uint32_t key_type;      /* Tx (1) or RX (2) */
        uint32_t status;        /* 0 succes,  1 failed, 2 timeout , 3 error */
-       uint8_t         reserved[16];
+       uint8_t version;
+       uint8_t pad[VND_CMD_PAD_SIZE];
+       uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
 } __packed;
 
 #define        QL_VND_SA_STAT_SUCCESS  0
@@ -212,9 +237,22 @@ struct auth_complete_cmd {
                uint8_t  wwpn[WWN_SIZE];
                port_id_t d_id;
        } u;
-       uint32_t reserved[VND_CMD_APP_RESERVED_SIZE];
+       uint8_t version;
+       uint8_t pad[VND_CMD_PAD_SIZE];
+       uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+} __packed;
+
+struct aen_complete_cmd {
+       struct app_id app_info;
+       port_id_t   port_id;
+       uint32_t    event_code;
+       uint8_t     version;
+       uint8_t     pad[VND_CMD_PAD_SIZE];
+       uint8_t     reserved[VND_CMD_APP_RESERVED_SIZE];
 } __packed;
 
 #define RX_DELAY_DELETE_TIMEOUT 20
 
+#define FCH_EVT_VENDOR_UNIQUE_VPORT_DOWN  1
+
 #endif /* QLA_EDIF_BSG_H */
index 0bb1d56..361015b 100644 (file)
@@ -807,7 +807,7 @@ struct els_entry_24xx {
 #define EPD_ELS_COMMAND                (0 << 13)
 #define EPD_ELS_ACC            (1 << 13)
 #define EPD_ELS_RJT            (2 << 13)
-#define EPD_RX_XCHG            (3 << 13)
+#define EPD_RX_XCHG            (3 << 13)  /* terminate exchange */
 #define ECF_CLR_PASSTHRU_PEND  BIT_12
 #define ECF_INCL_FRAME_HDR     BIT_11
 #define ECF_SEC_LOGIN          BIT_3
index dac27b5..3674b35 100644 (file)
@@ -335,6 +335,7 @@ extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *);
 extern int qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha,
        struct qla_work_evt *e);
 void qla2x00_sp_release(struct kref *kref);
+void qla2x00_els_dcmd2_iocb_timeout(void *data);
 
 /*
  * Global Function Prototypes in qla_mbx.c source file.
@@ -554,6 +555,10 @@ qla2x00_dump_mctp_data(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t);
 extern int
 qla26xx_dport_diagnostics(scsi_qla_host_t *, void *, uint, uint);
 
+extern int
+qla26xx_dport_diagnostics_v2(scsi_qla_host_t *,
+                            struct qla_dport_diag_v2 *,  mbx_cmd_t *);
+
 int qla24xx_send_mb_cmd(struct scsi_qla_host *, mbx_cmd_t *);
 int qla24xx_gpdb_wait(struct scsi_qla_host *, fc_port_t *, u8);
 int qla24xx_gidlist_wait(struct scsi_qla_host *, void *, dma_addr_t,
@@ -727,7 +732,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *);
 void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *);
 int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
 void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea);
-int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport);
+int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool);
 int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *);
 void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *);
 void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *);
@@ -989,7 +994,6 @@ fc_port_t *qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id);
 void qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype, uint32_t data, uint32_t data2,
                fc_port_t *fcport);
 void qla_edb_stop(scsi_qla_host_t *vha);
-ssize_t edif_doorbell_show(struct device *dev, struct device_attribute *attr, char *buf);
 int32_t qla_edif_app_mgmt(struct bsg_job *bsg_job);
 void qla_enode_init(scsi_qla_host_t *vha);
 void qla_enode_stop(scsi_qla_host_t *vha);
index e811de2..dff06a3 100644 (file)
@@ -3280,19 +3280,12 @@ done:
        return rval;
 }
 
-void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea)
-{
-       fc_port_t *fcport = ea->fcport;
-
-       qla24xx_post_gnl_work(vha, fcport);
-}
 
 void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
 {
        struct scsi_qla_host *vha = sp->vha;
        fc_port_t *fcport = sp->fcport;
        struct ct_sns_rsp *ct_rsp;
-       struct event_arg ea;
        uint8_t fc4_scsi_feat;
        uint8_t fc4_nvme_feat;
 
@@ -3300,10 +3293,10 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
               "Async done-%s res %x ID %x. %8phC\n",
               sp->name, res, fcport->d_id.b24, fcport->port_name);
 
-       fcport->flags &= ~FCF_ASYNC_SENT;
-       ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
+       ct_rsp = sp->u.iocb_cmd.u.ctarg.rsp;
        fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
        fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
+       sp->rc = res;
 
        /*
         * FC-GS-7, 5.2.3.12 FC-4 Features - format
@@ -3324,24 +3317,42 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
                }
        }
 
-       memset(&ea, 0, sizeof(ea));
-       ea.sp = sp;
-       ea.fcport = sp->fcport;
-       ea.rc = res;
+       if (sp->flags & SRB_WAKEUP_ON_COMP) {
+               complete(sp->comp);
+       } else  {
+               if (sp->u.iocb_cmd.u.ctarg.req) {
+                       dma_free_coherent(&vha->hw->pdev->dev,
+                               sp->u.iocb_cmd.u.ctarg.req_allocated_size,
+                               sp->u.iocb_cmd.u.ctarg.req,
+                               sp->u.iocb_cmd.u.ctarg.req_dma);
+                       sp->u.iocb_cmd.u.ctarg.req = NULL;
+               }
 
-       qla24xx_handle_gffid_event(vha, &ea);
-       /* ref: INIT */
-       kref_put(&sp->cmd_kref, qla2x00_sp_release);
+               if (sp->u.iocb_cmd.u.ctarg.rsp) {
+                       dma_free_coherent(&vha->hw->pdev->dev,
+                               sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
+                               sp->u.iocb_cmd.u.ctarg.rsp,
+                               sp->u.iocb_cmd.u.ctarg.rsp_dma);
+                       sp->u.iocb_cmd.u.ctarg.rsp = NULL;
+               }
+
+               /* ref: INIT */
+               kref_put(&sp->cmd_kref, qla2x00_sp_release);
+               /* we should not be here */
+               dump_stack();
+       }
 }
 
 /* Get FC4 Feature with Nport ID. */
-int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
+int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool wait)
 {
        int rval = QLA_FUNCTION_FAILED;
        struct ct_sns_req       *ct_req;
        srb_t *sp;
+       DECLARE_COMPLETION_ONSTACK(comp);
 
-       if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
+       /* this routine does not have handling for no wait */
+       if (!vha->flags.online || !wait)
                return rval;
 
        /* ref: INIT */
@@ -3349,43 +3360,86 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
        if (!sp)
                return rval;
 
-       fcport->flags |= FCF_ASYNC_SENT;
        sp->type = SRB_CT_PTHRU_CMD;
        sp->name = "gffid";
        sp->gen1 = fcport->rscn_gen;
        sp->gen2 = fcport->login_gen;
        qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
                              qla24xx_async_gffid_sp_done);
+       sp->comp = &comp;
+       sp->u.iocb_cmd.timeout = qla2x00_els_dcmd2_iocb_timeout;
+
+       if (wait)
+               sp->flags = SRB_WAKEUP_ON_COMP;
+
+       sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
+       sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
+                               sp->u.iocb_cmd.u.ctarg.req_allocated_size,
+                               &sp->u.iocb_cmd.u.ctarg.req_dma,
+           GFP_KERNEL);
+       if (!sp->u.iocb_cmd.u.ctarg.req) {
+               ql_log(ql_log_warn, vha, 0xd041,
+                      "%s: Failed to allocate ct_sns request.\n",
+                      __func__);
+               goto done_free_sp;
+       }
+
+       sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
+       sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
+                               sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
+                               &sp->u.iocb_cmd.u.ctarg.rsp_dma,
+           GFP_KERNEL);
+       if (!sp->u.iocb_cmd.u.ctarg.rsp) {
+               ql_log(ql_log_warn, vha, 0xd041,
+                      "%s: Failed to allocate ct_sns response.\n",
+                      __func__);
+               goto done_free_sp;
+       }
 
        /* CT_IU preamble  */
-       ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD,
-           GFF_ID_RSP_SIZE);
+       ct_req = qla2x00_prep_ct_req(sp->u.iocb_cmd.u.ctarg.req, GFF_ID_CMD, GFF_ID_RSP_SIZE);
 
        ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain;
        ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area;
        ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa;
 
-       sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
-       sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
-       sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
-       sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
        sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE;
        sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE;
        sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
 
-       ql_dbg(ql_dbg_disc, vha, 0x2132,
-           "Async-%s hdl=%x  %8phC.\n", sp->name,
-           sp->handle, fcport->port_name);
-
        rval = qla2x00_start_sp(sp);
-       if (rval != QLA_SUCCESS)
+
+       if (rval != QLA_SUCCESS) {
+               rval = QLA_FUNCTION_FAILED;
                goto done_free_sp;
+       } else {
+               ql_dbg(ql_dbg_disc, vha, 0x3074,
+                      "Async-%s hdl=%x portid %06x\n",
+                      sp->name, sp->handle, fcport->d_id.b24);
+       }
+
+       wait_for_completion(sp->comp);
+       rval = sp->rc;
 
-       return rval;
 done_free_sp:
+       if (sp->u.iocb_cmd.u.ctarg.req) {
+               dma_free_coherent(&vha->hw->pdev->dev,
+                                 sp->u.iocb_cmd.u.ctarg.req_allocated_size,
+                                 sp->u.iocb_cmd.u.ctarg.req,
+                                 sp->u.iocb_cmd.u.ctarg.req_dma);
+               sp->u.iocb_cmd.u.ctarg.req = NULL;
+       }
+
+       if (sp->u.iocb_cmd.u.ctarg.rsp) {
+               dma_free_coherent(&vha->hw->pdev->dev,
+                                 sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
+                                 sp->u.iocb_cmd.u.ctarg.rsp,
+                                 sp->u.iocb_cmd.u.ctarg.rsp_dma);
+               sp->u.iocb_cmd.u.ctarg.rsp = NULL;
+       }
+
        /* ref: INIT */
        kref_put(&sp->cmd_kref, qla2x00_sp_release);
-       fcport->flags &= ~FCF_ASYNC_SENT;
        return rval;
 }
 
@@ -3578,7 +3632,7 @@ login_logout:
                                do_delete) {
                                if (fcport->loop_id != FC_NO_LOOP_ID) {
                                        if (fcport->flags & FCF_FCP2_DEVICE)
-                                               fcport->logout_on_delete = 0;
+                                               continue;
 
                                        ql_log(ql_log_warn, vha, 0x20f0,
                                               "%s %d %8phC post del sess\n",
index 3f3417a..41ffad6 100644 (file)
@@ -47,6 +47,7 @@ qla2x00_sp_timeout(struct timer_list *t)
 {
        srb_t *sp = from_timer(sp, t, u.iocb_cmd.timer);
        struct srb_iocb *iocb;
+       scsi_qla_host_t *vha = sp->vha;
 
        WARN_ON(irqs_disabled());
        iocb = &sp->u.iocb_cmd;
@@ -54,6 +55,12 @@ qla2x00_sp_timeout(struct timer_list *t)
 
        /* ref: TMR */
        kref_put(&sp->cmd_kref, qla2x00_sp_release);
+
+       if (vha && qla2x00_isp_reg_stat(vha->hw)) {
+               ql_log(ql_log_info, vha, 0x9008,
+                   "PCI/Register disconnect.\n");
+               qla_pci_set_eeh_busy(vha);
+       }
 }
 
 void qla2x00_sp_free(srb_t *sp)
@@ -1480,7 +1487,6 @@ static int        qla_chk_secure_login(scsi_qla_host_t    *vha, fc_port_t *fcport,
                                ql_dbg(ql_dbg_disc, vha, 0x20ef,
                                    "%s %d %8phC EDIF: post DB_AUTH: AUTH needed\n",
                                    __func__, __LINE__, fcport->port_name);
-                               fcport->edif.app_started = 1;
                                fcport->edif.app_sess_online = 1;
 
                                qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_NEEDED,
@@ -1763,8 +1769,16 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
                break;
 
        case DSC_LOGIN_PEND:
-               if (fcport->fw_login_state == DSC_LS_PLOGI_COMP)
+               if (vha->hw->flags.edif_enabled)
+                       break;
+
+               if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
+                       ql_dbg(ql_dbg_disc, vha, 0x2118,
+                              "%s %d %8phC post %s PRLI\n",
+                              __func__, __LINE__, fcport->port_name,
+                              NVME_TARGET(vha->hw, fcport) ? "NVME" : "FC");
                        qla24xx_post_prli_work(vha, fcport);
+               }
                break;
 
        case DSC_UPD_FCPORT:
@@ -1818,7 +1832,8 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
        case RSCN_PORT_ADDR:
                fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
                if (fcport) {
-                       if (fcport->flags & FCF_FCP2_DEVICE) {
+                       if (fcport->flags & FCF_FCP2_DEVICE &&
+                           atomic_read(&fcport->state) == FCS_ONLINE) {
                                ql_dbg(ql_dbg_disc, vha, 0x2115,
                                       "Delaying session delete for FCP2 portid=%06x %8phC ",
                                        fcport->d_id.b24, fcport->port_name);
@@ -1850,7 +1865,8 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
                break;
        case RSCN_AREA_ADDR:
                list_for_each_entry(fcport, &vha->vp_fcports, list) {
-                       if (fcport->flags & FCF_FCP2_DEVICE)
+                       if (fcport->flags & FCF_FCP2_DEVICE &&
+                           atomic_read(&fcport->state) == FCS_ONLINE)
                                continue;
 
                        if ((ea->id.b24 & 0xffff00) == (fcport->d_id.b24 & 0xffff00)) {
@@ -1861,7 +1877,8 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
                break;
        case RSCN_DOM_ADDR:
                list_for_each_entry(fcport, &vha->vp_fcports, list) {
-                       if (fcport->flags & FCF_FCP2_DEVICE)
+                       if (fcport->flags & FCF_FCP2_DEVICE &&
+                           atomic_read(&fcport->state) == FCS_ONLINE)
                                continue;
 
                        if ((ea->id.b24 & 0xff0000) == (fcport->d_id.b24 & 0xff0000)) {
@@ -1873,7 +1890,8 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
        case RSCN_FAB_ADDR:
        default:
                list_for_each_entry(fcport, &vha->vp_fcports, list) {
-                       if (fcport->flags & FCF_FCP2_DEVICE)
+                       if (fcport->flags & FCF_FCP2_DEVICE &&
+                           atomic_read(&fcport->state) == FCS_ONLINE)
                                continue;
 
                        fcport->scan_needed = 1;
@@ -2124,6 +2142,13 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
                }
 
                if (N2N_TOPO(vha->hw)) {
+                       if (ea->fcport->n2n_link_reset_cnt ==
+                           vha->hw->login_retry_count &&
+                           ea->fcport->flags & FCF_FCSP_DEVICE) {
+                               /* remote authentication app just started */
+                               ea->fcport->n2n_link_reset_cnt = 0;
+                       }
+
                        if (ea->fcport->n2n_link_reset_cnt <
                            vha->hw->login_retry_count) {
                                ea->fcport->n2n_link_reset_cnt++;
@@ -5273,9 +5298,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
        INIT_LIST_HEAD(&fcport->edif.tx_sa_list);
        INIT_LIST_HEAD(&fcport->edif.rx_sa_list);
 
-       if (vha->e_dbell.db_flags == EDB_ACTIVE)
-               fcport->edif.app_started = 1;
-
        spin_lock_init(&fcport->edif.indx_list_lock);
        INIT_LIST_HEAD(&fcport->edif.edif_indx_list);
 
@@ -7197,6 +7219,9 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
        if (vha->flags.online) {
                qla2x00_abort_isp_cleanup(vha);
 
+               vha->dport_status |= DPORT_DIAG_CHIP_RESET_IN_PROGRESS;
+               vha->dport_status &= ~DPORT_DIAG_IN_PROGRESS;
+
                if (vha->hw->flags.port_isolated)
                        return status;
 
@@ -9657,6 +9682,12 @@ int qla2xxx_disable_port(struct Scsi_Host *host)
 
        vha->hw->flags.port_isolated = 1;
 
+       if (qla2x00_isp_reg_stat(vha->hw)) {
+               ql_log(ql_log_info, vha, 0x9006,
+                   "PCI/Register disconnect, exiting.\n");
+               qla_pci_set_eeh_busy(vha);
+               return FAILED;
+       }
        if (qla2x00_chip_is_down(vha))
                return 0;
 
@@ -9672,6 +9703,13 @@ int qla2xxx_enable_port(struct Scsi_Host *host)
 {
        scsi_qla_host_t *vha = shost_priv(host);
 
+       if (qla2x00_isp_reg_stat(vha->hw)) {
+               ql_log(ql_log_info, vha, 0x9001,
+                   "PCI/Register disconnect, exiting.\n");
+               qla_pci_set_eeh_busy(vha);
+               return FAILED;
+       }
+
        vha->hw->flags.port_isolated = 0;
        /* Set the flag to 1, so that isp_abort can proceed */
        vha->flags.online = 1;
index e0fe9dd..42ce4e1 100644 (file)
@@ -2819,7 +2819,7 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
        sp->vha->qla_stats.control_requests++;
 }
 
-static void
+void
 qla2x00_els_dcmd2_iocb_timeout(void *data)
 {
        srb_t *sp = data;
@@ -2882,6 +2882,9 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
            sp->name, res, sp->handle, fcport->d_id.b24, fcport->port_name);
 
        fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE);
+       /* For edif, set logout on delete to ensure any residual key from FW is flushed.*/
+       fcport->logout_on_delete = 1;
+       fcport->chip_reset = vha->hw->base_qpair->chip_reset;
 
        if (sp->flags & SRB_WAKEUP_ON_COMP)
                complete(&lio->u.els_plogi.comp);
index 21b31d6..24f9a3b 100644 (file)
@@ -1761,6 +1761,9 @@ global_port_update:
                break;
 
        case MBA_DPORT_DIAGNOSTICS:
+               if ((mb[1] & 0xF) == AEN_DONE_DIAG_TEST_WITH_NOERR ||
+                   (mb[1] & 0xF) == AEN_DONE_DIAG_TEST_WITH_ERR)
+                       vha->dport_status &= ~DPORT_DIAG_IN_PROGRESS;
                ql_dbg(ql_dbg_async, vha, 0x5052,
                    "D-Port Diagnostics: %04x %04x %04x %04x\n",
                    mb[0], mb[1], mb[2], mb[3]);
@@ -2245,9 +2248,9 @@ qla24xx_els_ct_entry(scsi_qla_host_t *v, struct req_que *req,
                                res = DID_ERROR << 16;
                        }
 
-                       if (logit) {
-                               if (sp->remap.remapped &&
-                                   ((u8 *)sp->remap.rsp.buf)[0] == ELS_LS_RJT) {
+                       if (sp->remap.remapped &&
+                           ((u8 *)sp->remap.rsp.buf)[0] == ELS_LS_RJT) {
+                               if (logit) {
                                        ql_dbg(ql_dbg_user, vha, 0x503f,
                                            "%s IOCB Done LS_RJT hdl=%x comp_status=0x%x\n",
                                            type, sp->handle, comp_status);
@@ -2259,18 +2262,24 @@ qla24xx_els_ct_entry(scsi_qla_host_t *v, struct req_que *req,
                                                pkt)->total_byte_count),
                                            e->s_id[0], e->s_id[2], e->s_id[1],
                                            e->d_id[2], e->d_id[1], e->d_id[0]);
-                               } else {
-                                       ql_log(ql_log_info, vha, 0x503f,
-                                           "%s IOCB Done hdl=%x comp_status=0x%x\n",
-                                           type, sp->handle, comp_status);
-                                       ql_log(ql_log_info, vha, 0x503f,
-                                           "subcode 1=0x%x subcode 2=0x%x bytes=0x%x %02x%02x%02x -> %02x%02x%02x\n",
-                                           fw_status[1], fw_status[2],
-                                           le32_to_cpu(((struct els_sts_entry_24xx *)
-                                               pkt)->total_byte_count),
-                                           e->s_id[0], e->s_id[2], e->s_id[1],
-                                           e->d_id[2], e->d_id[1], e->d_id[0]);
                                }
+                               if (sp->fcport && sp->fcport->flags & FCF_FCSP_DEVICE &&
+                                   sp->type == SRB_ELS_CMD_HST_NOLOGIN) {
+                                       ql_dbg(ql_dbg_edif, vha, 0x911e,
+                                           "%s rcv reject. Sched delete\n", __func__);
+                                       qlt_schedule_sess_for_deletion(sp->fcport);
+                               }
+                       } else if (logit) {
+                               ql_log(ql_log_info, vha, 0x503f,
+                                   "%s IOCB Done hdl=%x comp_status=0x%x\n",
+                                   type, sp->handle, comp_status);
+                               ql_log(ql_log_info, vha, 0x503f,
+                                   "subcode 1=0x%x subcode 2=0x%x bytes=0x%x %02x%02x%02x -> %02x%02x%02x\n",
+                                   fw_status[1], fw_status[2],
+                                   le32_to_cpu(((struct els_sts_entry_24xx *)
+                                   pkt)->total_byte_count),
+                                   e->s_id[0], e->s_id[2], e->s_id[1],
+                                   e->d_id[2], e->d_id[1], e->d_id[0]);
                        }
                }
                goto els_ct_done;
@@ -2639,7 +2648,7 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
        }
 
        if (unlikely(logit))
-               ql_log(ql_dbg_io, fcport->vha, 0x5060,
+               ql_dbg(ql_dbg_io, fcport->vha, 0x5060,
                   "NVME-%s ERR Handling - hdl=%x status(%x) tr_len:%x resid=%x  ox_id=%x\n",
                   sp->name, sp->handle, comp_status,
                   fd->transferred_length, le32_to_cpu(sts->residual_len),
@@ -3426,6 +3435,7 @@ check_scsi_status:
        case CS_PORT_UNAVAILABLE:
        case CS_TIMEOUT:
        case CS_RESET:
+       case CS_EDIF_INV_REQ:
 
                /*
                 * We are going to have the fc class block the rport
@@ -3496,7 +3506,7 @@ check_scsi_status:
 
 out:
        if (logit)
-               ql_log(ql_dbg_io, fcport->vha, 0x3022,
+               ql_dbg(ql_dbg_io, fcport->vha, 0x3022,
                       "FCP command status: 0x%x-0x%x (0x%x) nexus=%ld:%d:%llu portid=%02x%02x%02x oxid=0x%x cdb=%10phN len=0x%x rsp_info=0x%x resid=0x%x fw_resid=0x%x sp=%p cp=%p.\n",
                       comp_status, scsi_status, res, vha->host_no,
                       cp->device->id, cp->device->lun, fcport->d_id.b.domain,
@@ -4420,16 +4430,12 @@ msix_register_fail:
        }
 
        /* Enable MSI-X vector for response queue update for queue 0 */
-       if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
-               if (ha->msixbase && ha->mqiobase &&
-                   (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 ||
-                    ql2xmqsupport))
-                       ha->mqenable = 1;
-       } else
-               if (ha->mqiobase &&
-                   (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 ||
-                    ql2xmqsupport))
-                       ha->mqenable = 1;
+       if (IS_MQUE_CAPABLE(ha) &&
+           (ha->msixbase && ha->mqiobase && ha->max_qpairs))
+               ha->mqenable = 1;
+       else
+               ha->mqenable = 0;
+
        ql_dbg(ql_dbg_multiq, vha, 0xc005,
            "mqiobase=%p, max_rsp_queues=%d, max_req_queues=%d.\n",
            ha->mqiobase, ha->max_rsp_queues, ha->max_req_queues);
index 892caf2..643fa00 100644 (file)
@@ -274,6 +274,12 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
                atomic_inc(&ha->num_pend_mbx_stage3);
                if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
                    mcp->tov * HZ)) {
+                       ql_dbg(ql_dbg_mbx, vha, 0x117a,
+                           "cmd=%x Timeout.\n", command);
+                       spin_lock_irqsave(&ha->hardware_lock, flags);
+                       clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
+                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
                        if (chip_reset != ha->chip_reset) {
                                eeh_delay = ha->flags.eeh_busy ? 1 : 0;
 
@@ -286,12 +292,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
                                rval = QLA_ABORTED;
                                goto premature_exit;
                        }
-                       ql_dbg(ql_dbg_mbx, vha, 0x117a,
-                           "cmd=%x Timeout.\n", command);
-                       spin_lock_irqsave(&ha->hardware_lock, flags);
-                       clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
-                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
                } else if (ha->flags.purge_mbox ||
                    chip_reset != ha->chip_reset) {
                        eeh_delay = ha->flags.eeh_busy ? 1 : 0;
@@ -6471,6 +6471,54 @@ qla26xx_dport_diagnostics(scsi_qla_host_t *vha,
        return rval;
 }
 
+int
+qla26xx_dport_diagnostics_v2(scsi_qla_host_t *vha,
+                            struct qla_dport_diag_v2 *dd,  mbx_cmd_t *mcp)
+{
+       int rval;
+       dma_addr_t dd_dma;
+       uint size = sizeof(dd->buf);
+       uint16_t options = dd->options;
+
+       ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f,
+              "Entered %s.\n", __func__);
+
+       dd_dma = dma_map_single(&vha->hw->pdev->dev,
+                               dd->buf, size, DMA_FROM_DEVICE);
+       if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) {
+               ql_log(ql_log_warn, vha, 0x1194,
+                      "Failed to map dma buffer.\n");
+               return QLA_MEMORY_ALLOC_FAILED;
+       }
+
+       memset(dd->buf, 0, size);
+
+       mcp->mb[0] = MBC_DPORT_DIAGNOSTICS;
+       mcp->mb[1] = options;
+       mcp->mb[2] = MSW(LSD(dd_dma));
+       mcp->mb[3] = LSW(LSD(dd_dma));
+       mcp->mb[6] = MSW(MSD(dd_dma));
+       mcp->mb[7] = LSW(MSD(dd_dma));
+       mcp->mb[8] = size;
+       mcp->out_mb = MBX_8 | MBX_7 | MBX_6 | MBX_3 | MBX_2 | MBX_1 | MBX_0;
+       mcp->in_mb = MBX_3 | MBX_2 | MBX_1 | MBX_0;
+       mcp->buf_size = size;
+       mcp->flags = MBX_DMA_IN;
+       mcp->tov = MBX_TOV_SECONDS * 4;
+       rval = qla2x00_mailbox_command(vha, mcp);
+
+       if (rval != QLA_SUCCESS) {
+               ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval);
+       } else {
+               ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196,
+                      "Done %s.\n", __func__);
+       }
+
+       dma_unmap_single(&vha->hw->pdev->dev, dd_dma, size, DMA_FROM_DEVICE);
+
+       return rval;
+}
+
 static void qla2x00_async_mb_sp_done(srb_t *sp, int res)
 {
        sp->u.iocb_cmd.u.mbx.rc = res;
index 346d47b..16a9f22 100644 (file)
@@ -166,9 +166,13 @@ qla24xx_disable_vp(scsi_qla_host_t *vha)
        int ret = QLA_SUCCESS;
        fc_port_t *fcport;
 
-       if (vha->hw->flags.edif_enabled)
+       if (vha->hw->flags.edif_enabled) {
+               if (DBELL_ACTIVE(vha))
+                       qla2x00_post_aen_work(vha, FCH_EVT_VENDOR_UNIQUE,
+                           FCH_EVT_VENDOR_UNIQUE_VPORT_DOWN);
                /* delete sessions and flush sa_indexes */
                qla2x00_wait_for_sess_deletion(vha);
+       }
 
        if (vha->hw->flags.fw_started)
                ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
index 73073fb..1c7fb64 100644 (file)
@@ -333,6 +333,11 @@ MODULE_PARM_DESC(ql2xabts_wait_nvme,
                 "To wait for ABTS response on I/O timeouts for NVMe. (default: 1)");
 
 
+u32 ql2xdelay_before_pci_error_handling = 5;
+module_param(ql2xdelay_before_pci_error_handling, uint, 0644);
+MODULE_PARM_DESC(ql2xdelay_before_pci_error_handling,
+       "Number of seconds delayed before qla begin PCI error self-handling (default: 5).\n");
+
 static void qla2x00_clear_drv_active(struct qla_hw_data *);
 static void qla2x00_free_device(scsi_qla_host_t *);
 static int qla2xxx_map_queues(struct Scsi_Host *shost);
@@ -1337,21 +1342,20 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 /*
  * Returns: QLA_SUCCESS or QLA_FUNCTION_FAILED.
  */
-int
-qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
-       uint64_t l, enum nexus_wait_type type)
+static int
+__qla2x00_eh_wait_for_pending_commands(struct qla_qpair *qpair, unsigned int t,
+                                      uint64_t l, enum nexus_wait_type type)
 {
        int cnt, match, status;
        unsigned long flags;
-       struct qla_hw_data *ha = vha->hw;
-       struct req_que *req;
+       scsi_qla_host_t *vha = qpair->vha;
+       struct req_que *req = qpair->req;
        srb_t *sp;
        struct scsi_cmnd *cmd;
 
        status = QLA_SUCCESS;
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       req = vha->req;
+       spin_lock_irqsave(qpair->qp_lock_ptr, flags);
        for (cnt = 1; status == QLA_SUCCESS &&
                cnt < req->num_outstanding_cmds; cnt++) {
                sp = req->outstanding_cmds[cnt];
@@ -1378,15 +1382,35 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
                if (!match)
                        continue;
 
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+               spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
                status = qla2x00_eh_wait_on_command(cmd);
-               spin_lock_irqsave(&ha->hardware_lock, flags);
+               spin_lock_irqsave(qpair->qp_lock_ptr, flags);
        }
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
        return status;
 }
 
+int
+qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
+                                    uint64_t l, enum nexus_wait_type type)
+{
+       struct qla_qpair *qpair;
+       struct qla_hw_data *ha = vha->hw;
+       int i, status = QLA_SUCCESS;
+
+       status = __qla2x00_eh_wait_for_pending_commands(ha->base_qpair, t, l,
+                                                       type);
+       for (i = 0; status == QLA_SUCCESS && i < ha->max_qpairs; i++) {
+               qpair = ha->queue_pair_map[i];
+               if (!qpair)
+                       continue;
+               status = __qla2x00_eh_wait_for_pending_commands(qpair, t, l,
+                                                               type);
+       }
+       return status;
+}
+
 static char *reset_errors[] = {
        "HBA not online",
        "HBA not ready",
@@ -1420,7 +1444,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
                return err;
 
        if (fcport->deleted)
-               return SUCCESS;
+               return FAILED;
 
        ql_log(ql_log_info, vha, 0x8009,
            "DEVICE RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", vha->host_no,
@@ -1488,7 +1512,7 @@ qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
                return err;
 
        if (fcport->deleted)
-               return SUCCESS;
+               return FAILED;
 
        ql_log(ql_log_info, vha, 0x8009,
            "TARGET RESET ISSUED nexus=%ld:%d cmd=%p.\n", vha->host_no,
@@ -5472,7 +5496,7 @@ qla2x00_do_work(struct scsi_qla_host *vha)
                            e->u.fcport.fcport, false);
                        break;
                case QLA_EVT_SA_REPLACE:
-                       qla24xx_issue_sa_replace_iocb(vha, e);
+                       rc = qla24xx_issue_sa_replace_iocb(vha, e);
                        break;
                }
 
@@ -7238,6 +7262,44 @@ static void qla_heart_beat(struct scsi_qla_host *vha, u16 dpc_started)
        }
 }
 
+static void qla_wind_down_chip(scsi_qla_host_t *vha)
+{
+       struct qla_hw_data *ha = vha->hw;
+
+       if (!ha->flags.eeh_busy)
+               return;
+       if (ha->pci_error_state)
+               /* system is trying to recover */
+               return;
+
+       /*
+        * Current system is not handling PCIE error.  At this point, this is
+        * best effort to wind down the adapter.
+        */
+       if (time_after_eq(jiffies, ha->eeh_jif + ql2xdelay_before_pci_error_handling * HZ) &&
+           !ha->flags.eeh_flush) {
+               ql_log(ql_log_info, vha, 0x9009,
+                   "PCI Error detected, attempting to reset hardware.\n");
+
+               ha->isp_ops->reset_chip(vha);
+               ha->isp_ops->disable_intrs(ha);
+
+               ha->flags.eeh_flush = EEH_FLUSH_RDY;
+               ha->eeh_jif = jiffies;
+
+       } else if (ha->flags.eeh_flush == EEH_FLUSH_RDY &&
+           time_after_eq(jiffies, ha->eeh_jif +  5 * HZ)) {
+               pci_clear_master(ha->pdev);
+
+               /* flush all command */
+               qla2x00_abort_isp_cleanup(vha);
+               ha->flags.eeh_flush = EEH_FLUSH_DONE;
+
+               ql_log(ql_log_info, vha, 0x900a,
+                   "PCI Error handling complete, all IOs aborted.\n");
+       }
+}
+
 /**************************************************************************
 *   qla2x00_timer
 *
@@ -7261,6 +7323,8 @@ qla2x00_timer(struct timer_list *t)
        fc_port_t *fcport = NULL;
 
        if (ha->flags.eeh_busy) {
+               qla_wind_down_chip(vha);
+
                ql_dbg(ql_dbg_timer, vha, 0x6000,
                    "EEH = %d, restarting timer.\n",
                    ha->flags.eeh_busy);
@@ -7841,6 +7905,9 @@ void qla_pci_set_eeh_busy(struct scsi_qla_host *vha)
 
        spin_lock_irqsave(&base_vha->work_lock, flags);
        if (!ha->flags.eeh_busy) {
+               ha->eeh_jif = jiffies;
+               ha->flags.eeh_flush = 0;
+
                ha->flags.eeh_busy = 1;
                do_cleanup = true;
        }
index cb97f62..2b2f682 100644 (file)
@@ -981,22 +981,6 @@ void qlt_free_session_done(struct work_struct *work)
                sess->send_els_logo);
 
        if (!IS_SW_RESV_ADDR(sess->d_id)) {
-               if (ha->flags.edif_enabled &&
-                   (!own || own->iocb.u.isp24.status_subcode == ELS_PLOGI)) {
-                       sess->edif.authok = 0;
-                       if (!ha->flags.host_shutting_down) {
-                               ql_dbg(ql_dbg_edif, vha, 0x911e,
-                                       "%s wwpn %8phC calling qla2x00_release_all_sadb\n",
-                                       __func__, sess->port_name);
-                               qla2x00_release_all_sadb(vha, sess);
-                       } else {
-                               ql_dbg(ql_dbg_edif, vha, 0x911e,
-                                       "%s bypassing release_all_sadb\n",
-                                       __func__);
-                       }
-                       qla_edif_clear_appdata(vha, sess);
-                       qla_edif_sess_down(vha, sess);
-               }
                qla2x00_mark_device_lost(vha, sess, 0);
 
                if (sess->send_els_logo) {
@@ -1042,6 +1026,25 @@ void qlt_free_session_done(struct work_struct *work)
                        sess->nvme_flag |= NVME_FLAG_DELETING;
                        qla_nvme_unregister_remote_port(sess);
                }
+
+               if (ha->flags.edif_enabled &&
+                   (!own || (own &&
+                             own->iocb.u.isp24.status_subcode == ELS_PLOGI))) {
+                       sess->edif.authok = 0;
+                       if (!ha->flags.host_shutting_down) {
+                               ql_dbg(ql_dbg_edif, vha, 0x911e,
+                                      "%s wwpn %8phC calling qla2x00_release_all_sadb\n",
+                                      __func__, sess->port_name);
+                               qla2x00_release_all_sadb(vha, sess);
+                       } else {
+                               ql_dbg(ql_dbg_edif, vha, 0x911e,
+                                      "%s bypassing release_all_sadb\n",
+                                      __func__);
+                       }
+
+                       qla_edif_clear_appdata(vha, sess);
+                       qla_edif_sess_down(vha, sess);
+               }
        }
 
        /*
index b09d7d2..defd21e 100644 (file)
@@ -6,9 +6,9 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "10.02.07.400-k"
+#define QLA2XXX_VERSION      "10.02.07.700-k"
 
 #define QLA_DRIVER_MAJOR_VER   10
 #define QLA_DRIVER_MINOR_VER   2
 #define QLA_DRIVER_PATCH_VER   7
-#define QLA_DRIVER_BETA_VER    400
+#define QLA_DRIVER_BETA_VER    700
index 49ef864..947d98a 100644 (file)
@@ -463,14 +463,12 @@ static void scsi_report_sense(struct scsi_device *sdev,
                        evt_type = SDEV_EVT_LUN_CHANGE_REPORTED;
                        scsi_report_lun_change(sdev);
                        sdev_printk(KERN_WARNING, sdev,
-                                   "Warning! Received an indication that the "
                                    "LUN assignments on this target have "
                                    "changed. The Linux SCSI layer does not "
                                    "automatically remap LUN assignments.\n");
                } else if (sshdr->asc == 0x3f)
                        sdev_printk(KERN_WARNING, sdev,
-                                   "Warning! Received an indication that the "
-                                   "operating parameters on this target have "
+                                   "Operating parameters on this target have "
                                    "changed. The Linux SCSI layer does not "
                                    "automatically adjust these parameters.\n");
 
index 6ffc9e4..2aca0a8 100644 (file)
@@ -75,13 +75,6 @@ int scsi_init_sense_cache(struct Scsi_Host *shost)
        return ret;
 }
 
-/*
- * When to reinvoke queueing after a resource shortage. It's 3 msecs to
- * not change behaviour from the previous unplug mechanism, experimentation
- * may prove this needs changing.
- */
-#define SCSI_QUEUE_DELAY       3
-
 static void
 scsi_set_blocked(struct scsi_cmnd *cmd, int reason)
 {
@@ -1648,6 +1641,13 @@ static void scsi_mq_put_budget(struct request_queue *q, int budget_token)
        sbitmap_put(&sdev->budget_map, budget_token);
 }
 
+/*
+ * When to reinvoke queueing after a resource shortage. It's 3 msecs to
+ * not change behaviour from the previous unplug mechanism, experimentation
+ * may prove this needs changing.
+ */
+#define SCSI_QUEUE_DELAY 3
+
 static int scsi_mq_get_budget(struct request_queue *q)
 {
        struct scsi_device *sdev = q->queuedata;
index 5d21f07..cd3db96 100644 (file)
@@ -1980,7 +1980,7 @@ static void __iscsi_unbind_session(struct work_struct *work)
        scsi_remove_target(&session->dev);
 
        if (session->ida_used)
-               ida_simple_remove(&iscsi_sess_ida, target_id);
+               ida_free(&iscsi_sess_ida, target_id);
 
 unbind_session_exit:
        iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
@@ -2049,7 +2049,7 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
                return -ENOMEM;
 
        if (target_id == ISCSI_MAX_TARGET) {
-               id = ida_simple_get(&iscsi_sess_ida, 0, 0, GFP_KERNEL);
+               id = ida_alloc(&iscsi_sess_ida, GFP_KERNEL);
 
                if (id < 0) {
                        iscsi_cls_session_printk(KERN_ERR, session,
@@ -2088,7 +2088,7 @@ release_dev:
        device_del(&session->dev);
 release_ida:
        if (session->ida_used)
-               ida_simple_remove(&iscsi_sess_ida, session->target_id);
+               ida_free(&iscsi_sess_ida, session->target_id);
 destroy_wq:
        destroy_workqueue(session->workq);
        return err;
@@ -2143,8 +2143,6 @@ static int iscsi_iter_destroy_conn_fn(struct device *dev, void *data)
                return 0;
 
        iscsi_remove_conn(iscsi_dev_to_conn(dev));
-       iscsi_put_conn(iscsi_dev_to_conn(dev));
-
        return 0;
 }
 
@@ -2264,18 +2262,20 @@ static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn,
        }
 }
 
-static int iscsi_if_stop_conn(struct iscsi_transport *transport,
-                             struct iscsi_uevent *ev)
+static int iscsi_if_stop_conn(struct iscsi_cls_conn *conn, int flag)
 {
-       int flag = ev->u.stop_conn.flag;
-       struct iscsi_cls_conn *conn;
-
-       conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid);
-       if (!conn)
-               return -EINVAL;
-
        ISCSI_DBG_TRANS_CONN(conn, "iscsi if conn stop.\n");
        /*
+        * For offload, iscsid may not know about the ep like when iscsid is
+        * restarted or for kernel based session shutdown iscsid is not even
+        * up. For these cases, we do the disconnect now.
+        */
+       mutex_lock(&conn->ep_mutex);
+       if (conn->ep)
+               iscsi_if_disconnect_bound_ep(conn, conn->ep, true);
+       mutex_unlock(&conn->ep_mutex);
+
+       /*
         * If this is a termination we have to call stop_conn with that flag
         * so the correct states get set. If we haven't run the work yet try to
         * avoid the extra run.
@@ -2285,16 +2285,6 @@ static int iscsi_if_stop_conn(struct iscsi_transport *transport,
                iscsi_stop_conn(conn, flag);
        } else {
                /*
-                * For offload, when iscsid is restarted it won't know about
-                * existing endpoints so it can't do a ep_disconnect. We clean
-                * it up here for userspace.
-                */
-               mutex_lock(&conn->ep_mutex);
-               if (conn->ep)
-                       iscsi_if_disconnect_bound_ep(conn, conn->ep, true);
-               mutex_unlock(&conn->ep_mutex);
-
-               /*
                 * Figure out if it was the kernel or userspace initiating this.
                 */
                spin_lock_irq(&conn->lock);
@@ -2349,6 +2339,55 @@ static void iscsi_cleanup_conn_work_fn(struct work_struct *work)
        ISCSI_DBG_TRANS_CONN(conn, "cleanup done.\n");
 }
 
+static int iscsi_iter_force_destroy_conn_fn(struct device *dev, void *data)
+{
+       struct iscsi_transport *transport;
+       struct iscsi_cls_conn *conn;
+
+       if (!iscsi_is_conn_dev(dev))
+               return 0;
+
+       conn = iscsi_dev_to_conn(dev);
+       transport = conn->transport;
+
+       if (READ_ONCE(conn->state) != ISCSI_CONN_DOWN)
+               iscsi_if_stop_conn(conn, STOP_CONN_TERM);
+
+       transport->destroy_conn(conn);
+       return 0;
+}
+
+/**
+ * iscsi_force_destroy_session - destroy a session from the kernel
+ * @session: session to destroy
+ *
+ * Force the destruction of a session from the kernel. This should only be
+ * used when userspace is no longer running during system shutdown.
+ */
+void iscsi_force_destroy_session(struct iscsi_cls_session *session)
+{
+       struct iscsi_transport *transport = session->transport;
+       unsigned long flags;
+
+       WARN_ON_ONCE(system_state == SYSTEM_RUNNING);
+
+       spin_lock_irqsave(&sesslock, flags);
+       if (list_empty(&session->sess_list)) {
+               spin_unlock_irqrestore(&sesslock, flags);
+               /*
+                * Conn/ep is already freed. Session is being torn down via
+                * async path. For shutdown we don't care about it so return.
+                */
+               return;
+       }
+       spin_unlock_irqrestore(&sesslock, flags);
+
+       device_for_each_child(&session->dev, NULL,
+                             iscsi_iter_force_destroy_conn_fn);
+       transport->destroy_session(session);
+}
+EXPORT_SYMBOL_GPL(iscsi_force_destroy_session);
+
 void iscsi_free_session(struct iscsi_cls_session *session)
 {
        ISCSI_DBG_TRANS_SESSION(session, "Freeing session\n");
@@ -3720,7 +3759,12 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,
        case ISCSI_UEVENT_DESTROY_CONN:
                return iscsi_if_destroy_conn(transport, ev);
        case ISCSI_UEVENT_STOP_CONN:
-               return iscsi_if_stop_conn(transport, ev);
+               conn = iscsi_conn_lookup(ev->u.stop_conn.sid,
+                                        ev->u.stop_conn.cid);
+               if (!conn)
+                       return -EINVAL;
+
+               return iscsi_if_stop_conn(conn, ev->u.stop_conn.flag);
        }
 
        /*
@@ -4812,7 +4856,7 @@ free_priv:
 }
 EXPORT_SYMBOL_GPL(iscsi_register_transport);
 
-int iscsi_unregister_transport(struct iscsi_transport *tt)
+void iscsi_unregister_transport(struct iscsi_transport *tt)
 {
        struct iscsi_internal *priv;
        unsigned long flags;
@@ -4835,8 +4879,6 @@ int iscsi_unregister_transport(struct iscsi_transport *tt)
        sysfs_remove_group(&priv->dev.kobj, &iscsi_transport_group);
        device_unregister(&priv->dev);
        mutex_unlock(&rx_queue_mutex);
-
-       return 0;
 }
 EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
 
index a1a2ac0..081e39b 100644 (file)
@@ -103,6 +103,7 @@ static void sd_config_discard(struct scsi_disk *, unsigned int);
 static void sd_config_write_same(struct scsi_disk *);
 static int  sd_revalidate_disk(struct gendisk *);
 static void sd_unlock_native_capacity(struct gendisk *disk);
+static void sd_start_done_work(struct work_struct *work);
 static int  sd_probe(struct device *);
 static int  sd_remove(struct device *);
 static void sd_shutdown(struct device *);
@@ -3463,6 +3464,7 @@ static int sd_probe(struct device *dev)
        sdkp->max_retries = SD_MAX_RETRIES;
        atomic_set(&sdkp->openers, 0);
        atomic_set(&sdkp->device->ioerr_cnt, 0);
+       INIT_WORK(&sdkp->start_done_work, sd_start_done_work);
 
        if (!sdp->request_queue->rq_timeout) {
                if (sdp->type != TYPE_MOD)
@@ -3585,12 +3587,69 @@ static void scsi_disk_release(struct device *dev)
        kfree(sdkp);
 }
 
+/* Process sense data after a START command finished. */
+static void sd_start_done_work(struct work_struct *work)
+{
+       struct scsi_disk *sdkp = container_of(work, typeof(*sdkp),
+                                             start_done_work);
+       struct scsi_sense_hdr sshdr;
+       int res = sdkp->start_result;
+
+       if (res == 0)
+               return;
+
+       sd_print_result(sdkp, "Start/Stop Unit failed", res);
+
+       if (res < 0)
+               return;
+
+       if (scsi_normalize_sense(sdkp->start_sense_buffer,
+                                sdkp->start_sense_len, &sshdr))
+               sd_print_sense_hdr(sdkp, &sshdr);
+}
+
+/* A START command finished. May be called from interrupt context. */
+static void sd_start_done(struct request *req, blk_status_t status)
+{
+       const struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
+       struct scsi_disk *sdkp = scsi_disk(req->q->disk);
+
+       sdkp->start_result = scmd->result;
+       WARN_ON_ONCE(scmd->sense_len > SCSI_SENSE_BUFFERSIZE);
+       sdkp->start_sense_len = scmd->sense_len;
+       memcpy(sdkp->start_sense_buffer, scmd->sense_buffer,
+              ARRAY_SIZE(sdkp->start_sense_buffer));
+       WARN_ON_ONCE(!schedule_work(&sdkp->start_done_work));
+}
+
+/* Submit a START command asynchronously. */
+static int sd_submit_start(struct scsi_disk *sdkp, u8 cmd[], u8 cmd_len)
+{
+       struct scsi_device *sdev = sdkp->device;
+       struct request_queue *q = sdev->request_queue;
+       struct request *req;
+       struct scsi_cmnd *scmd;
+
+       req = scsi_alloc_request(q, REQ_OP_DRV_IN, BLK_MQ_REQ_PM);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       scmd = blk_mq_rq_to_pdu(req);
+       scmd->cmd_len = cmd_len;
+       memcpy(scmd->cmnd, cmd, cmd_len);
+       scmd->allowed = sdkp->max_retries;
+       req->timeout = SD_TIMEOUT;
+       req->rq_flags |= RQF_PM | RQF_QUIET;
+       req->end_io = sd_start_done;
+       blk_execute_rq_nowait(req, /*at_head=*/true);
+
+       return 0;
+}
+
 static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
 {
        unsigned char cmd[6] = { START_STOP };  /* START_VALID */
-       struct scsi_sense_hdr sshdr;
        struct scsi_device *sdp = sdkp->device;
-       int res;
 
        if (start)
                cmd[4] |= 1;    /* START */
@@ -3601,23 +3660,10 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
        if (!scsi_device_online(sdp))
                return -ENODEV;
 
-       res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
-                       SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL);
-       if (res) {
-               sd_print_result(sdkp, "Start/Stop Unit failed", res);
-               if (res > 0 && scsi_sense_valid(&sshdr)) {
-                       sd_print_sense_hdr(sdkp, &sshdr);
-                       /* 0x3a is medium not present */
-                       if (sshdr.asc == 0x3a)
-                               res = 0;
-               }
-       }
+       /* Wait until processing of sense data has finished. */
+       flush_work(&sdkp->start_done_work);
 
-       /* SCSI error codes must not go to the generic layer */
-       if (res)
-               return -EIO;
-
-       return 0;
+       return sd_submit_start(sdkp, cmd, sizeof(cmd));
 }
 
 /*
@@ -3644,6 +3690,8 @@ static void sd_shutdown(struct device *dev)
                sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
                sd_start_stop_device(sdkp, 0);
        }
+
+       flush_work(&sdkp->start_done_work);
 }
 
 static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
index 5eea762..b891877 100644 (file)
@@ -150,6 +150,11 @@ struct scsi_disk {
        unsigned        urswrz : 1;
        unsigned        security : 1;
        unsigned        ignore_medium_access_errors : 1;
+
+       int             start_result;
+       u32             start_sense_len;
+       u8              start_sense_buffer[SCSI_SENSE_BUFFERSIZE];
+       struct work_struct start_done_work;
 };
 #define to_scsi_disk(obj) container_of(obj, struct scsi_disk, disk_dev)
 
index 2a045a5..c849ab6 100644 (file)
@@ -159,7 +159,7 @@ struct snic_exch_ver_req {
  * HBA Capabilities
  * Bit 1: Reserved.
  * Bit 2: Dynamic Discovery of LUNs.
- * Bit 3: Async event notifications on on tgt online/offline events.
+ * Bit 3: Async event notifications on tgt online/offline events.
  * Bit 4: IO timeout support in FW.
  * Bit 5-31: Reserved.
  */
index 255a2d4..f0db17e 100644 (file)
@@ -3598,7 +3598,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
 }
 
 /*
- *  Gerard's alchemy:) that deals with with the data 
+ *  Gerard's alchemy:) that deals with the data
  *  pointer for both MDP and the residual calculation.
  *
  *  I didn't want to bloat the code by more than 200 
index ce14540..5d0f518 100644 (file)
@@ -210,7 +210,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
                return ERR_PTR(ret);
        }
 
-       tpg = container_of(se_tpg, struct iscsi_portal_group, tpg_se_tpg);
+       tpg = to_iscsi_tpg(se_tpg);
        ret = iscsit_get_tpg(tpg);
        if (ret < 0)
                return ERR_PTR(-EINVAL);
@@ -281,9 +281,7 @@ static ssize_t iscsi_nacl_attrib_##name##_show(struct config_item *item,\
                char *page)                                             \
 {                                                                      \
        struct se_node_acl *se_nacl = attrib_to_nacl(item);             \
-       struct iscsi_node_acl *nacl = container_of(se_nacl, struct iscsi_node_acl, \
-                                       se_node_acl);                   \
-                                                                       \
+       struct iscsi_node_acl *nacl = to_iscsi_nacl(se_nacl);           \
        return sprintf(page, "%u\n", nacl->node_attrib.name);           \
 }                                                                      \
                                                                        \
@@ -291,8 +289,7 @@ static ssize_t iscsi_nacl_attrib_##name##_store(struct config_item *item,\
                const char *page, size_t count)                         \
 {                                                                      \
        struct se_node_acl *se_nacl = attrib_to_nacl(item);             \
-       struct iscsi_node_acl *nacl = container_of(se_nacl, struct iscsi_node_acl, \
-                                       se_node_acl);                   \
+       struct iscsi_node_acl *nacl = to_iscsi_nacl(se_nacl);           \
        u32 val;                                                        \
        int ret;                                                        \
                                                                        \
@@ -317,6 +314,36 @@ ISCSI_NACL_ATTR(random_datain_pdu_offsets);
 ISCSI_NACL_ATTR(random_datain_seq_offsets);
 ISCSI_NACL_ATTR(random_r2t_offsets);
 
+static ssize_t iscsi_nacl_attrib_authentication_show(struct config_item *item,
+               char *page)
+{
+       struct se_node_acl *se_nacl = attrib_to_nacl(item);
+       struct iscsi_node_acl *nacl = to_iscsi_nacl(se_nacl);
+
+       return sprintf(page, "%d\n", nacl->node_attrib.authentication);
+}
+
+static ssize_t iscsi_nacl_attrib_authentication_store(struct config_item *item,
+               const char *page, size_t count)
+{
+       struct se_node_acl *se_nacl = attrib_to_nacl(item);
+       struct iscsi_node_acl *nacl = to_iscsi_nacl(se_nacl);
+       s32 val;
+       int ret;
+
+       ret = kstrtos32(page, 0, &val);
+       if (ret)
+               return ret;
+       if (val != 0 && val != 1 && val != NA_AUTHENTICATION_INHERITED)
+               return -EINVAL;
+
+       nacl->node_attrib.authentication = val;
+
+       return count;
+}
+
+CONFIGFS_ATTR(iscsi_nacl_attrib_, authentication);
+
 static struct configfs_attribute *lio_target_nacl_attrib_attrs[] = {
        &iscsi_nacl_attrib_attr_dataout_timeout,
        &iscsi_nacl_attrib_attr_dataout_timeout_retries,
@@ -326,6 +353,7 @@ static struct configfs_attribute *lio_target_nacl_attrib_attrs[] = {
        &iscsi_nacl_attrib_attr_random_datain_pdu_offsets,
        &iscsi_nacl_attrib_attr_random_datain_seq_offsets,
        &iscsi_nacl_attrib_attr_random_r2t_offsets,
+       &iscsi_nacl_attrib_attr_authentication,
        NULL,
 };
 
@@ -377,15 +405,14 @@ static ssize_t iscsi_nacl_auth_##name##_show(struct config_item *item,    \
                char *page)                                             \
 {                                                                      \
        struct se_node_acl *nacl = auth_to_nacl(item);                  \
-       return __iscsi_nacl_auth_##name##_show(container_of(nacl,       \
-                       struct iscsi_node_acl, se_node_acl), page);     \
+       return __iscsi_nacl_auth_##name##_show(to_iscsi_nacl(nacl), page);      \
 }                                                                      \
 static ssize_t iscsi_nacl_auth_##name##_store(struct config_item *item,        \
                const char *page, size_t count)                         \
 {                                                                      \
        struct se_node_acl *nacl = auth_to_nacl(item);                  \
-       return __iscsi_nacl_auth_##name##_store(container_of(nacl,      \
-                       struct iscsi_node_acl, se_node_acl), page, count); \
+       return __iscsi_nacl_auth_##name##_store(to_iscsi_nacl(nacl),    \
+                                               page, count); \
 }                                                                      \
                                                                        \
 CONFIGFS_ATTR(iscsi_nacl_auth_, name)
@@ -417,8 +444,7 @@ static ssize_t iscsi_nacl_auth_##name##_show(struct config_item *item,      \
                char *page)                                             \
 {                                                                      \
        struct se_node_acl *nacl = auth_to_nacl(item);                  \
-       return __iscsi_nacl_auth_##name##_show(container_of(nacl,       \
-                       struct iscsi_node_acl, se_node_acl), page);     \
+       return __iscsi_nacl_auth_##name##_show(to_iscsi_nacl(nacl), page);      \
 }                                                                      \
                                                                        \
 CONFIGFS_ATTR_RO(iscsi_nacl_auth_, name)
@@ -623,8 +649,7 @@ static ssize_t lio_target_nacl_cmdsn_depth_store(struct config_item *item,
 {
        struct se_node_acl *se_nacl = acl_to_nacl(item);
        struct se_portal_group *se_tpg = se_nacl->se_tpg;
-       struct iscsi_portal_group *tpg = container_of(se_tpg,
-                       struct iscsi_portal_group, tpg_se_tpg);
+       struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);
        struct config_item *acl_ci, *tpg_ci, *wwn_ci;
        u32 cmdsn_depth = 0;
        int ret;
@@ -700,8 +725,7 @@ static struct configfs_attribute *lio_target_initiator_attrs[] = {
 static int lio_target_init_nodeacl(struct se_node_acl *se_nacl,
                const char *name)
 {
-       struct iscsi_node_acl *acl =
-               container_of(se_nacl, struct iscsi_node_acl, se_node_acl);
+       struct iscsi_node_acl *acl = to_iscsi_nacl(se_nacl);
 
        config_group_init_type_name(&acl->node_stat_grps.iscsi_sess_stats_group,
                        "iscsi_sess_stats", &iscsi_stat_sess_cit);
@@ -720,8 +744,7 @@ static ssize_t iscsi_tpg_attrib_##name##_show(struct config_item *item,     \
                char *page)                                             \
 {                                                                      \
        struct se_portal_group *se_tpg = attrib_to_tpg(item);           \
-       struct iscsi_portal_group *tpg = container_of(se_tpg,           \
-                       struct iscsi_portal_group, tpg_se_tpg); \
+       struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);          \
        ssize_t rb;                                                     \
                                                                        \
        if (iscsit_get_tpg(tpg) < 0)                                    \
@@ -736,8 +759,7 @@ static ssize_t iscsi_tpg_attrib_##name##_store(struct config_item *item,\
                const char *page, size_t count)                         \
 {                                                                      \
        struct se_portal_group *se_tpg = attrib_to_tpg(item);           \
-       struct iscsi_portal_group *tpg = container_of(se_tpg,           \
-                       struct iscsi_portal_group, tpg_se_tpg); \
+       struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);          \
        u32 val;                                                        \
        int ret;                                                        \
                                                                        \
@@ -800,8 +822,7 @@ static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
 static ssize_t __iscsi_##prefix##_##name##_show(struct se_portal_group *se_tpg,        \
                char *page)                                                     \
 {                                                                              \
-       struct iscsi_portal_group *tpg = container_of(se_tpg,                   \
-                               struct iscsi_portal_group, tpg_se_tpg);         \
+       struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);                  \
        struct iscsi_node_auth *auth = &tpg->tpg_demo_auth;                     \
                                                                                \
        if (!capable(CAP_SYS_ADMIN))                                            \
@@ -813,8 +834,7 @@ static ssize_t __iscsi_##prefix##_##name##_show(struct se_portal_group *se_tpg,
 static ssize_t __iscsi_##prefix##_##name##_store(struct se_portal_group *se_tpg,\
                const char *page, size_t count)                                 \
 {                                                                              \
-       struct iscsi_portal_group *tpg = container_of(se_tpg,                   \
-                               struct iscsi_portal_group, tpg_se_tpg);         \
+       struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);                  \
        struct iscsi_node_auth *auth = &tpg->tpg_demo_auth;                     \
                                                                                \
        if (!capable(CAP_SYS_ADMIN))                                            \
@@ -861,8 +881,7 @@ DEF_TPG_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET);
 static ssize_t __iscsi_##prefix##_##name##_show(struct se_portal_group *se_tpg,        \
                char *page)                                                             \
 {                                                                              \
-       struct iscsi_portal_group *tpg = container_of(se_tpg,                   \
-                               struct iscsi_portal_group, tpg_se_tpg);         \
+       struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);                  \
        struct iscsi_node_auth *auth = &tpg->tpg_demo_auth;                     \
                                                                                \
        if (!capable(CAP_SYS_ADMIN))                                            \
@@ -900,8 +919,7 @@ static ssize_t iscsi_tpg_param_##name##_show(struct config_item *item,      \
                char *page)                                             \
 {                                                                      \
        struct se_portal_group *se_tpg = param_to_tpg(item);            \
-       struct iscsi_portal_group *tpg = container_of(se_tpg,           \
-                       struct iscsi_portal_group, tpg_se_tpg);         \
+       struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);          \
        struct iscsi_param *param;                                      \
        ssize_t rb;                                                     \
                                                                        \
@@ -923,8 +941,7 @@ static ssize_t iscsi_tpg_param_##name##_store(struct config_item *item, \
                const char *page, size_t count)                         \
 {                                                                      \
        struct se_portal_group *se_tpg = param_to_tpg(item);            \
-       struct iscsi_portal_group *tpg = container_of(se_tpg,           \
-                       struct iscsi_portal_group, tpg_se_tpg);         \
+       struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);          \
        char *buf;                                                      \
        int ret, len;                                                   \
                                                                        \
@@ -1073,8 +1090,7 @@ free_out:
 static int lio_target_tiqn_enabletpg(struct se_portal_group *se_tpg,
                                     bool enable)
 {
-       struct iscsi_portal_group *tpg = container_of(se_tpg,
-                       struct iscsi_portal_group, tpg_se_tpg);
+       struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);
        int ret;
 
        ret = iscsit_get_tpg(tpg);
@@ -1106,7 +1122,7 @@ static void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg)
        struct iscsi_portal_group *tpg;
        struct iscsi_tiqn *tiqn;
 
-       tpg = container_of(se_tpg, struct iscsi_portal_group, tpg_se_tpg);
+       tpg = to_iscsi_tpg(se_tpg);
        tiqn = tpg->tpg_tiqn;
        /*
         * iscsit_tpg_del_portal_group() assumes force=1
@@ -1416,46 +1432,41 @@ static void lio_aborted_task(struct se_cmd *se_cmd)
        cmd->conn->conn_transport->iscsit_aborted_task(cmd->conn, cmd);
 }
 
-static inline struct iscsi_portal_group *iscsi_tpg(struct se_portal_group *se_tpg)
-{
-       return container_of(se_tpg, struct iscsi_portal_group, tpg_se_tpg);
-}
-
 static char *lio_tpg_get_endpoint_wwn(struct se_portal_group *se_tpg)
 {
-       return iscsi_tpg(se_tpg)->tpg_tiqn->tiqn;
+       return to_iscsi_tpg(se_tpg)->tpg_tiqn->tiqn;
 }
 
 static u16 lio_tpg_get_tag(struct se_portal_group *se_tpg)
 {
-       return iscsi_tpg(se_tpg)->tpgt;
+       return to_iscsi_tpg(se_tpg)->tpgt;
 }
 
 static u32 lio_tpg_get_default_depth(struct se_portal_group *se_tpg)
 {
-       return iscsi_tpg(se_tpg)->tpg_attrib.default_cmdsn_depth;
+       return to_iscsi_tpg(se_tpg)->tpg_attrib.default_cmdsn_depth;
 }
 
 static int lio_tpg_check_demo_mode(struct se_portal_group *se_tpg)
 {
-       return iscsi_tpg(se_tpg)->tpg_attrib.generate_node_acls;
+       return to_iscsi_tpg(se_tpg)->tpg_attrib.generate_node_acls;
 }
 
 static int lio_tpg_check_demo_mode_cache(struct se_portal_group *se_tpg)
 {
-       return iscsi_tpg(se_tpg)->tpg_attrib.cache_dynamic_acls;
+       return to_iscsi_tpg(se_tpg)->tpg_attrib.cache_dynamic_acls;
 }
 
 static int lio_tpg_check_demo_mode_write_protect(
        struct se_portal_group *se_tpg)
 {
-       return iscsi_tpg(se_tpg)->tpg_attrib.demo_mode_write_protect;
+       return to_iscsi_tpg(se_tpg)->tpg_attrib.demo_mode_write_protect;
 }
 
 static int lio_tpg_check_prod_mode_write_protect(
        struct se_portal_group *se_tpg)
 {
-       return iscsi_tpg(se_tpg)->tpg_attrib.prod_mode_write_protect;
+       return to_iscsi_tpg(se_tpg)->tpg_attrib.prod_mode_write_protect;
 }
 
 static int lio_tpg_check_prot_fabric_only(
@@ -1465,9 +1476,9 @@ static int lio_tpg_check_prot_fabric_only(
         * Only report fabric_prot_type if t10_pi has also been enabled
         * for incoming ib_isert sessions.
         */
-       if (!iscsi_tpg(se_tpg)->tpg_attrib.t10_pi)
+       if (!to_iscsi_tpg(se_tpg)->tpg_attrib.t10_pi)
                return 0;
-       return iscsi_tpg(se_tpg)->tpg_attrib.fabric_prot_type;
+       return to_iscsi_tpg(se_tpg)->tpg_attrib.fabric_prot_type;
 }
 
 /*
@@ -1504,16 +1515,14 @@ static void lio_tpg_close_session(struct se_session *se_sess)
 
 static u32 lio_tpg_get_inst_index(struct se_portal_group *se_tpg)
 {
-       return iscsi_tpg(se_tpg)->tpg_tiqn->tiqn_index;
+       return to_iscsi_tpg(se_tpg)->tpg_tiqn->tiqn_index;
 }
 
 static void lio_set_default_node_attributes(struct se_node_acl *se_acl)
 {
-       struct iscsi_node_acl *acl = container_of(se_acl, struct iscsi_node_acl,
-                               se_node_acl);
+       struct iscsi_node_acl *acl = to_iscsi_nacl(se_acl);
        struct se_portal_group *se_tpg = se_acl->se_tpg;
-       struct iscsi_portal_group *tpg = container_of(se_tpg,
-                               struct iscsi_portal_group, tpg_se_tpg);
+       struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);
 
        acl->node_attrib.nacl = acl;
        iscsit_set_default_node_attribues(acl, tpg);
index b34ac9e..fb93a11 100644 (file)
@@ -94,6 +94,31 @@ int extract_param(
        return 0;
 }
 
+static struct iscsi_node_auth *iscsi_get_node_auth(struct iscsit_conn *conn)
+{
+       struct iscsi_portal_group *tpg;
+       struct iscsi_node_acl *nacl;
+       struct se_node_acl *se_nacl;
+
+       if (conn->sess->sess_ops->SessionType)
+               return &iscsit_global->discovery_acl.node_auth;
+
+       se_nacl = conn->sess->se_sess->se_node_acl;
+       if (!se_nacl) {
+               pr_err("Unable to locate struct se_node_acl for CHAP auth\n");
+               return NULL;
+       }
+
+       if (se_nacl->dynamic_node_acl) {
+               tpg = to_iscsi_tpg(se_nacl->se_tpg);
+               return &tpg->tpg_demo_auth;
+       }
+
+       nacl = to_iscsi_nacl(se_nacl);
+
+       return &nacl->node_auth;
+}
+
 static u32 iscsi_handle_authentication(
        struct iscsit_conn *conn,
        char *in_buf,
@@ -102,40 +127,11 @@ static u32 iscsi_handle_authentication(
        int *out_length,
        unsigned char *authtype)
 {
-       struct iscsit_session *sess = conn->sess;
        struct iscsi_node_auth *auth;
-       struct iscsi_node_acl *iscsi_nacl;
-       struct iscsi_portal_group *iscsi_tpg;
-       struct se_node_acl *se_nacl;
-
-       if (!sess->sess_ops->SessionType) {
-               /*
-                * For SessionType=Normal
-                */
-               se_nacl = conn->sess->se_sess->se_node_acl;
-               if (!se_nacl) {
-                       pr_err("Unable to locate struct se_node_acl for"
-                                       " CHAP auth\n");
-                       return -1;
-               }
-
-               if (se_nacl->dynamic_node_acl) {
-                       iscsi_tpg = container_of(se_nacl->se_tpg,
-                                       struct iscsi_portal_group, tpg_se_tpg);
 
-                       auth = &iscsi_tpg->tpg_demo_auth;
-               } else {
-                       iscsi_nacl = container_of(se_nacl, struct iscsi_node_acl,
-                                                 se_node_acl);
-
-                       auth = &iscsi_nacl->node_auth;
-               }
-       } else {
-               /*
-                * For SessionType=Discovery
-                */
-               auth = &iscsit_global->discovery_acl.node_auth;
-       }
+       auth = iscsi_get_node_auth(conn);
+       if (!auth)
+               return -1;
 
        if (strstr("CHAP", authtype))
                strcpy(conn->sess->auth_type, "CHAP");
@@ -815,6 +811,42 @@ static int iscsi_target_do_authentication(
        return 0;
 }
 
+static bool iscsi_conn_auth_required(struct iscsit_conn *conn)
+{
+       struct iscsi_node_acl *nacl;
+       struct se_node_acl *se_nacl;
+
+       if (conn->sess->sess_ops->SessionType) {
+               /*
+                * For SessionType=Discovery
+                */
+               return conn->tpg->tpg_attrib.authentication;
+       }
+       /*
+        * For SessionType=Normal
+        */
+       se_nacl = conn->sess->se_sess->se_node_acl;
+       if (!se_nacl) {
+               pr_debug("Unknown ACL is trying to connect\n");
+               return true;
+       }
+
+       if (se_nacl->dynamic_node_acl) {
+               pr_debug("Dynamic ACL %s is trying to connect\n",
+                        se_nacl->initiatorname);
+               return conn->tpg->tpg_attrib.authentication;
+       }
+
+       pr_debug("Known ACL %s is trying to connect\n",
+                se_nacl->initiatorname);
+
+       nacl = to_iscsi_nacl(se_nacl);
+       if (nacl->node_attrib.authentication == NA_AUTHENTICATION_INHERITED)
+               return conn->tpg->tpg_attrib.authentication;
+
+       return nacl->node_attrib.authentication;
+}
+
 static int iscsi_target_handle_csg_zero(
        struct iscsit_conn *conn,
        struct iscsi_login *login)
@@ -876,22 +908,26 @@ static int iscsi_target_handle_csg_zero(
                return -1;
 
        if (!iscsi_check_negotiated_keys(conn->param_list)) {
-               if (conn->tpg->tpg_attrib.authentication &&
-                   !strncmp(param->value, NONE, 4)) {
-                       pr_err("Initiator sent AuthMethod=None but"
-                               " Target is enforcing iSCSI Authentication,"
-                                       " login failed.\n");
-                       iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
-                                       ISCSI_LOGIN_STATUS_AUTH_FAILED);
-                       return -1;
-               }
+               bool auth_required = iscsi_conn_auth_required(conn);
+
+               if (auth_required) {
+                       if (!strncmp(param->value, NONE, 4)) {
+                               pr_err("Initiator sent AuthMethod=None but"
+                                      " Target is enforcing iSCSI Authentication,"
+                                      " login failed.\n");
+                               iscsit_tx_login_rsp(conn,
+                                               ISCSI_STATUS_CLS_INITIATOR_ERR,
+                                               ISCSI_LOGIN_STATUS_AUTH_FAILED);
+                               return -1;
+                       }
 
-               if (conn->tpg->tpg_attrib.authentication &&
-                   !login->auth_complete)
-                       return 0;
+                       if (!login->auth_complete)
+                               return 0;
 
-               if (strncmp(param->value, NONE, 4) && !login->auth_complete)
-                       return 0;
+                       if (strncmp(param->value, NONE, 4) &&
+                           !login->auth_complete)
+                               return 0;
+               }
 
                if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE1) &&
                    (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) {
@@ -906,6 +942,18 @@ do_auth:
        return iscsi_target_do_authentication(conn, login);
 }
 
+static bool iscsi_conn_authenticated(struct iscsit_conn *conn,
+                                    struct iscsi_login *login)
+{
+       if (!iscsi_conn_auth_required(conn))
+               return true;
+
+       if (login->auth_complete)
+               return true;
+
+       return false;
+}
+
 static int iscsi_target_handle_csg_one(struct iscsit_conn *conn, struct iscsi_login *login)
 {
        int ret;
@@ -949,11 +997,10 @@ static int iscsi_target_handle_csg_one(struct iscsit_conn *conn, struct iscsi_lo
                return -1;
        }
 
-       if (!login->auth_complete &&
-            conn->tpg->tpg_attrib.authentication) {
+       if (!iscsi_conn_authenticated(conn, login)) {
                pr_err("Initiator is requesting CSG: 1, has not been"
-                        " successfully authenticated, and the Target is"
-                       " enforcing iSCSI Authentication, login failed.\n");
+                      " successfully authenticated, and the Target is"
+                      " enforcing iSCSI Authentication, login failed.\n");
                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
                                ISCSI_LOGIN_STATUS_AUTH_FAILED);
                return -1;
index 874cb33..d63efde 100644 (file)
@@ -30,6 +30,7 @@ void iscsit_set_default_node_attribues(
 {
        struct iscsi_node_attrib *a = &acl->node_attrib;
 
+       a->authentication = NA_AUTHENTICATION_INHERITED;
        a->dataout_timeout = NA_DATAOUT_TIMEOUT;
        a->dataout_timeout_retries = NA_DATAOUT_TIMEOUT_RETRIES;
        a->nopin_timeout = NA_NOPIN_TIMEOUT;
index 4339ee5..3cac1aa 100644 (file)
@@ -394,8 +394,7 @@ struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(
 {
        struct se_session *se_sess = sess->se_sess;
        struct se_node_acl *se_nacl = se_sess->se_node_acl;
-       struct iscsi_node_acl *acl = container_of(se_nacl, struct iscsi_node_acl,
-                                       se_node_acl);
+       struct iscsi_node_acl *acl = to_iscsi_nacl(se_nacl);
 
        return &acl->node_attrib;
 }
index b56ef8a..58df014 100644 (file)
@@ -385,7 +385,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
 
                        /*
                         * Extract the RELATIVE TARGET PORT IDENTIFIER to identify
-                        * the Target Port in question for the the incoming
+                        * the Target Port in question for the incoming
                         * SET_TARGET_PORT_GROUPS op.
                         */
                        rtpi = get_unaligned_be16(ptr + 2);
index bbcbbfa..416514c 100644 (file)
@@ -732,6 +732,7 @@ static ssize_t emulate_tpu_store(struct config_item *item,
                const char *page, size_t count)
 {
        struct se_dev_attrib *da = to_attrib(item);
+       struct se_device *dev = da->da_dev;
        bool flag;
        int ret;
 
@@ -744,8 +745,11 @@ static ssize_t emulate_tpu_store(struct config_item *item,
         * Discard supported is detected iblock_create_virtdevice().
         */
        if (flag && !da->max_unmap_block_desc_count) {
-               pr_err("Generic Block Discard not supported\n");
-               return -ENOSYS;
+               if (!dev->transport->configure_unmap ||
+                   !dev->transport->configure_unmap(dev)) {
+                       pr_err("Generic Block Discard not supported\n");
+                       return -ENOSYS;
+               }
        }
 
        da->emulate_tpu = flag;
@@ -758,6 +762,7 @@ static ssize_t emulate_tpws_store(struct config_item *item,
                const char *page, size_t count)
 {
        struct se_dev_attrib *da = to_attrib(item);
+       struct se_device *dev = da->da_dev;
        bool flag;
        int ret;
 
@@ -770,8 +775,11 @@ static ssize_t emulate_tpws_store(struct config_item *item,
         * Discard supported is detected iblock_create_virtdevice().
         */
        if (flag && !da->max_unmap_block_desc_count) {
-               pr_err("Generic Block Discard not supported\n");
-               return -ENOSYS;
+               if (!dev->transport->configure_unmap ||
+                   !dev->transport->configure_unmap(dev)) {
+                       pr_err("Generic Block Discard not supported\n");
+                       return -ENOSYS;
+               }
        }
 
        da->emulate_tpws = flag;
@@ -964,6 +972,7 @@ static ssize_t unmap_zeroes_data_store(struct config_item *item,
                const char *page, size_t count)
 {
        struct se_dev_attrib *da = to_attrib(item);
+       struct se_device *dev = da->da_dev;
        bool flag;
        int ret;
 
@@ -982,10 +991,12 @@ static ssize_t unmap_zeroes_data_store(struct config_item *item,
         * Discard supported is detected iblock_configure_device().
         */
        if (flag && !da->max_unmap_block_desc_count) {
-               pr_err("dev[%p]: Thin Provisioning LBPRZ will not be set"
-                      " because max_unmap_block_desc_count is zero\n",
-                      da->da_dev);
-               return -ENOSYS;
+               if (!dev->transport->configure_unmap ||
+                   !dev->transport->configure_unmap(dev)) {
+                       pr_err("dev[%p]: Thin Provisioning LBPRZ will not be set because max_unmap_block_desc_count is zero\n",
+                              da->da_dev);
+                       return -ENOSYS;
+               }
        }
        da->unmap_zeroes_data = flag;
        pr_debug("dev[%p]: SE Device Thin Provisioning LBPRZ bit: %d\n",
index 25f33eb..086ac9c 100644 (file)
@@ -960,6 +960,12 @@ int target_configure_device(struct se_device *dev)
        ret = dev->transport->configure_device(dev);
        if (ret)
                goto out_free_index;
+
+       if (dev->transport->configure_unmap &&
+           dev->transport->configure_unmap(dev)) {
+               pr_debug("Discard support available, but disabled by default.\n");
+       }
+
        /*
         * XXX: there is not much point to have two different values here..
         */
index e68f1cc..dd51a2a 100644 (file)
@@ -86,6 +86,24 @@ static struct se_device *fd_alloc_device(struct se_hba *hba, const char *name)
        return &fd_dev->dev;
 }
 
+static bool fd_configure_unmap(struct se_device *dev)
+{
+       struct file *file = FD_DEV(dev)->fd_file;
+       struct inode *inode = file->f_mapping->host;
+
+       if (S_ISBLK(inode->i_mode))
+               return target_configure_unmap_from_queue(&dev->dev_attrib,
+                                                        I_BDEV(inode));
+
+       /* Limit UNMAP emulation to 8k Number of LBAs (NoLB) */
+       dev->dev_attrib.max_unmap_lba_count = 0x2000;
+       /* Currently hardcoded to 1 in Linux/SCSI code. */
+       dev->dev_attrib.max_unmap_block_desc_count = 1;
+       dev->dev_attrib.unmap_granularity = 1;
+       dev->dev_attrib.unmap_granularity_alignment = 0;
+       return true;
+}
+
 static int fd_configure_device(struct se_device *dev)
 {
        struct fd_dev *fd_dev = FD_DEV(dev);
@@ -149,10 +167,6 @@ static int fd_configure_device(struct se_device *dev)
                        " block_device blocks: %llu logical_block_size: %d\n",
                        dev_size, div_u64(dev_size, fd_dev->fd_block_size),
                        fd_dev->fd_block_size);
-
-               if (target_configure_unmap_from_queue(&dev->dev_attrib, bdev))
-                       pr_debug("IFILE: BLOCK Discard support available,"
-                                " disabled by default\n");
                /*
                 * Enable write same emulation for IBLOCK and use 0xFFFF as
                 * the smaller WRITE_SAME(10) only has a two-byte block count.
@@ -170,16 +184,6 @@ static int fd_configure_device(struct se_device *dev)
                }
 
                fd_dev->fd_block_size = FD_BLOCKSIZE;
-               /*
-                * Limit UNMAP emulation to 8k Number of LBAs (NoLB)
-                */
-               dev->dev_attrib.max_unmap_lba_count = 0x2000;
-               /*
-                * Currently hardcoded to 1 in Linux/SCSI code..
-                */
-               dev->dev_attrib.max_unmap_block_desc_count = 1;
-               dev->dev_attrib.unmap_granularity = 1;
-               dev->dev_attrib.unmap_granularity_alignment = 0;
 
                /*
                 * Limit WRITE_SAME w/ UNMAP=0 emulation to 8k Number of LBAs (NoLB)
@@ -438,10 +442,6 @@ fd_execute_write_same(struct se_cmd *cmd)
        unsigned int len = 0, i;
        ssize_t ret;
 
-       if (!nolb) {
-               target_complete_cmd(cmd, SAM_STAT_GOOD);
-               return 0;
-       }
        if (cmd->prot_op) {
                pr_err("WRITE_SAME: Protection information with FILEIO"
                       " backends not supported\n");
@@ -924,6 +924,7 @@ static const struct target_backend_ops fileio_ops = {
        .configure_device       = fd_configure_device,
        .destroy_device         = fd_destroy_device,
        .free_device            = fd_free_device,
+       .configure_unmap        = fd_configure_unmap,
        .parse_cdb              = fd_parse_cdb,
        .set_configfs_dev_params = fd_set_configfs_dev_params,
        .show_configfs_dev_params = fd_show_configfs_dev_params,
index 378c803..bbf69d9 100644 (file)
@@ -76,6 +76,14 @@ free_dev:
        return NULL;
 }
 
+static bool iblock_configure_unmap(struct se_device *dev)
+{
+       struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
+
+       return target_configure_unmap_from_queue(&dev->dev_attrib,
+                                                ib_dev->ibd_bd);
+}
+
 static int iblock_configure_device(struct se_device *dev)
 {
        struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
@@ -119,10 +127,6 @@ static int iblock_configure_device(struct se_device *dev)
        dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q);
        dev->dev_attrib.hw_queue_depth = q->nr_requests;
 
-       if (target_configure_unmap_from_queue(&dev->dev_attrib, bd))
-               pr_debug("IBLOCK: BLOCK Discard support available,"
-                        " disabled by default\n");
-
        /*
         * Enable write same emulation for IBLOCK and use 0xFFFF as
         * the smaller WRITE_SAME(10) only has a two-byte block count.
@@ -899,6 +903,7 @@ static const struct target_backend_ops iblock_ops = {
        .configure_device       = iblock_configure_device,
        .destroy_device         = iblock_destroy_device,
        .free_device            = iblock_free_device,
+       .configure_unmap        = iblock_configure_unmap,
        .plug_device            = iblock_plug_device,
        .unplug_device          = iblock_unplug_device,
        .parse_cdb              = iblock_parse_cdb,
index ffb01fc..8f67db2 100644 (file)
@@ -215,7 +215,7 @@ static inline void ufshcd_vops_config_scaling_param(struct ufs_hba *hba,
                hba->vops->config_scaling_param(hba, p, data);
 }
 
-extern struct ufs_pm_lvl_states ufs_pm_lvl_states[];
+extern const struct ufs_pm_lvl_states ufs_pm_lvl_states[];
 
 /**
  * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN
@@ -234,8 +234,8 @@ static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun)
 
 int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask);
 int ufshcd_write_ee_control(struct ufs_hba *hba);
-int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask,
-                            u16 set, u16 clr);
+int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask,
+                            const u16 *other_mask, u16 set, u16 clr);
 
 static inline int ufshcd_update_ee_drv_mask(struct ufs_hba *hba,
                                            u16 set, u16 clr)
index ce86d1b..7c1d7bb 100644 (file)
@@ -175,7 +175,7 @@ enum {
 #define ufshcd_clear_eh_in_progress(h) \
        ((h)->eh_flags &= ~UFSHCD_EH_IN_PROGRESS)
 
-struct ufs_pm_lvl_states ufs_pm_lvl_states[] = {
+const struct ufs_pm_lvl_states ufs_pm_lvl_states[] = {
        [UFS_PM_LVL_0] = {UFS_ACTIVE_PWR_MODE, UIC_LINK_ACTIVE_STATE},
        [UFS_PM_LVL_1] = {UFS_ACTIVE_PWR_MODE, UIC_LINK_HIBERN8_STATE},
        [UFS_PM_LVL_2] = {UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE},
@@ -363,7 +363,7 @@ static void ufshcd_add_tm_upiu_trace(struct ufs_hba *hba, unsigned int tag,
 }
 
 static void ufshcd_add_uic_command_trace(struct ufs_hba *hba,
-                                        struct uic_command *ucmd,
+                                        const struct uic_command *ucmd,
                                         enum ufs_trace_str_t str_t)
 {
        u32 cmd;
@@ -443,11 +443,11 @@ static void ufshcd_print_clk_freqs(struct ufs_hba *hba)
 }
 
 static void ufshcd_print_evt(struct ufs_hba *hba, u32 id,
-                            char *err_name)
+                            const char *err_name)
 {
        int i;
        bool found = false;
-       struct ufs_event_hist *e;
+       const struct ufs_event_hist *e;
 
        if (id >= UFS_EVT_CNT)
                return;
@@ -497,7 +497,7 @@ static void ufshcd_print_evt_hist(struct ufs_hba *hba)
 static
 void ufshcd_print_trs(struct ufs_hba *hba, unsigned long bitmap, bool pr_prdt)
 {
-       struct ufshcd_lrb *lrbp;
+       const struct ufshcd_lrb *lrbp;
        int prdt_length;
        int tag;
 
@@ -553,7 +553,7 @@ static void ufshcd_print_tmrs(struct ufs_hba *hba, unsigned long bitmap)
 
 static void ufshcd_print_host_state(struct ufs_hba *hba)
 {
-       struct scsi_device *sdev_ufs = hba->ufs_device_wlun;
+       const struct scsi_device *sdev_ufs = hba->ufs_device_wlun;
 
        dev_err(hba->dev, "UFS Host state=%d\n", hba->ufshcd_state);
        dev_err(hba->dev, "outstanding reqs=0x%lx tasks=0x%lx\n",
@@ -1109,7 +1109,7 @@ static bool ufshcd_is_devfreq_scaling_required(struct ufs_hba *hba,
  */
 static u32 ufshcd_pending_cmds(struct ufs_hba *hba)
 {
-       struct scsi_device *sdev;
+       const struct scsi_device *sdev;
        u32 pending = 0;
 
        lockdep_assert_held(hba->host->host_lock);
@@ -2080,14 +2080,15 @@ static inline int ufshcd_monitor_opcode2dir(u8 opcode)
 static inline bool ufshcd_should_inform_monitor(struct ufs_hba *hba,
                                                struct ufshcd_lrb *lrbp)
 {
-       struct ufs_hba_monitor *m = &hba->monitor;
+       const struct ufs_hba_monitor *m = &hba->monitor;
 
        return (m->enabled && lrbp && lrbp->cmd &&
                (!m->chunk_size || m->chunk_size == lrbp->cmd->sdb.length) &&
                ktime_before(hba->monitor.enabled_ts, lrbp->issue_time_stamp));
 }
 
-static void ufshcd_start_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
+static void ufshcd_start_monitor(struct ufs_hba *hba,
+                                const struct ufshcd_lrb *lrbp)
 {
        int dir = ufshcd_monitor_opcode2dir(*lrbp->cmd->cmnd);
        unsigned long flags;
@@ -2098,14 +2099,14 @@ static void ufshcd_start_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
        spin_unlock_irqrestore(hba->host->host_lock, flags);
 }
 
-static void ufshcd_update_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
+static void ufshcd_update_monitor(struct ufs_hba *hba, const struct ufshcd_lrb *lrbp)
 {
        int dir = ufshcd_monitor_opcode2dir(*lrbp->cmd->cmnd);
        unsigned long flags;
 
        spin_lock_irqsave(hba->host->host_lock, flags);
        if (dir >= 0 && hba->monitor.nr_queued[dir] > 0) {
-               struct request *req = scsi_cmd_to_rq(lrbp->cmd);
+               const struct request *req = scsi_cmd_to_rq(lrbp->cmd);
                struct ufs_hba_monitor *m = &hba->monitor;
                ktime_t now, inc, lat;
 
@@ -2227,6 +2228,8 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba)
        int err;
 
        hba->capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES);
+       if (hba->quirks & UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS)
+               hba->capabilities &= ~MASK_64_ADDRESSING_SUPPORT;
 
        /* nutrs and nutmrs are 0 based values */
        hba->nutrs = (hba->capabilities & MASK_TRANSFER_REQUESTS_SLOTS) + 1;
@@ -3073,7 +3076,7 @@ static int ufshcd_query_flag_retry(struct ufs_hba *hba,
 
        if (ret)
                dev_err(hba->dev,
-                       "%s: query attribute, opcode %d, idn %d, failed with error %d after %d retires\n",
+                       "%s: query attribute, opcode %d, idn %d, failed with error %d after %d retries\n",
                        __func__, opcode, idn, ret, retries);
        return ret;
 }
@@ -3241,7 +3244,7 @@ int ufshcd_query_attr_retry(struct ufs_hba *hba,
 
        if (ret)
                dev_err(hba->dev,
-                       "%s: query attribute, idn %d, failed with error %d after %d retires\n",
+                       "%s: query attribute, idn %d, failed with error %d after %d retries\n",
                        __func__, idn, ret, QUERY_REQ_RETRIES);
        return ret;
 }
@@ -3812,7 +3815,7 @@ int ufshcd_dme_configure_adapt(struct ufs_hba *hba,
 {
        int ret;
 
-       if (agreed_gear != UFS_HS_G4)
+       if (agreed_gear < UFS_HS_G4)
                adapt_val = PA_NO_ADAPT;
 
        ret = ufshcd_dme_set(hba,
@@ -4101,7 +4104,7 @@ out_unlock:
  *
  * Returns 0 on success, non-zero value on failure
  */
-static int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode)
+int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode)
 {
        struct uic_command uic_cmd = {0};
        int ret;
@@ -4126,6 +4129,7 @@ static int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode)
 out:
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufshcd_uic_change_pwr_mode);
 
 int ufshcd_link_recovery(struct ufs_hba *hba)
 {
@@ -4268,8 +4272,13 @@ static int ufshcd_get_max_pwr_mode(struct ufs_hba *hba)
        if (hba->max_pwr_info.is_valid)
                return 0;
 
-       pwr_info->pwr_tx = FAST_MODE;
-       pwr_info->pwr_rx = FAST_MODE;
+       if (hba->quirks & UFSHCD_QUIRK_HIBERN_FASTAUTO) {
+               pwr_info->pwr_tx = FASTAUTO_MODE;
+               pwr_info->pwr_rx = FASTAUTO_MODE;
+       } else {
+               pwr_info->pwr_tx = FAST_MODE;
+               pwr_info->pwr_rx = FAST_MODE;
+       }
        pwr_info->hs_rate = PA_HS_MODE_B;
 
        /* Get the connected lane count */
@@ -4909,7 +4918,7 @@ static int ufshcd_get_lu_wp(struct ufs_hba *hba,
  *
  */
 static inline void ufshcd_get_lu_power_on_wp_status(struct ufs_hba *hba,
-                                                   struct scsi_device *sdev)
+                                                   const struct scsi_device *sdev)
 {
        if (hba->dev_info.f_power_on_wp_en &&
            !hba->dev_info.is_lu_power_on_wp) {
@@ -5428,8 +5437,8 @@ int ufshcd_write_ee_control(struct ufs_hba *hba)
        return err;
 }
 
-int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask,
-                            u16 set, u16 clr)
+int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask,
+                            const u16 *other_mask, u16 set, u16 clr)
 {
        u16 new_mask, ee_ctrl_mask;
        int err = 0;
@@ -7366,7 +7375,8 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd)
  *
  * Returns calculated max ICC level for specific regulator
  */
-static u32 ufshcd_get_max_icc_level(int sup_curr_uA, u32 start_scan, char *buff)
+static u32 ufshcd_get_max_icc_level(int sup_curr_uA, u32 start_scan,
+                                   const char *buff)
 {
        int i;
        int curr_uA;
@@ -7413,7 +7423,7 @@ static u32 ufshcd_get_max_icc_level(int sup_curr_uA, u32 start_scan, char *buff)
  * Returns calculated ICC level
  */
 static u32 ufshcd_find_max_sup_active_icc_level(struct ufs_hba *hba,
-                                                       u8 *desc_buf, int len)
+                                               const u8 *desc_buf, int len)
 {
        u32 icc_level = 0;
 
@@ -7563,7 +7573,7 @@ out:
        return ret;
 }
 
-static void ufshcd_wb_probe(struct ufs_hba *hba, u8 *desc_buf)
+static void ufshcd_wb_probe(struct ufs_hba *hba, const u8 *desc_buf)
 {
        struct ufs_dev_info *dev_info = &hba->dev_info;
        u8 lun;
@@ -7634,7 +7644,7 @@ wb_disabled:
        hba->caps &= ~UFSHCD_CAP_WB_EN;
 }
 
-static void ufshcd_temp_notif_probe(struct ufs_hba *hba, u8 *desc_buf)
+static void ufshcd_temp_notif_probe(struct ufs_hba *hba, const u8 *desc_buf)
 {
        struct ufs_dev_info *dev_info = &hba->dev_info;
        u32 ext_ufs_feature;
@@ -7868,7 +7878,7 @@ static int ufshcd_quirk_tune_host_pa_tactivate(struct ufs_hba *hba)
        u32 granularity, peer_granularity;
        u32 pa_tactivate, peer_pa_tactivate;
        u32 pa_tactivate_us, peer_pa_tactivate_us;
-       u8 gran_to_us_table[] = {1, 4, 8, 16, 32, 100};
+       static const u8 gran_to_us_table[] = {1, 4, 8, 16, 32, 100};
 
        ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_GRANULARITY),
                                  &granularity);
@@ -7985,7 +7995,7 @@ struct ufs_ref_clk {
        enum ufs_ref_clk_freq val;
 };
 
-static struct ufs_ref_clk ufs_ref_clk_freqs[] = {
+static const struct ufs_ref_clk ufs_ref_clk_freqs[] = {
        {19200000, REF_CLK_FREQ_19_2_MHZ},
        {26000000, REF_CLK_FREQ_26_MHZ},
        {38400000, REF_CLK_FREQ_38_4_MHZ},
@@ -8427,7 +8437,7 @@ static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on)
        return ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on);
 }
 
-static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg)
+int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg)
 {
        int ret = 0;
 
@@ -8443,6 +8453,7 @@ static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg)
 out:
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufshcd_get_vreg);
 
 static int ufshcd_init_vreg(struct ufs_hba *hba)
 {
index 8259022..4cc2dbd 100644 (file)
@@ -92,6 +92,18 @@ config SCSI_UFS_HISI
          Select this if you have UFS controller on Hisilicon chipset.
          If unsure, say N.
 
+config SCSI_UFS_RENESAS
+       tristate "Renesas specific hooks to UFS controller platform driver"
+       depends on (ARCH_RENESAS || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM
+       help
+         This selects the Renesas specific additions to UFSHCD platform driver.
+         UFS host on Renesas needs some vendor specific configuration before
+         accessing the hardware.
+
+         Select this if you have UFS controller on Renesas chipset.
+
+         If unsure, say N.
+
 config SCSI_UFS_TI_J721E
        tristate "TI glue layer for Cadence UFS Controller"
        depends on OF && HAS_IOMEM && (ARCH_K3 || COMPILE_TEST)
index e4be542..7717ca9 100644 (file)
@@ -11,4 +11,5 @@ obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
 obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
 obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o
 obj-$(CONFIG_SCSI_UFS_MEDIATEK) += ufs-mediatek.o
+obj-$(CONFIG_SCSI_UFS_RENESAS) += ufs-renesas.o
 obj-$(CONFIG_SCSI_UFS_TI_J721E) += ti-j721e-ufs.o
index a81d8cb..f971569 100644 (file)
 #define HCI_ERR_EN_DME_LAYER   0x88
 #define HCI_CLKSTOP_CTRL       0xB0
 #define REFCLKOUT_STOP         BIT(4)
+#define MPHY_APBCLK_STOP       BIT(3)
 #define REFCLK_STOP            BIT(2)
 #define UNIPRO_MCLK_STOP       BIT(1)
 #define UNIPRO_PCLK_STOP       BIT(0)
 #define CLK_STOP_MASK          (REFCLKOUT_STOP | REFCLK_STOP |\
-                                UNIPRO_MCLK_STOP |\
+                                UNIPRO_MCLK_STOP | MPHY_APBCLK_STOP|\
                                 UNIPRO_PCLK_STOP)
 #define HCI_MISC               0xB4
 #define REFCLK_CTRL_EN         BIT(7)
@@ -135,15 +136,9 @@ enum {
 /*
  * UNIPRO registers
  */
-#define UNIPRO_COMP_VERSION                    0x000
-#define UNIPRO_DME_PWR_REQ                     0x090
-#define UNIPRO_DME_PWR_REQ_POWERMODE           0x094
-#define UNIPRO_DME_PWR_REQ_LOCALL2TIMER0       0x098
-#define UNIPRO_DME_PWR_REQ_LOCALL2TIMER1       0x09C
-#define UNIPRO_DME_PWR_REQ_LOCALL2TIMER2       0x0A0
-#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER0      0x0A4
-#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER1      0x0A8
-#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER2      0x0AC
+#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0        0x78B8
+#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1        0x78BC
+#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2        0x78C0
 
 /*
  * UFS Protector registers
@@ -157,7 +152,6 @@ enum {
 
 #define CNTR_DIV_VAL 40
 
-static struct exynos_ufs_drv_data exynos_ufs_drvs;
 static void exynos_ufs_auto_ctrl_hcc(struct exynos_ufs *ufs, bool en);
 static void exynos_ufs_ctrl_clkstop(struct exynos_ufs *ufs, bool en);
 
@@ -657,8 +651,9 @@ static void exynos_ufs_config_phy_cap_attr(struct exynos_ufs *ufs)
 
                        if (attr->rx_min_actv_time_cap)
                                ufshcd_dme_set(hba,
-                                       UIC_ARG_MIB_SEL(RX_MIN_ACTIVATETIME_CAP,
-                                               i), attr->rx_min_actv_time_cap);
+                                       UIC_ARG_MIB_SEL(
+                                       RX_MIN_ACTIVATETIME_CAPABILITY, i),
+                                       attr->rx_min_actv_time_cap);
 
                        if (attr->rx_hibern8_time_cap)
                                ufshcd_dme_set(hba,
@@ -1473,7 +1468,100 @@ static int exynosauto_ufs_vh_init(struct ufs_hba *hba)
        return 0;
 }
 
-static struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
+static int fsd_ufs_pre_link(struct exynos_ufs *ufs)
+{
+       int i;
+       struct ufs_hba *hba = ufs->hba;
+
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_CLK_PERIOD),
+                      DIV_ROUND_UP(NSEC_PER_SEC,  ufs->mclk_rate));
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0x201), 0x12);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
+
+       for_each_ufs_tx_lane(ufs, i) {
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xAA, i),
+                              DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x8F, i), 0x3F);
+       }
+
+       for_each_ufs_rx_lane(ufs, i) {
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x12, i),
+                              DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x5C, i), 0x38);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x0F, i), 0x0);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x65, i), 0x1);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x69, i), 0x1);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x21, i), 0x0);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x22, i), 0x0);
+       }
+
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_AUTOMODE_THLD), 0x4E20);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE), 0x2e820183);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0x0);
+
+       exynos_ufs_establish_connt(ufs);
+
+       return 0;
+}
+
+static int fsd_ufs_post_link(struct exynos_ufs *ufs)
+{
+       int i;
+       struct ufs_hba *hba = ufs->hba;
+       u32 hw_cap_min_tactivate;
+       u32 peer_rx_min_actv_time_cap;
+       u32 max_rx_hibern8_time_cap;
+
+       ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(0x8F, 4),
+                       &hw_cap_min_tactivate); /* HW Capability of MIN_TACTIVATE */
+       ufshcd_dme_get(hba, UIC_ARG_MIB(PA_TACTIVATE),
+                       &peer_rx_min_actv_time_cap);    /* PA_TActivate */
+       ufshcd_dme_get(hba, UIC_ARG_MIB(PA_HIBERN8TIME),
+                       &max_rx_hibern8_time_cap);      /* PA_Hibern8Time */
+
+       if (peer_rx_min_actv_time_cap >= hw_cap_min_tactivate)
+               ufshcd_dme_peer_set(hba, UIC_ARG_MIB(PA_TACTIVATE),
+                                       peer_rx_min_actv_time_cap + 1);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME), max_rx_hibern8_time_cap + 1);
+
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_MODE), 0x01);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_SAVECONFIGTIME), 0xFA);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_MODE), 0x00);
+
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
+
+       for_each_ufs_rx_lane(ufs, i) {
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x35, i), 0x05);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x73, i), 0x01);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x41, i), 0x02);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x42, i), 0xAC);
+       }
+
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
+
+       return 0;
+}
+
+static int fsd_ufs_pre_pwr_change(struct exynos_ufs *ufs,
+                                       struct ufs_pa_layer_attr *pwr)
+{
+       struct ufs_hba *hba = ufs->hba;
+
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXTERMINATION), 0x1);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXTERMINATION), 0x1);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), 12000);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), 32000);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), 16000);
+
+       unipro_writel(ufs, 12000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0);
+       unipro_writel(ufs, 32000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1);
+       unipro_writel(ufs, 16000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2);
+
+       return 0;
+}
+
+static const struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
        .name                           = "exynos_ufs",
        .init                           = exynos_ufs_init,
        .hce_enable_notify              = exynos_ufs_hce_enable_notify,
@@ -1545,7 +1633,7 @@ static struct exynos_ufs_uic_attr exynos7_uic_attr = {
        .pa_dbg_option_suite            = 0x30103,
 };
 
-static struct exynos_ufs_drv_data exynosauto_ufs_drvs = {
+static const struct exynos_ufs_drv_data exynosauto_ufs_drvs = {
        .uic_attr               = &exynos7_uic_attr,
        .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
                                  UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR |
@@ -1561,7 +1649,7 @@ static struct exynos_ufs_drv_data exynosauto_ufs_drvs = {
        .post_pwr_change        = exynosauto_ufs_post_pwr_change,
 };
 
-static struct exynos_ufs_drv_data exynosauto_ufs_vh_drvs = {
+static const struct exynos_ufs_drv_data exynosauto_ufs_vh_drvs = {
        .vops                   = &ufs_hba_exynosauto_vh_ops,
        .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
                                  UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR |
@@ -1573,7 +1661,7 @@ static struct exynos_ufs_drv_data exynosauto_ufs_vh_drvs = {
        .opts                   = EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX,
 };
 
-static struct exynos_ufs_drv_data exynos_ufs_drvs = {
+static const struct exynos_ufs_drv_data exynos_ufs_drvs = {
        .uic_attr               = &exynos7_uic_attr,
        .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
                                  UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR |
@@ -1595,6 +1683,47 @@ static struct exynos_ufs_drv_data exynos_ufs_drvs = {
        .post_pwr_change        = exynos7_ufs_post_pwr_change,
 };
 
+static struct exynos_ufs_uic_attr fsd_uic_attr = {
+       .tx_trailingclks                = 0x10,
+       .tx_dif_p_nsec                  = 3000000,      /* unit: ns */
+       .tx_dif_n_nsec                  = 1000000,      /* unit: ns */
+       .tx_high_z_cnt_nsec             = 20000,        /* unit: ns */
+       .tx_base_unit_nsec              = 100000,       /* unit: ns */
+       .tx_gran_unit_nsec              = 4000,         /* unit: ns */
+       .tx_sleep_cnt                   = 1000,         /* unit: ns */
+       .tx_min_activatetime            = 0xa,
+       .rx_filler_enable               = 0x2,
+       .rx_dif_p_nsec                  = 1000000,      /* unit: ns */
+       .rx_hibern8_wait_nsec           = 4000000,      /* unit: ns */
+       .rx_base_unit_nsec              = 100000,       /* unit: ns */
+       .rx_gran_unit_nsec              = 4000,         /* unit: ns */
+       .rx_sleep_cnt                   = 1280,         /* unit: ns */
+       .rx_stall_cnt                   = 320,          /* unit: ns */
+       .rx_hs_g1_sync_len_cap          = SYNC_LEN_COARSE(0xf),
+       .rx_hs_g2_sync_len_cap          = SYNC_LEN_COARSE(0xf),
+       .rx_hs_g3_sync_len_cap          = SYNC_LEN_COARSE(0xf),
+       .rx_hs_g1_prep_sync_len_cap     = PREP_LEN(0xf),
+       .rx_hs_g2_prep_sync_len_cap     = PREP_LEN(0xf),
+       .rx_hs_g3_prep_sync_len_cap     = PREP_LEN(0xf),
+       .pa_dbg_option_suite            = 0x2E820183,
+};
+
+struct exynos_ufs_drv_data fsd_ufs_drvs = {
+       .uic_attr               = &fsd_uic_attr,
+       .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
+                                 UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR |
+                                 UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR |
+                                 UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING |
+                                 UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR,
+       .opts                   = EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL |
+                                 EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
+                                 EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
+                                 EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX,
+       .pre_link               = fsd_ufs_pre_link,
+       .post_link              = fsd_ufs_post_link,
+       .pre_pwr_change         = fsd_ufs_pre_pwr_change,
+};
+
 static const struct of_device_id exynos_ufs_of_match[] = {
        { .compatible = "samsung,exynos7-ufs",
          .data       = &exynos_ufs_drvs },
@@ -1602,6 +1731,8 @@ static const struct of_device_id exynos_ufs_of_match[] = {
          .data       = &exynosauto_ufs_drvs },
        { .compatible = "samsung,exynosautov9-ufs-vh",
          .data       = &exynosauto_ufs_vh_drvs },
+       { .compatible = "tesla,fsd-ufs",
+         .data       = &fsd_ufs_drvs },
        {},
 };
 
index 0b0a3d5..a4bd664 100644 (file)
@@ -22,6 +22,7 @@
 #define PA_DBG_RXPHY_CFGUPDT   0x9519
 #define PA_DBG_MODE            0x9529
 #define PA_DBG_SKIP_RESET_PHY  0x9539
+#define PA_DBG_AUTOMODE_THLD   0x9536
 #define PA_DBG_OV_TM           0x9540
 #define PA_DBG_SKIP_LINE_RESET 0x9541
 #define PA_DBG_LINE_RESET_REQ  0x9543
index beabc3c..c958279 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/of_device.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/pm_qos.h>
 #include <linux/regulator/consumer.h>
 #include <linux/reset.h>
 #include <linux/sched/clock.h>
 #define CREATE_TRACE_POINTS
 #include "ufs-mediatek-trace.h"
 
-#define ufs_mtk_smc(cmd, val, res) \
-       arm_smccc_smc(MTK_SIP_UFS_CONTROL, \
-                     cmd, val, 0, 0, 0, 0, 0, &(res))
-
-#define ufs_mtk_va09_pwr_ctrl(res, on) \
-       ufs_mtk_smc(UFS_MTK_SIP_VA09_PWR_CTRL, on, res)
-
-#define ufs_mtk_crypto_ctrl(res, enable) \
-       ufs_mtk_smc(UFS_MTK_SIP_CRYPTO_CTRL, enable, res)
-
-#define ufs_mtk_ref_clk_notify(on, res) \
-       ufs_mtk_smc(UFS_MTK_SIP_REF_CLK_NOTIFICATION, on, res)
-
-#define ufs_mtk_device_reset_ctrl(high, res) \
-       ufs_mtk_smc(UFS_MTK_SIP_DEVICE_RESET, high, res)
-
 static const struct ufs_dev_quirk ufs_mtk_dev_fixups[] = {
-       { .wmanufacturerid = UFS_VENDOR_MICRON,
+       { .wmanufacturerid = UFS_ANY_VENDOR,
          .model = UFS_ANY_MODEL,
-         .quirk = UFS_DEVICE_QUIRK_DELAY_AFTER_LPM },
+         .quirk = UFS_DEVICE_QUIRK_DELAY_AFTER_LPM |
+               UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM },
        { .wmanufacturerid = UFS_VENDOR_SKHYNIX,
          .model = "H9HQ21AFAMZDAR",
          .quirk = UFS_DEVICE_QUIRK_SUPPORT_EXTENDED_FEATURES },
@@ -82,6 +68,13 @@ static bool ufs_mtk_is_broken_vcc(struct ufs_hba *hba)
        return !!(host->caps & UFS_MTK_CAP_BROKEN_VCC);
 }
 
+static bool ufs_mtk_is_pmc_via_fastauto(struct ufs_hba *hba)
+{
+       struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+
+       return (host->caps & UFS_MTK_CAP_PMC_VIA_FASTAUTO);
+}
+
 static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable)
 {
        u32 tmp;
@@ -191,6 +184,14 @@ static int ufs_mtk_hce_enable_notify(struct ufs_hba *hba,
                        hba->capabilities &= ~MASK_AUTO_HIBERN8_SUPPORT;
                        hba->ahit = 0;
                }
+
+               /*
+                * Turn on CLK_CG early to bypass abnormal ERR_CHK signal
+                * to prevent host hang issue
+                */
+               ufshcd_writel(hba,
+                             ufshcd_readl(hba, REG_UFS_XOUFS_CTRL) | 0x80,
+                             REG_UFS_XOUFS_CTRL);
        }
 
        return 0;
@@ -244,8 +245,9 @@ static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba, bool on)
        if (host->ref_clk_enabled == on)
                return 0;
 
+       ufs_mtk_ref_clk_notify(on, PRE_CHANGE, res);
+
        if (on) {
-               ufs_mtk_ref_clk_notify(on, res);
                ufshcd_writel(hba, REFCLK_REQUEST, REG_UFS_REFCLK_CTRL);
        } else {
                ufshcd_delay_us(host->ref_clk_gating_wait_us, 10);
@@ -267,7 +269,7 @@ static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba, bool on)
 
        dev_err(hba->dev, "missing ack of refclk req, reg: 0x%x\n", value);
 
-       ufs_mtk_ref_clk_notify(host->ref_clk_enabled, res);
+       ufs_mtk_ref_clk_notify(host->ref_clk_enabled, POST_CHANGE, res);
 
        return -ETIMEDOUT;
 
@@ -275,8 +277,8 @@ out:
        host->ref_clk_enabled = on;
        if (on)
                ufshcd_delay_us(host->ref_clk_ungating_wait_us, 10);
-       else
-               ufs_mtk_ref_clk_notify(on, res);
+
+       ufs_mtk_ref_clk_notify(on, POST_CHANGE, res);
 
        return 0;
 }
@@ -579,20 +581,38 @@ static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
        if (of_property_read_bool(np, "mediatek,ufs-broken-vcc"))
                host->caps |= UFS_MTK_CAP_BROKEN_VCC;
 
+       if (of_property_read_bool(np, "mediatek,ufs-pmc-via-fastauto"))
+               host->caps |= UFS_MTK_CAP_PMC_VIA_FASTAUTO;
+
        dev_info(hba->dev, "caps: 0x%x", host->caps);
 }
 
-static void ufs_mtk_scale_perf(struct ufs_hba *hba, bool up)
+static void ufs_mtk_boost_pm_qos(struct ufs_hba *hba, bool boost)
 {
        struct ufs_mtk_host *host = ufshcd_get_variant(hba);
 
-       ufs_mtk_boost_crypt(hba, up);
-       ufs_mtk_setup_ref_clk(hba, up);
+       if (!host || !host->pm_qos_init)
+               return;
+
+       cpu_latency_qos_update_request(&host->pm_qos_req,
+                                      boost ? 0 : PM_QOS_DEFAULT_VALUE);
+}
 
-       if (up)
+static void ufs_mtk_pwr_ctrl(struct ufs_hba *hba, bool on)
+{
+       struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+
+       if (on) {
                phy_power_on(host->mphy);
-       else
+               ufs_mtk_setup_ref_clk(hba, on);
+               ufs_mtk_boost_crypt(hba, on);
+               ufs_mtk_boost_pm_qos(hba, on);
+       } else {
+               ufs_mtk_boost_pm_qos(hba, on);
+               ufs_mtk_boost_crypt(hba, on);
+               ufs_mtk_setup_ref_clk(hba, on);
                phy_power_off(host->mphy);
+       }
 }
 
 /**
@@ -637,9 +657,9 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
                }
 
                if (clk_pwr_off)
-                       ufs_mtk_scale_perf(hba, false);
+                       ufs_mtk_pwr_ctrl(hba, false);
        } else if (on && status == POST_CHANGE) {
-               ufs_mtk_scale_perf(hba, true);
+               ufs_mtk_pwr_ctrl(hba, true);
        }
 
        return ret;
@@ -675,6 +695,73 @@ static u32 ufs_mtk_get_ufs_hci_version(struct ufs_hba *hba)
        return hba->ufs_version;
 }
 
+#define MAX_VCC_NAME 30
+static int ufs_mtk_vreg_fix_vcc(struct ufs_hba *hba)
+{
+       struct ufs_vreg_info *info = &hba->vreg_info;
+       struct device_node *np = hba->dev->of_node;
+       struct device *dev = hba->dev;
+       char vcc_name[MAX_VCC_NAME];
+       struct arm_smccc_res res;
+       int err, ver;
+
+       if (hba->vreg_info.vcc)
+               return 0;
+
+       if (of_property_read_bool(np, "mediatek,ufs-vcc-by-num")) {
+               ufs_mtk_get_vcc_num(res);
+               if (res.a1 > UFS_VCC_NONE && res.a1 < UFS_VCC_MAX)
+                       snprintf(vcc_name, MAX_VCC_NAME, "vcc-opt%lu", res.a1);
+               else
+                       return -ENODEV;
+       } else if (of_property_read_bool(np, "mediatek,ufs-vcc-by-ver")) {
+               ver = (hba->dev_info.wspecversion & 0xF00) >> 8;
+               snprintf(vcc_name, MAX_VCC_NAME, "vcc-ufs%u", ver);
+       } else {
+               return 0;
+       }
+
+       err = ufshcd_populate_vreg(dev, vcc_name, &info->vcc);
+       if (err)
+               return err;
+
+       err = ufshcd_get_vreg(dev, info->vcc);
+       if (err)
+               return err;
+
+       err = regulator_enable(info->vcc->reg);
+       if (!err) {
+               info->vcc->enabled = true;
+               dev_info(dev, "%s: %s enabled\n", __func__, vcc_name);
+       }
+
+       return err;
+}
+
+static void ufs_mtk_vreg_fix_vccqx(struct ufs_hba *hba)
+{
+       struct ufs_vreg_info *info = &hba->vreg_info;
+       struct ufs_vreg **vreg_on, **vreg_off;
+
+       if (hba->dev_info.wspecversion >= 0x0300) {
+               vreg_on = &info->vccq;
+               vreg_off = &info->vccq2;
+       } else {
+               vreg_on = &info->vccq2;
+               vreg_off = &info->vccq;
+       }
+
+       if (*vreg_on)
+               (*vreg_on)->always_on = true;
+
+       if (*vreg_off) {
+               regulator_disable((*vreg_off)->reg);
+               devm_kfree(hba->dev, (*vreg_off)->name);
+               devm_kfree(hba->dev, *vreg_off);
+               *vreg_off = NULL;
+       }
+}
+
 /**
  * ufs_mtk_init - find other essential mmio bases
  * @hba: host controller instance
@@ -754,6 +841,26 @@ out:
        return err;
 }
 
+static bool ufs_mtk_pmc_via_fastauto(struct ufs_hba *hba,
+                                    struct ufs_pa_layer_attr *dev_req_params)
+{
+       if (!ufs_mtk_is_pmc_via_fastauto(hba))
+               return false;
+
+       if (dev_req_params->hs_rate == hba->pwr_info.hs_rate)
+               return false;
+
+       if (dev_req_params->pwr_tx != FAST_MODE &&
+           dev_req_params->gear_tx < UFS_HS_G4)
+               return false;
+
+       if (dev_req_params->pwr_rx != FAST_MODE &&
+           dev_req_params->gear_rx < UFS_HS_G4)
+               return false;
+
+       return true;
+}
+
 static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
                                  struct ufs_pa_layer_attr *dev_max_params,
                                  struct ufs_pa_layer_attr *dev_req_params)
@@ -763,8 +870,8 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
        int ret;
 
        ufshcd_init_pwr_dev_param(&host_cap);
-       host_cap.hs_rx_gear = UFS_HS_G4;
-       host_cap.hs_tx_gear = UFS_HS_G4;
+       host_cap.hs_rx_gear = UFS_HS_G5;
+       host_cap.hs_tx_gear = UFS_HS_G5;
 
        ret = ufshcd_get_pwr_dev_param(&host_cap,
                                       dev_max_params,
@@ -774,6 +881,32 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
                        __func__);
        }
 
+       if (ufs_mtk_pmc_via_fastauto(hba, dev_req_params)) {
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXTERMINATION), true);
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXGEAR), UFS_HS_G1);
+
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXTERMINATION), true);
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXGEAR), UFS_HS_G1);
+
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_ACTIVETXDATALANES),
+                              dev_req_params->lane_tx);
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_ACTIVERXDATALANES),
+                              dev_req_params->lane_rx);
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HSSERIES),
+                              dev_req_params->hs_rate);
+
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXHSADAPTTYPE),
+                              PA_NO_ADAPT);
+
+               ret = ufshcd_uic_change_pwr_mode(hba,
+                                       FASTAUTO_MODE << 4 | FASTAUTO_MODE);
+
+               if (ret) {
+                       dev_err(hba->dev, "%s: HSG1B FASTAUTO failed ret=%d\n",
+                               __func__, ret);
+               }
+       }
+
        if (host->hw_ver.major >= 3) {
                ret = ufshcd_dme_configure_adapt(hba,
                                           dev_req_params->gear_tx,
@@ -963,6 +1096,11 @@ static int ufs_mtk_link_set_lpm(struct ufs_hba *hba)
 {
        int err;
 
+       /* Disable reset confirm feature by UniPro */
+       ufshcd_writel(hba,
+                     (ufshcd_readl(hba, REG_UFS_XOUFS_CTRL) & ~0x100),
+                     REG_UFS_XOUFS_CTRL);
+
        err = ufs_mtk_unipro_set_lpm(hba, true);
        if (err) {
                /* Resume UniPro state for following error recovery */
@@ -973,17 +1111,52 @@ static int ufs_mtk_link_set_lpm(struct ufs_hba *hba)
        return 0;
 }
 
-static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
+static void ufs_mtk_vccqx_set_lpm(struct ufs_hba *hba, bool lpm)
+{
+       struct ufs_vreg *vccqx = NULL;
+
+       if (hba->vreg_info.vccq)
+               vccqx = hba->vreg_info.vccq;
+       else
+               vccqx = hba->vreg_info.vccq2;
+
+       regulator_set_mode(vccqx->reg,
+                          lpm ? REGULATOR_MODE_IDLE : REGULATOR_MODE_NORMAL);
+}
+
+static void ufs_mtk_vsx_set_lpm(struct ufs_hba *hba, bool lpm)
+{
+       struct arm_smccc_res res;
+
+       ufs_mtk_device_pwr_ctrl(!lpm,
+                               (unsigned long)hba->dev_info.wspecversion,
+                               res);
+}
+
+static void ufs_mtk_dev_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
 {
-       if (!hba->vreg_info.vccq2 || !hba->vreg_info.vcc)
+       if (!hba->vreg_info.vccq && !hba->vreg_info.vccq2)
+               return;
+
+       /* Skip if VCC is assumed always-on */
+       if (!hba->vreg_info.vcc)
+               return;
+
+       /* Bypass LPM when device is still active */
+       if (lpm && ufshcd_is_ufs_dev_active(hba))
+               return;
+
+       /* Bypass LPM if VCC is enabled */
+       if (lpm && hba->vreg_info.vcc->enabled)
                return;
 
-       if (lpm && !hba->vreg_info.vcc->enabled)
-               regulator_set_mode(hba->vreg_info.vccq2->reg,
-                                  REGULATOR_MODE_IDLE);
-       else if (!lpm)
-               regulator_set_mode(hba->vreg_info.vccq2->reg,
-                                  REGULATOR_MODE_NORMAL);
+       if (lpm) {
+               ufs_mtk_vccqx_set_lpm(hba, lpm);
+               ufs_mtk_vsx_set_lpm(hba, lpm);
+       } else {
+               ufs_mtk_vsx_set_lpm(hba, lpm);
+               ufs_mtk_vccqx_set_lpm(hba, lpm);
+       }
 }
 
 static void ufs_mtk_auto_hibern8_disable(struct ufs_hba *hba)
@@ -1026,7 +1199,6 @@ static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,
                 * ufshcd_suspend() re-enabling regulators while vreg is still
                 * in low-power mode.
                 */
-               ufs_mtk_vreg_set_lpm(hba, true);
                err = ufs_mtk_mphy_power_on(hba, false);
                if (err)
                        goto fail;
@@ -1035,6 +1207,8 @@ static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,
        if (ufshcd_is_link_off(hba))
                ufs_mtk_device_reset_ctrl(0, res);
 
+       ufs_mtk_host_pwr_ctrl(HOST_PWR_HCI, false, res);
+
        return 0;
 fail:
        /*
@@ -1049,13 +1223,17 @@ fail:
 static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 {
        int err;
+       struct arm_smccc_res res;
+
+       if (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL)
+               ufs_mtk_dev_vreg_set_lpm(hba, false);
+
+       ufs_mtk_host_pwr_ctrl(HOST_PWR_HCI, true, res);
 
        err = ufs_mtk_mphy_power_on(hba, true);
        if (err)
                goto fail;
 
-       ufs_mtk_vreg_set_lpm(hba, false);
-
        if (ufshcd_is_link_hibern8(hba)) {
                err = ufs_mtk_link_set_hpm(hba);
                if (err)
@@ -1087,8 +1265,10 @@ static int ufs_mtk_apply_dev_quirks(struct ufs_hba *hba)
        struct ufs_dev_info *dev_info = &hba->dev_info;
        u16 mid = dev_info->wmanufacturerid;
 
-       if (mid == UFS_VENDOR_SAMSUNG)
+       if (mid == UFS_VENDOR_SAMSUNG) {
                ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TACTIVATE), 6);
+               ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME), 10);
+       }
 
        /*
         * Decide waiting time before gating reference clock and
@@ -1104,7 +1284,6 @@ static int ufs_mtk_apply_dev_quirks(struct ufs_hba *hba)
        else
                ufs_mtk_setup_ref_clk_wait_us(hba,
                                              REFCLK_DEFAULT_WAIT_US);
-
        return 0;
 }
 
@@ -1122,6 +1301,9 @@ static void ufs_mtk_fixup_dev_quirks(struct ufs_hba *hba)
                hba->dev_quirks &= ~(UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM |
                        UFS_DEVICE_QUIRK_DELAY_AFTER_LPM);
        }
+
+       ufs_mtk_vreg_fix_vcc(hba);
+       ufs_mtk_vreg_fix_vccqx(hba);
 }
 
 static void ufs_mtk_event_notify(struct ufs_hba *hba,
@@ -1220,9 +1402,59 @@ static int ufs_mtk_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int ufs_mtk_system_suspend(struct device *dev)
+{
+       struct ufs_hba *hba = dev_get_drvdata(dev);
+       int ret;
+
+       ret = ufshcd_system_suspend(dev);
+       if (ret)
+               return ret;
+
+       ufs_mtk_dev_vreg_set_lpm(hba, true);
+
+       return 0;
+}
+
+static int ufs_mtk_system_resume(struct device *dev)
+{
+       struct ufs_hba *hba = dev_get_drvdata(dev);
+
+       ufs_mtk_dev_vreg_set_lpm(hba, false);
+
+       return ufshcd_system_resume(dev);
+}
+#endif
+
+static int ufs_mtk_runtime_suspend(struct device *dev)
+{
+       struct ufs_hba *hba = dev_get_drvdata(dev);
+       int ret = 0;
+
+       ret = ufshcd_runtime_suspend(dev);
+       if (ret)
+               return ret;
+
+       ufs_mtk_dev_vreg_set_lpm(hba, true);
+
+       return 0;
+}
+
+static int ufs_mtk_runtime_resume(struct device *dev)
+{
+       struct ufs_hba *hba = dev_get_drvdata(dev);
+
+       ufs_mtk_dev_vreg_set_lpm(hba, false);
+
+       return ufshcd_runtime_resume(dev);
+}
+
 static const struct dev_pm_ops ufs_mtk_pm_ops = {
-       SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
-       SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(ufs_mtk_system_suspend,
+                               ufs_mtk_system_resume)
+       SET_RUNTIME_PM_OPS(ufs_mtk_runtime_suspend,
+                          ufs_mtk_runtime_resume, NULL)
        .prepare         = ufshcd_suspend_prepare,
        .complete        = ufshcd_resume_complete,
 };
index 414dca8..aa26d41 100644 (file)
@@ -7,11 +7,13 @@
 #define _UFS_MEDIATEK_H
 
 #include <linux/bitops.h>
+#include <linux/pm_qos.h>
 #include <linux/soc/mediatek/mtk_sip_svc.h>
 
 /*
  * Vendor specific UFSHCI Registers
  */
+#define REG_UFS_XOUFS_CTRL          0x140
 #define REG_UFS_REFCLK_CTRL         0x144
 #define REG_UFS_EXTREG              0x2100
 #define REG_UFS_MPHYCTRL            0x2200
@@ -83,6 +85,9 @@ enum {
 #define UFS_MTK_SIP_DEVICE_RESET          BIT(1)
 #define UFS_MTK_SIP_CRYPTO_CTRL           BIT(2)
 #define UFS_MTK_SIP_REF_CLK_NOTIFICATION  BIT(3)
+#define UFS_MTK_SIP_HOST_PWR_CTRL         BIT(5)
+#define UFS_MTK_SIP_GET_VCC_NUM           BIT(6)
+#define UFS_MTK_SIP_DEVICE_PWR_CTRL       BIT(7)
 
 /*
  * VS_DEBUGCLOCKENABLE
@@ -108,6 +113,7 @@ enum ufs_mtk_host_caps {
        UFS_MTK_CAP_VA09_PWR_CTRL              = 1 << 1,
        UFS_MTK_CAP_DISABLE_AH8                = 1 << 2,
        UFS_MTK_CAP_BROKEN_VCC                 = 1 << 3,
+       UFS_MTK_CAP_PMC_VIA_FASTAUTO           = 1 << 6,
 };
 
 struct ufs_mtk_crypt_cfg {
@@ -126,6 +132,7 @@ struct ufs_mtk_hw_ver {
 
 struct ufs_mtk_host {
        struct phy *mphy;
+       struct pm_qos_request pm_qos_req;
        struct regulator *reg_va09;
        struct reset_control *hci_reset;
        struct reset_control *unipro_reset;
@@ -135,6 +142,7 @@ struct ufs_mtk_host {
        struct ufs_mtk_hw_ver hw_ver;
        enum ufs_mtk_host_caps caps;
        bool mphy_powered_on;
+       bool pm_qos_init;
        bool unipro_lpm;
        bool ref_clk_enabled;
        u16 ref_clk_ungating_wait_us;
@@ -142,4 +150,70 @@ struct ufs_mtk_host {
        u32 ip_ver;
 };
 
+/*
+ * Multi-VCC by Numbering
+ */
+enum ufs_mtk_vcc_num {
+       UFS_VCC_NONE = 0,
+       UFS_VCC_1,
+       UFS_VCC_2,
+       UFS_VCC_MAX
+};
+
+/*
+ * Host Power Control options
+ */
+enum {
+       HOST_PWR_HCI = 0,
+       HOST_PWR_MPHY
+};
+
+/*
+ * SMC call wrapper function
+ */
+struct ufs_mtk_smc_arg {
+       unsigned long cmd;
+       struct arm_smccc_res *res;
+       unsigned long v1;
+       unsigned long v2;
+       unsigned long v3;
+       unsigned long v4;
+       unsigned long v5;
+       unsigned long v6;
+       unsigned long v7;
+};
+
+static void _ufs_mtk_smc(struct ufs_mtk_smc_arg s)
+{
+       arm_smccc_smc(MTK_SIP_UFS_CONTROL,
+                     s.cmd, s.v1, s.v2, s.v3, s.v4, s.v5, s.v6, s.res);
+}
+
+#define ufs_mtk_smc(...) \
+       _ufs_mtk_smc((struct ufs_mtk_smc_arg) {__VA_ARGS__})
+
+/*
+ * SMC call interface
+ */
+#define ufs_mtk_va09_pwr_ctrl(res, on) \
+       ufs_mtk_smc(UFS_MTK_SIP_VA09_PWR_CTRL, &(res), on)
+
+#define ufs_mtk_crypto_ctrl(res, enable) \
+       ufs_mtk_smc(UFS_MTK_SIP_CRYPTO_CTRL, &(res), enable)
+
+#define ufs_mtk_ref_clk_notify(on, stage, res) \
+       ufs_mtk_smc(UFS_MTK_SIP_REF_CLK_NOTIFICATION, &(res), on, stage)
+
+#define ufs_mtk_device_reset_ctrl(high, res) \
+       ufs_mtk_smc(UFS_MTK_SIP_DEVICE_RESET, &(res), high)
+
+#define ufs_mtk_host_pwr_ctrl(opt, on, res) \
+       ufs_mtk_smc(UFS_MTK_SIP_HOST_PWR_CTRL, &(res), opt, on)
+
+#define ufs_mtk_get_vcc_num(res) \
+       ufs_mtk_smc(UFS_MTK_SIP_GET_VCC_NUM, &(res))
+
+#define ufs_mtk_device_pwr_ctrl(on, ufs_ver, res) \
+       ufs_mtk_smc(UFS_MTK_SIP_DEVICE_PWR_CTRL, &(res), on, ufs_ver)
+
 #endif /* !_UFS_MEDIATEK_H */
index f10d466..473fad8 100644 (file)
@@ -58,19 +58,6 @@ static void ufs_qcom_dump_regs_wrapper(struct ufs_hba *hba, int offset, int len,
        ufshcd_dump_regs(hba, offset, len * 4, prefix);
 }
 
-static int ufs_qcom_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes)
-{
-       int err = 0;
-
-       err = ufshcd_dme_get(hba,
-                       UIC_ARG_MIB(PA_CONNECTEDTXDATALANES), tx_lanes);
-       if (err)
-               dev_err(hba->dev, "%s: couldn't read PA_CONNECTEDTXDATALANES %d\n",
-                               __func__, err);
-
-       return err;
-}
-
 static int ufs_qcom_host_clk_get(struct device *dev,
                const char *name, struct clk **clk_out, bool optional)
 {
@@ -194,13 +181,6 @@ out:
        return err;
 }
 
-static int ufs_qcom_link_startup_post_change(struct ufs_hba *hba)
-{
-       u32 tx_lanes;
-
-       return ufs_qcom_get_connected_tx_lanes(hba, &tx_lanes);
-}
-
 static int ufs_qcom_check_hibern8(struct ufs_hba *hba)
 {
        int err;
@@ -570,9 +550,6 @@ static int ufs_qcom_link_startup_notify(struct ufs_hba *hba,
                        err = ufshcd_disable_host_tx_lcc(hba);
 
                break;
-       case POST_CHANGE:
-               ufs_qcom_link_startup_post_change(hba);
-               break;
        default:
                break;
        }
diff --git a/drivers/ufs/host/ufs-renesas.c b/drivers/ufs/host/ufs-renesas.c
new file mode 100644 (file)
index 0000000..f8a5e79
--- /dev/null
@@ -0,0 +1,412 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Renesas UFS host controller driver
+ *
+ * Copyright (C) 2022 Renesas Electronics Corporation
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <ufs/ufshcd.h>
+
+#include "ufshcd-pltfrm.h"
+
+struct ufs_renesas_priv {
+       bool initialized;       /* The hardware needs initialization once */
+};
+
+enum {
+       SET_PHY_INDEX_LO = 0,
+       SET_PHY_INDEX_HI,
+       TIMER_INDEX,
+       MAX_INDEX
+};
+
+enum ufs_renesas_init_param_mode {
+       MODE_RESTORE,
+       MODE_SET,
+       MODE_SAVE,
+       MODE_POLL,
+       MODE_WAIT,
+       MODE_WRITE,
+};
+
+#define PARAM_RESTORE(_reg, _index) \
+               { .mode = MODE_RESTORE, .reg = _reg, .index = _index }
+#define PARAM_SET(_index, _set) \
+               { .mode = MODE_SET, .index = _index, .u.set = _set }
+#define PARAM_SAVE(_reg, _mask, _index) \
+               { .mode = MODE_SAVE, .reg = _reg, .mask = (u32)(_mask), \
+                 .index = _index }
+#define PARAM_POLL(_reg, _expected, _mask) \
+               { .mode = MODE_POLL, .reg = _reg, .u.expected = _expected, \
+                 .mask = (u32)(_mask) }
+#define PARAM_WAIT(_delay_us) \
+               { .mode = MODE_WAIT, .u.delay_us = _delay_us }
+
+#define PARAM_WRITE(_reg, _val) \
+               { .mode = MODE_WRITE, .reg = _reg, .u.val = _val }
+
+#define PARAM_WRITE_D0_D4(_d0, _d4) \
+               PARAM_WRITE(0xd0, _d0), PARAM_WRITE(0xd4, _d4)
+
+#define PARAM_WRITE_800_80C_POLL(_addr, _data_800)             \
+               PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),      \
+               PARAM_WRITE_D0_D4(0x00000800, ((_data_800) << 16) | BIT(8) | (_addr)), \
+               PARAM_WRITE(0xd0, 0x0000080c),                  \
+               PARAM_POLL(0xd4, BIT(8), BIT(8))
+
+#define PARAM_RESTORE_800_80C_POLL(_index)                     \
+               PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),      \
+               PARAM_WRITE(0xd0, 0x00000800),                  \
+               PARAM_RESTORE(0xd4, _index),                    \
+               PARAM_WRITE(0xd0, 0x0000080c),                  \
+               PARAM_POLL(0xd4, BIT(8), BIT(8))
+
+#define PARAM_WRITE_804_80C_POLL(_addr, _data_804)             \
+               PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),      \
+               PARAM_WRITE_D0_D4(0x00000804, ((_data_804) << 16) | BIT(8) | (_addr)), \
+               PARAM_WRITE(0xd0, 0x0000080c),                  \
+               PARAM_POLL(0xd4, BIT(8), BIT(8))
+
+#define PARAM_WRITE_828_82C_POLL(_data_828)                    \
+               PARAM_WRITE_D0_D4(0x0000082c, 0x0f000000),      \
+               PARAM_WRITE_D0_D4(0x00000828, _data_828),       \
+               PARAM_WRITE(0xd0, 0x0000082c),                  \
+               PARAM_POLL(0xd4, _data_828, _data_828)
+
+#define PARAM_WRITE_PHY(_addr16, _data16)                      \
+               PARAM_WRITE(0xf0, 1),                           \
+               PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \
+               PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff), \
+               PARAM_WRITE_800_80C_POLL(0x18, (_data16) & 0xff), \
+               PARAM_WRITE_800_80C_POLL(0x19, ((_data16) >> 8) & 0xff), \
+               PARAM_WRITE_800_80C_POLL(0x1c, 0x01),           \
+               PARAM_WRITE_828_82C_POLL(0x0f000000),           \
+               PARAM_WRITE(0xf0, 0)
+
+#define PARAM_SET_PHY(_addr16, _data16)                                \
+               PARAM_WRITE(0xf0, 1),                           \
+               PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \
+               PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff), \
+               PARAM_WRITE_800_80C_POLL(0x1c, 0x01),           \
+               PARAM_WRITE_828_82C_POLL(0x0f000000),           \
+               PARAM_WRITE_804_80C_POLL(0x1a, 0),              \
+               PARAM_WRITE(0xd0, 0x00000808),                  \
+               PARAM_SAVE(0xd4, 0xff, SET_PHY_INDEX_LO),       \
+               PARAM_WRITE_804_80C_POLL(0x1b, 0),              \
+               PARAM_WRITE(0xd0, 0x00000808),                  \
+               PARAM_SAVE(0xd4, 0xff, SET_PHY_INDEX_HI),       \
+               PARAM_WRITE_828_82C_POLL(0x0f000000),           \
+               PARAM_WRITE(0xf0, 0),                           \
+               PARAM_WRITE(0xf0, 1),                           \
+               PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \
+               PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff), \
+               PARAM_SET(SET_PHY_INDEX_LO, ((_data16 & 0xff) << 16) | BIT(8) | 0x18), \
+               PARAM_RESTORE_800_80C_POLL(SET_PHY_INDEX_LO),   \
+               PARAM_SET(SET_PHY_INDEX_HI, (((_data16 >> 8) & 0xff) << 16) | BIT(8) | 0x19), \
+               PARAM_RESTORE_800_80C_POLL(SET_PHY_INDEX_HI),   \
+               PARAM_WRITE_800_80C_POLL(0x1c, 0x01),           \
+               PARAM_WRITE_828_82C_POLL(0x0f000000),           \
+               PARAM_WRITE(0xf0, 0)
+
+#define PARAM_INDIRECT_WRITE(_gpio, _addr, _data_800)          \
+               PARAM_WRITE(0xf0, _gpio),                       \
+               PARAM_WRITE_800_80C_POLL(_addr, _data_800),     \
+               PARAM_WRITE_828_82C_POLL(0x0f000000),           \
+               PARAM_WRITE(0xf0, 0)
+
+#define PARAM_INDIRECT_POLL(_gpio, _addr, _expected, _mask)    \
+               PARAM_WRITE(0xf0, _gpio),                       \
+               PARAM_WRITE_800_80C_POLL(_addr, 0),             \
+               PARAM_WRITE(0xd0, 0x00000808),                  \
+               PARAM_POLL(0xd4, _expected, _mask),             \
+               PARAM_WRITE(0xf0, 0)
+
+struct ufs_renesas_init_param {
+       enum ufs_renesas_init_param_mode mode;
+       u32 reg;
+       union {
+               u32 expected;
+               u32 delay_us;
+               u32 set;
+               u32 val;
+       } u;
+       u32 mask;
+       u32 index;
+};
+
+/* This setting is for SERIES B */
+static const struct ufs_renesas_init_param ufs_param[] = {
+       PARAM_WRITE(0xc0, 0x49425308),
+       PARAM_WRITE_D0_D4(0x00000104, 0x00000002),
+       PARAM_WAIT(1),
+       PARAM_WRITE_D0_D4(0x00000828, 0x00000200),
+       PARAM_WAIT(1),
+       PARAM_WRITE_D0_D4(0x00000828, 0x00000000),
+       PARAM_WRITE_D0_D4(0x00000104, 0x00000001),
+       PARAM_WRITE_D0_D4(0x00000940, 0x00000001),
+       PARAM_WAIT(1),
+       PARAM_WRITE_D0_D4(0x00000940, 0x00000000),
+
+       PARAM_WRITE(0xc0, 0x49425308),
+       PARAM_WRITE(0xc0, 0x41584901),
+
+       PARAM_WRITE_D0_D4(0x0000080c, 0x00000100),
+       PARAM_WRITE_D0_D4(0x00000804, 0x00000000),
+       PARAM_WRITE(0xd0, 0x0000080c),
+       PARAM_POLL(0xd4, BIT(8), BIT(8)),
+
+       PARAM_WRITE(REG_CONTROLLER_ENABLE, 0x00000001),
+
+       PARAM_WRITE(0xd0, 0x00000804),
+       PARAM_POLL(0xd4, BIT(8) | BIT(6) | BIT(0), BIT(8) | BIT(6) | BIT(0)),
+
+       PARAM_WRITE(0xd0, 0x00000d00),
+       PARAM_SAVE(0xd4, 0x0000ffff, TIMER_INDEX),
+       PARAM_WRITE(0xd4, 0x00000000),
+       PARAM_WRITE_D0_D4(0x0000082c, 0x0f000000),
+       PARAM_WRITE_D0_D4(0x00000828, 0x08000000),
+       PARAM_WRITE(0xd0, 0x0000082c),
+       PARAM_POLL(0xd4, BIT(27), BIT(27)),
+       PARAM_WRITE(0xd0, 0x00000d2c),
+       PARAM_POLL(0xd4, BIT(0), BIT(0)),
+
+       /* phy setup */
+       PARAM_INDIRECT_WRITE(1, 0x01, 0x001f),
+       PARAM_INDIRECT_WRITE(7, 0x5d, 0x0014),
+       PARAM_INDIRECT_WRITE(7, 0x5e, 0x0014),
+       PARAM_INDIRECT_WRITE(7, 0x0d, 0x0003),
+       PARAM_INDIRECT_WRITE(7, 0x0e, 0x0007),
+       PARAM_INDIRECT_WRITE(7, 0x5f, 0x0003),
+       PARAM_INDIRECT_WRITE(7, 0x60, 0x0003),
+       PARAM_INDIRECT_WRITE(7, 0x5b, 0x00a6),
+       PARAM_INDIRECT_WRITE(7, 0x5c, 0x0003),
+
+       PARAM_INDIRECT_POLL(7, 0x3c, 0, BIT(7)),
+       PARAM_INDIRECT_POLL(7, 0x4c, 0, BIT(4)),
+
+       PARAM_INDIRECT_WRITE(1, 0x32, 0x0080),
+       PARAM_INDIRECT_WRITE(1, 0x1f, 0x0001),
+       PARAM_INDIRECT_WRITE(0, 0x2c, 0x0001),
+       PARAM_INDIRECT_WRITE(0, 0x32, 0x0087),
+
+       PARAM_INDIRECT_WRITE(1, 0x4d, 0x0061),
+       PARAM_INDIRECT_WRITE(4, 0x9b, 0x0009),
+       PARAM_INDIRECT_WRITE(4, 0xa6, 0x0005),
+       PARAM_INDIRECT_WRITE(4, 0xa5, 0x0058),
+       PARAM_INDIRECT_WRITE(1, 0x39, 0x0027),
+       PARAM_INDIRECT_WRITE(1, 0x47, 0x004c),
+
+       PARAM_INDIRECT_WRITE(7, 0x0d, 0x0002),
+       PARAM_INDIRECT_WRITE(7, 0x0e, 0x0007),
+
+       PARAM_WRITE_PHY(0x0028, 0x0061),
+       PARAM_WRITE_PHY(0x4014, 0x0061),
+       PARAM_SET_PHY(0x401c, BIT(2)),
+       PARAM_WRITE_PHY(0x4000, 0x0000),
+       PARAM_WRITE_PHY(0x4001, 0x0000),
+
+       PARAM_WRITE_PHY(0x10ae, 0x0001),
+       PARAM_WRITE_PHY(0x10ad, 0x0000),
+       PARAM_WRITE_PHY(0x10af, 0x0001),
+       PARAM_WRITE_PHY(0x10b6, 0x0001),
+       PARAM_WRITE_PHY(0x10ae, 0x0000),
+
+       PARAM_WRITE_PHY(0x10ae, 0x0001),
+       PARAM_WRITE_PHY(0x10ad, 0x0000),
+       PARAM_WRITE_PHY(0x10af, 0x0002),
+       PARAM_WRITE_PHY(0x10b6, 0x0001),
+       PARAM_WRITE_PHY(0x10ae, 0x0000),
+
+       PARAM_WRITE_PHY(0x10ae, 0x0001),
+       PARAM_WRITE_PHY(0x10ad, 0x0080),
+       PARAM_WRITE_PHY(0x10af, 0x0000),
+       PARAM_WRITE_PHY(0x10b6, 0x0001),
+       PARAM_WRITE_PHY(0x10ae, 0x0000),
+
+       PARAM_WRITE_PHY(0x10ae, 0x0001),
+       PARAM_WRITE_PHY(0x10ad, 0x0080),
+       PARAM_WRITE_PHY(0x10af, 0x001a),
+       PARAM_WRITE_PHY(0x10b6, 0x0001),
+       PARAM_WRITE_PHY(0x10ae, 0x0000),
+
+       PARAM_INDIRECT_WRITE(7, 0x70, 0x0016),
+       PARAM_INDIRECT_WRITE(7, 0x71, 0x0016),
+       PARAM_INDIRECT_WRITE(7, 0x72, 0x0014),
+       PARAM_INDIRECT_WRITE(7, 0x73, 0x0014),
+       PARAM_INDIRECT_WRITE(7, 0x74, 0x0000),
+       PARAM_INDIRECT_WRITE(7, 0x75, 0x0000),
+       PARAM_INDIRECT_WRITE(7, 0x76, 0x0010),
+       PARAM_INDIRECT_WRITE(7, 0x77, 0x0010),
+       PARAM_INDIRECT_WRITE(7, 0x78, 0x00ff),
+       PARAM_INDIRECT_WRITE(7, 0x79, 0x0000),
+
+       PARAM_INDIRECT_WRITE(7, 0x19, 0x0007),
+
+       PARAM_INDIRECT_WRITE(7, 0x1a, 0x0007),
+
+       PARAM_INDIRECT_WRITE(7, 0x24, 0x000c),
+
+       PARAM_INDIRECT_WRITE(7, 0x25, 0x000c),
+
+       PARAM_INDIRECT_WRITE(7, 0x62, 0x0000),
+       PARAM_INDIRECT_WRITE(7, 0x63, 0x0000),
+       PARAM_INDIRECT_WRITE(7, 0x5d, 0x0014),
+       PARAM_INDIRECT_WRITE(7, 0x5e, 0x0017),
+       PARAM_INDIRECT_WRITE(7, 0x5d, 0x0004),
+       PARAM_INDIRECT_WRITE(7, 0x5e, 0x0017),
+       PARAM_INDIRECT_POLL(7, 0x55, 0, BIT(6)),
+       PARAM_INDIRECT_POLL(7, 0x41, 0, BIT(7)),
+       /* end of phy setup */
+
+       PARAM_WRITE(0xf0, 0),
+       PARAM_WRITE(0xd0, 0x00000d00),
+       PARAM_RESTORE(0xd4, TIMER_INDEX),
+};
+
+static void ufs_renesas_dbg_register_dump(struct ufs_hba *hba)
+{
+       ufshcd_dump_regs(hba, 0xc0, 0x40, "regs: 0xc0 + ");
+}
+
+static void ufs_renesas_reg_control(struct ufs_hba *hba,
+                                   const struct ufs_renesas_init_param *p)
+{
+       static u32 save[MAX_INDEX];
+       int ret;
+       u32 val;
+
+       WARN_ON(p->index >= MAX_INDEX);
+
+       switch (p->mode) {
+       case MODE_RESTORE:
+               ufshcd_writel(hba, save[p->index], p->reg);
+               break;
+       case MODE_SET:
+               save[p->index] |= p->u.set;
+               break;
+       case MODE_SAVE:
+               save[p->index] = ufshcd_readl(hba, p->reg) & p->mask;
+               break;
+       case MODE_POLL:
+               ret = readl_poll_timeout_atomic(hba->mmio_base + p->reg,
+                                               val,
+                                               (val & p->mask) == p->u.expected,
+                                               10, 1000);
+               if (ret)
+                       dev_err(hba->dev, "%s: poll failed %d (%08x, %08x, %08x)\n",
+                               __func__, ret, val, p->mask, p->u.expected);
+               break;
+       case MODE_WAIT:
+               if (p->u.delay_us > 1000)
+                       mdelay(DIV_ROUND_UP(p->u.delay_us, 1000));
+               else
+                       udelay(p->u.delay_us);
+               break;
+       case MODE_WRITE:
+               ufshcd_writel(hba, p->u.val, p->reg);
+               break;
+       default:
+               break;
+       }
+}
+
+static void ufs_renesas_pre_init(struct ufs_hba *hba)
+{
+       const struct ufs_renesas_init_param *p = ufs_param;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(ufs_param); i++)
+               ufs_renesas_reg_control(hba, &p[i]);
+}
+
+static int ufs_renesas_hce_enable_notify(struct ufs_hba *hba,
+                                        enum ufs_notify_change_status status)
+{
+       struct ufs_renesas_priv *priv = ufshcd_get_variant(hba);
+
+       if (priv->initialized)
+               return 0;
+
+       if (status == PRE_CHANGE)
+               ufs_renesas_pre_init(hba);
+
+       priv->initialized = true;
+
+       return 0;
+}
+
+static int ufs_renesas_setup_clocks(struct ufs_hba *hba, bool on,
+                                   enum ufs_notify_change_status status)
+{
+       if (on && status == PRE_CHANGE)
+               pm_runtime_get_sync(hba->dev);
+       else if (!on && status == POST_CHANGE)
+               pm_runtime_put(hba->dev);
+
+       return 0;
+}
+
+static int ufs_renesas_init(struct ufs_hba *hba)
+{
+       struct ufs_renesas_priv *priv;
+
+       priv = devm_kmalloc(hba->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       ufshcd_set_variant(hba, priv);
+
+       hba->quirks |= UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS | UFSHCD_QUIRK_HIBERN_FASTAUTO;
+
+       return 0;
+}
+
+static const struct ufs_hba_variant_ops ufs_renesas_vops = {
+       .name           = "renesas",
+       .init           = ufs_renesas_init,
+       .setup_clocks   = ufs_renesas_setup_clocks,
+       .hce_enable_notify = ufs_renesas_hce_enable_notify,
+       .dbg_register_dump = ufs_renesas_dbg_register_dump,
+};
+
+static const struct of_device_id __maybe_unused ufs_renesas_of_match[] = {
+       { .compatible = "renesas,r8a779f0-ufs" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ufs_renesas_of_match);
+
+static int ufs_renesas_probe(struct platform_device *pdev)
+{
+       return ufshcd_pltfrm_init(pdev, &ufs_renesas_vops);
+}
+
+static int ufs_renesas_remove(struct platform_device *pdev)
+{
+       struct ufs_hba *hba = platform_get_drvdata(pdev);
+
+       ufshcd_remove(hba);
+
+       return 0;
+}
+
+static struct platform_driver ufs_renesas_platform = {
+       .probe  = ufs_renesas_probe,
+       .remove = ufs_renesas_remove,
+       .driver = {
+               .name   = "ufshcd-renesas",
+               .of_match_table = of_match_ptr(ufs_renesas_of_match),
+       },
+};
+module_platform_driver(ufs_renesas_platform);
+
+MODULE_AUTHOR("Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>");
+MODULE_DESCRIPTION("Renesas UFS host controller driver");
+MODULE_LICENSE("Dual MIT/GPL");
index e7332cc..bde3468 100644 (file)
@@ -26,7 +26,7 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)
        int i;
        struct device *dev = hba->dev;
        struct device_node *np = dev->of_node;
-       char *name;
+       const char *name;
        u32 *clkfreq = NULL;
        struct ufs_clk_info *clki;
        int len = 0;
@@ -79,8 +79,8 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)
        }
 
        for (i = 0; i < sz; i += 2) {
-               ret = of_property_read_string_index(np,
-                               "clock-names", i/2, (const char **)&name);
+               ret = of_property_read_string_index(np, "clock-names", i/2,
+                                                   &name);
                if (ret)
                        goto out;
 
@@ -109,8 +109,8 @@ out:
 }
 
 #define MAX_PROP_SIZE 32
-static int ufshcd_populate_vreg(struct device *dev, const char *name,
-               struct ufs_vreg **out_vreg)
+int ufshcd_populate_vreg(struct device *dev, const char *name,
+                        struct ufs_vreg **out_vreg)
 {
        char prop_name[MAX_PROP_SIZE];
        struct ufs_vreg *vreg = NULL;
@@ -145,6 +145,7 @@ out:
        *out_vreg = vreg;
        return 0;
 }
+EXPORT_SYMBOL_GPL(ufshcd_populate_vreg);
 
 /**
  * ufshcd_parse_regulator_info - get regulator info from device tree
@@ -208,8 +209,8 @@ static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba)
  *
  * Returns 0 on success, non-zero value on failure
  */
-int ufshcd_get_pwr_dev_param(struct ufs_dev_params *pltfrm_param,
-                            struct ufs_pa_layer_attr *dev_max,
+int ufshcd_get_pwr_dev_param(const struct ufs_dev_params *pltfrm_param,
+                            const struct ufs_pa_layer_attr *dev_max,
                             struct ufs_pa_layer_attr *agreed_pwr)
 {
        int min_pltfrm_gear;
index 43c2e41..2e4ba2b 100644 (file)
@@ -25,12 +25,14 @@ struct ufs_dev_params {
        u32 desired_working_mode;
 };
 
-int ufshcd_get_pwr_dev_param(struct ufs_dev_params *dev_param,
-                            struct ufs_pa_layer_attr *dev_max,
+int ufshcd_get_pwr_dev_param(const struct ufs_dev_params *dev_param,
+                            const struct ufs_pa_layer_attr *dev_max,
                             struct ufs_pa_layer_attr *agreed_pwr);
 void ufshcd_init_pwr_dev_param(struct ufs_dev_params *dev_param);
 int ufshcd_pltfrm_init(struct platform_device *pdev,
                       const struct ufs_hba_variant_ops *vops);
 void ufshcd_pltfrm_shutdown(struct platform_device *pdev);
+int ufshcd_populate_vreg(struct device *dev, const char *name,
+                        struct ufs_vreg **out_vreg);
 
 #endif /* UFSHCD_PLTFRM_H_ */
index c0703cd..654cc39 100644 (file)
@@ -135,9 +135,6 @@ struct iscsi_task {
        void                    *dd_data;       /* driver/transport data */
 };
 
-/* invalid scsi_task pointer */
-#define        INVALID_SCSI_TASK       (struct iscsi_task *)-1l
-
 static inline int iscsi_task_has_unsol_data(struct iscsi_task *task)
 {
        return task->unsol_r2t.data_length > task->unsol_r2t.sent;
@@ -213,6 +210,8 @@ struct iscsi_conn {
        struct list_head        cmdqueue;       /* data-path cmd queue */
        struct list_head        requeue;        /* tasks needing another run */
        struct work_struct      xmitwork;       /* per-conn. xmit workqueue */
+       /* recv */
+       struct work_struct      recvwork;
        unsigned long           flags;          /* ISCSI_CONN_FLAGs */
 
        /* negotiated params */
@@ -411,7 +410,7 @@ extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev);
 extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
                                          int dd_data_size,
                                          bool xmit_can_sleep);
-extern void iscsi_host_remove(struct Scsi_Host *shost);
+extern void iscsi_host_remove(struct Scsi_Host *shost, bool is_shutdown);
 extern void iscsi_host_free(struct Scsi_Host *shost);
 extern int iscsi_target_alloc(struct scsi_target *starget);
 extern int iscsi_host_get_max_scsi_cmds(struct Scsi_Host *shost,
@@ -452,8 +451,10 @@ extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
 extern int iscsi_conn_get_addr_param(struct sockaddr_storage *addr,
                                     enum iscsi_param param, char *buf);
 extern void iscsi_suspend_tx(struct iscsi_conn *conn);
+extern void iscsi_suspend_rx(struct iscsi_conn *conn);
 extern void iscsi_suspend_queue(struct iscsi_conn *conn);
-extern void iscsi_conn_queue_work(struct iscsi_conn *conn);
+extern void iscsi_conn_queue_xmit(struct iscsi_conn *conn);
+extern void iscsi_conn_queue_recv(struct iscsi_conn *conn);
 
 #define iscsi_conn_printk(prefix, _c, fmt, a...) \
        iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \
@@ -478,7 +479,7 @@ extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t);
 extern void iscsi_requeue_task(struct iscsi_task *task);
 extern void iscsi_put_task(struct iscsi_task *task);
 extern void __iscsi_put_task(struct iscsi_task *task);
-extern void __iscsi_get_task(struct iscsi_task *task);
+extern bool iscsi_get_task(struct iscsi_task *task);
 extern void iscsi_complete_scsi_task(struct iscsi_task *task,
                                     uint32_t exp_cmdsn, uint32_t max_cmdsn);
 
index ff04eb6..2dbead7 100644 (file)
@@ -145,7 +145,7 @@ struct sata_device {
 
        struct ata_port *ap;
        struct ata_host *ata_host;
-       struct smp_resp rps_resp ____cacheline_aligned; /* report_phy_sata_resp */
+       struct smp_rps_resp rps_resp ____cacheline_aligned; /* report_phy_sata_resp */
        u8     fis[ATA_RESP_FIS_SIZE];
 };
 
index acfc69f..71b749b 100644 (file)
@@ -471,18 +471,6 @@ struct report_phy_sata_resp {
        __be32 crc;
 } __attribute__ ((packed));
 
-struct smp_resp {
-       u8    frame_type;
-       u8    function;
-       u8    result;
-       u8    reserved;
-       union {
-               struct report_general_resp  rg;
-               struct discover_resp        disc;
-               struct report_phy_sata_resp rps;
-       };
-} __attribute__ ((packed));
-
 #elif defined(__BIG_ENDIAN_BITFIELD)
 struct sas_identify_frame {
        /* Byte 0 */
@@ -704,20 +692,32 @@ struct report_phy_sata_resp {
        __be32 crc;
 } __attribute__ ((packed));
 
-struct smp_resp {
+#else
+#error "Bitfield order not defined!"
+#endif
+
+struct smp_rg_resp {
        u8    frame_type;
        u8    function;
        u8    result;
        u8    reserved;
-       union {
-               struct report_general_resp  rg;
-               struct discover_resp        disc;
-               struct report_phy_sata_resp rps;
-       };
+       struct report_general_resp rg;
 } __attribute__ ((packed));
 
-#else
-#error "Bitfield order not defined!"
-#endif
+struct smp_disc_resp {
+       u8    frame_type;
+       u8    function;
+       u8    result;
+       u8    reserved;
+       struct discover_resp disc;
+} __attribute__ ((packed));
+
+struct smp_rps_resp {
+       u8    frame_type;
+       u8    function;
+       u8    result;
+       u8    reserved;
+       struct report_phy_sata_resp rps;
+} __attribute__ ((packed));
 
 #endif /* _SAS_H_ */
index 9acb842..cab52b0 100644 (file)
@@ -162,7 +162,7 @@ struct iscsi_transport {
  * transport registration upcalls
  */
 extern struct scsi_transport_template *iscsi_register_transport(struct iscsi_transport *tt);
-extern int iscsi_unregister_transport(struct iscsi_transport *tt);
+extern void iscsi_unregister_transport(struct iscsi_transport *tt);
 
 /*
  * control plane upcalls
@@ -442,6 +442,7 @@ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
                                                struct iscsi_transport *t,
                                                int dd_size,
                                                unsigned int target_id);
+extern void iscsi_force_destroy_session(struct iscsi_cls_session *session);
 extern void iscsi_remove_session(struct iscsi_cls_session *session);
 extern void iscsi_free_session(struct iscsi_cls_session *session);
 extern struct iscsi_cls_conn *iscsi_alloc_conn(struct iscsi_cls_session *sess,
index 8e68ace..94d06dd 100644 (file)
@@ -26,6 +26,7 @@ struct sock;
 #define ISCSI_RX_THREAD_NAME           "iscsi_trx"
 #define ISCSI_TX_THREAD_NAME           "iscsi_ttx"
 #define ISCSI_IQN_LEN                  224
+#define NA_AUTHENTICATION_INHERITED    -1
 
 /* struct iscsi_node_attrib sanity values */
 #define NA_DATAOUT_TIMEOUT             3
@@ -715,6 +716,7 @@ struct iscsi_login {
 } ____cacheline_aligned;
 
 struct iscsi_node_attrib {
+       s32                     authentication;
        u32                     dataout_timeout;
        u32                     dataout_timeout_retries;
        u32                     default_erl;
@@ -758,6 +760,12 @@ struct iscsi_node_acl {
        struct iscsi_node_stat_grps node_stat_grps;
 };
 
+static inline struct iscsi_node_acl *
+to_iscsi_nacl(struct se_node_acl *se_nacl)
+{
+       return container_of(se_nacl, struct iscsi_node_acl, se_node_acl);
+}
+
 struct iscsi_tpg_attrib {
        u32                     authentication;
        u32                     login_timeout;
@@ -839,6 +847,12 @@ struct iscsi_portal_group {
        struct list_head        tpg_list;
 } ____cacheline_aligned;
 
+static inline struct iscsi_portal_group *
+to_iscsi_tpg(struct se_portal_group *se_tpg)
+{
+       return container_of(se_tpg, struct iscsi_portal_group, tpg_se_tpg);
+}
+
 struct iscsi_wwn_stat_grps {
        struct config_group     iscsi_stat_group;
        struct config_group     iscsi_instance_group;
index 773963a..a3c193d 100644 (file)
@@ -37,6 +37,7 @@ struct target_backend_ops {
        struct se_dev_plug *(*plug_device)(struct se_device *se_dev);
        void (*unplug_device)(struct se_dev_plug *se_plug);
 
+       bool (*configure_unmap)(struct se_device *se_dev);
        ssize_t (*set_configfs_dev_params)(struct se_device *,
                                           const char *, ssize_t);
        ssize_t (*show_configfs_dev_params)(struct se_device *, char *);
index 370ade0..a2c7bef 100644 (file)
@@ -166,6 +166,8 @@ TRACE_EVENT(scsi_dispatch_cmd_start,
                __field( unsigned int,  lun     )
                __field( unsigned int,  opcode  )
                __field( unsigned int,  cmd_len )
+               __field( int,   driver_tag)
+               __field( int,   scheduler_tag)
                __field( unsigned int,  data_sglen )
                __field( unsigned int,  prot_sglen )
                __field( unsigned char, prot_op )
@@ -179,6 +181,8 @@ TRACE_EVENT(scsi_dispatch_cmd_start,
                __entry->lun            = cmd->device->lun;
                __entry->opcode         = cmd->cmnd[0];
                __entry->cmd_len        = cmd->cmd_len;
+               __entry->driver_tag     = scsi_cmd_to_rq(cmd)->tag;
+               __entry->scheduler_tag  = scsi_cmd_to_rq(cmd)->internal_tag;
                __entry->data_sglen     = scsi_sg_count(cmd);
                __entry->prot_sglen     = scsi_prot_sg_count(cmd);
                __entry->prot_op        = scsi_get_prot_op(cmd);
@@ -186,11 +190,11 @@ TRACE_EVENT(scsi_dispatch_cmd_start,
        ),
 
        TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \
-                 " prot_op=%s cmnd=(%s %s raw=%s)",
+                 " prot_op=%s driver_tag=%d scheduler_tag=%d cmnd=(%s %s raw=%s)",
                  __entry->host_no, __entry->channel, __entry->id,
                  __entry->lun, __entry->data_sglen, __entry->prot_sglen,
-                 show_prot_op_name(__entry->prot_op),
-                 show_opcode_name(__entry->opcode),
+                 show_prot_op_name(__entry->prot_op), __entry->driver_tag,
+                 __entry->scheduler_tag, show_opcode_name(__entry->opcode),
                  __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len),
                  __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len))
 );
@@ -209,6 +213,8 @@ TRACE_EVENT(scsi_dispatch_cmd_error,
                __field( int,           rtn     )
                __field( unsigned int,  opcode  )
                __field( unsigned int,  cmd_len )
+               __field( int,   driver_tag)
+               __field( int,   scheduler_tag)
                __field( unsigned int,  data_sglen )
                __field( unsigned int,  prot_sglen )
                __field( unsigned char, prot_op )
@@ -223,6 +229,8 @@ TRACE_EVENT(scsi_dispatch_cmd_error,
                __entry->rtn            = rtn;
                __entry->opcode         = cmd->cmnd[0];
                __entry->cmd_len        = cmd->cmd_len;
+               __entry->driver_tag     = scsi_cmd_to_rq(cmd)->tag;
+               __entry->scheduler_tag  = scsi_cmd_to_rq(cmd)->internal_tag;
                __entry->data_sglen     = scsi_sg_count(cmd);
                __entry->prot_sglen     = scsi_prot_sg_count(cmd);
                __entry->prot_op        = scsi_get_prot_op(cmd);
@@ -230,11 +238,12 @@ TRACE_EVENT(scsi_dispatch_cmd_error,
        ),
 
        TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \
-                 " prot_op=%s cmnd=(%s %s raw=%s) rtn=%d",
+                 " prot_op=%s driver_tag=%d scheduler_tag=%d cmnd=(%s %s raw=%s)" \
+                 " rtn=%d",
                  __entry->host_no, __entry->channel, __entry->id,
                  __entry->lun, __entry->data_sglen, __entry->prot_sglen,
-                 show_prot_op_name(__entry->prot_op),
-                 show_opcode_name(__entry->opcode),
+                 show_prot_op_name(__entry->prot_op), __entry->driver_tag,
+                 __entry->scheduler_tag, show_opcode_name(__entry->opcode),
                  __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len),
                  __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len),
                  __entry->rtn)
@@ -254,6 +263,8 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template,
                __field( int,           result  )
                __field( unsigned int,  opcode  )
                __field( unsigned int,  cmd_len )
+               __field( int,   driver_tag)
+               __field( int,   scheduler_tag)
                __field( unsigned int,  data_sglen )
                __field( unsigned int,  prot_sglen )
                __field( unsigned char, prot_op )
@@ -268,19 +279,21 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template,
                __entry->result         = cmd->result;
                __entry->opcode         = cmd->cmnd[0];
                __entry->cmd_len        = cmd->cmd_len;
+               __entry->driver_tag     = scsi_cmd_to_rq(cmd)->tag;
+               __entry->scheduler_tag  = scsi_cmd_to_rq(cmd)->internal_tag;
                __entry->data_sglen     = scsi_sg_count(cmd);
                __entry->prot_sglen     = scsi_prot_sg_count(cmd);
                __entry->prot_op        = scsi_get_prot_op(cmd);
                memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len);
        ),
 
-       TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \
-                 "prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=" \
-                 "%s host=%s message=%s status=%s)",
+       TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u " \
+                 "prot_op=%s driver_tag=%d scheduler_tag=%d cmnd=(%s %s raw=%s) " \
+                 "result=(driver=%s host=%s message=%s status=%s)",
                  __entry->host_no, __entry->channel, __entry->id,
                  __entry->lun, __entry->data_sglen, __entry->prot_sglen,
-                 show_prot_op_name(__entry->prot_op),
-                 show_opcode_name(__entry->opcode),
+                 show_prot_op_name(__entry->prot_op), __entry->driver_tag,
+                 __entry->scheduler_tag, show_opcode_name(__entry->opcode),
                  __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len),
                  __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len),
                  "DRIVER_OK",
index a922714..7fe1a92 100644 (file)
@@ -577,6 +577,18 @@ enum ufshcd_quirks {
         * support physical host configuration.
         */
        UFSHCD_QUIRK_SKIP_PH_CONFIGURATION              = 1 << 16,
+
+       /*
+        * This quirk needs to be enabled if the host controller has
+        * 64-bit addressing supported capability but it doesn't work.
+        */
+       UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS               = 1 << 17,
+
+       /*
+        * This quirk needs to be enabled if the host controller has
+        * auto-hibernate capability but it's FASTAUTO only.
+        */
+       UFSHCD_QUIRK_HIBERN_FASTAUTO                    = 1 << 18,
 };
 
 enum ufshcd_caps {
@@ -1087,6 +1099,7 @@ extern int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel,
                               u32 *mib_val, u8 peer);
 extern int ufshcd_config_pwr_mode(struct ufs_hba *hba,
                        struct ufs_pa_layer_attr *desired_pwr_mode);
+extern int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode);
 
 /* UIC command interfaces for DME primitives */
 #define DME_LOCAL      0
@@ -1186,6 +1199,8 @@ void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn desc_id,
 
 u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba);
 
+int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg);
+
 int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd);
 
 int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
@@ -1217,14 +1232,14 @@ static inline int ufshcd_vops_phy_initialization(struct ufs_hba *hba)
        return 0;
 }
 
-extern struct ufs_pm_lvl_states ufs_pm_lvl_states[];
+extern const struct ufs_pm_lvl_states ufs_pm_lvl_states[];
 
 int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len,
                     const char *prefix);
 
 int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask);
 int ufshcd_write_ee_control(struct ufs_hba *hba);
-int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask,
-                            u16 set, u16 clr);
+int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask,
+                            const u16 *other_mask, u16 set, u16 clr);
 
 #endif /* End of Header */
index 0521f88..6c553f9 100644 (file)
 /*
  * M-RX Configuration Attributes
  */
+#define RX_HS_G1_SYNC_LENGTH_CAP               0x008B
+#define RX_HS_G1_PREP_LENGTH_CAP               0x008C
+#define RX_MIN_ACTIVATETIME_CAPABILITY         0x008F
+#define RX_HIBERN8TIME_CAPABILITY              0x0092
+#define RX_HS_G2_SYNC_LENGTH_CAP               0x0094
+#define RX_HS_G3_SYNC_LENGTH_CAP               0x0095
+#define RX_HS_G2_PREP_LENGTH_CAP               0x0096
+#define RX_HS_G3_PREP_LENGTH_CAP               0x0097
+#define RX_ADV_GRANULARITY_CAP                 0x0098
+#define RX_HIBERN8TIME_CAP                     0x0092
+#define RX_ADV_HIBERN8TIME_CAP                 0x0099
+#define RX_ADV_MIN_ACTIVATETIME_CAP            0x009A
 #define RX_MODE                                        0x00A1
 #define RX_HSRATE_SERIES                       0x00A2
 #define RX_HSGEAR                              0x00A3
 #define RX_ENTER_HIBERN8                       0x00A7
 #define RX_BYPASS_8B10B_ENABLE                 0x00A8
 #define RX_TERMINATION_FORCE_ENABLE            0x00A9
-#define RX_MIN_ACTIVATETIME_CAPABILITY         0x008F
-#define RX_HIBERN8TIME_CAPABILITY              0x0092
+#define RXCALCTRL                              0x00B4
+#define RXSQCTRL                               0x00B5
+#define CFGRXCDR8                              0x00BA
+#define CFGRXOVR8                              0x00BD
+#define CFGRXOVR6                              0x00BF
+#define RXDIRECTCTRL2                          0x00C7
+#define CFGRXOVR4                              0x00E9
 #define RX_REFCLKFREQ                          0x00EB
 #define        RX_CFGCLKFREQVAL                        0x00EC
 #define CFGWIDEINLN                            0x00F0
-#define CFGRXCDR8                              0x00BA
 #define ENARXDIRECTCFG4                                0x00F2
-#define CFGRXOVR8                              0x00BD
-#define RXDIRECTCTRL2                          0x00C7
 #define ENARXDIRECTCFG3                                0x00F3
-#define RXCALCTRL                              0x00B4
 #define ENARXDIRECTCFG2                                0x00F4
-#define CFGRXOVR4                              0x00E9
-#define RXSQCTRL                               0x00B5
-#define CFGRXOVR6                              0x00BF
-#define RX_HS_G1_SYNC_LENGTH_CAP               0x008B
-#define RX_HS_G1_PREP_LENGTH_CAP               0x008C
-#define RX_HS_G2_SYNC_LENGTH_CAP               0x0094
-#define RX_HS_G3_SYNC_LENGTH_CAP               0x0095
-#define RX_HS_G2_PREP_LENGTH_CAP               0x0096
-#define RX_HS_G3_PREP_LENGTH_CAP               0x0097
-#define RX_ADV_GRANULARITY_CAP                 0x0098
-#define RX_MIN_ACTIVATETIME_CAP                        0x008F
-#define RX_HIBERN8TIME_CAP                     0x0092
-#define RX_ADV_HIBERN8TIME_CAP                 0x0099
-#define RX_ADV_MIN_ACTIVATETIME_CAP            0x009A
 
 
 #define is_mphy_tx_attr(attr)                  (attr < RX_MODE)
 /*
  * PHY Adapter attributes
  */
-#define PA_ACTIVETXDATALANES   0x1560
-#define PA_ACTIVERXDATALANES   0x1580
-#define PA_TXTRAILINGCLOCKS    0x1564
 #define PA_PHY_TYPE            0x1500
 #define PA_AVAILTXDATALANES    0x1520
-#define PA_AVAILRXDATALANES    0x1540
-#define PA_MINRXTRAILINGCLOCKS 0x1543
-#define PA_TXPWRSTATUS         0x1567
-#define PA_RXPWRSTATUS         0x1582
-#define PA_TXFORCECLOCK                0x1562
-#define PA_TXPWRMODE           0x1563
-#define PA_LEGACYDPHYESCDL     0x1570
 #define PA_MAXTXSPEEDFAST      0x1521
 #define PA_MAXTXSPEEDSLOW      0x1522
 #define PA_MAXRXSPEEDFAST      0x1541
 #define PA_MAXRXSPEEDSLOW      0x1542
 #define PA_TXLINKSTARTUPHS     0x1544
+#define PA_AVAILRXDATALANES    0x1540
+#define PA_MINRXTRAILINGCLOCKS 0x1543
 #define PA_LOCAL_TX_LCC_ENABLE 0x155E
+#define PA_ACTIVETXDATALANES   0x1560
+#define PA_CONNECTEDTXDATALANES        0x1561
+#define PA_TXFORCECLOCK                0x1562
+#define PA_TXPWRMODE           0x1563
+#define PA_TXTRAILINGCLOCKS    0x1564
 #define PA_TXSPEEDFAST         0x1565
 #define PA_TXSPEEDSLOW         0x1566
-#define PA_REMOTEVERINFO       0x15A0
+#define PA_TXPWRSTATUS         0x1567
 #define PA_TXGEAR              0x1568
 #define PA_TXTERMINATION       0x1569
 #define PA_HSSERIES            0x156A
+#define PA_LEGACYDPHYESCDL     0x1570
 #define PA_PWRMODE             0x1571
+#define PA_ACTIVERXDATALANES   0x1580
+#define PA_CONNECTEDRXDATALANES        0x1581
+#define PA_RXPWRSTATUS         0x1582
 #define PA_RXGEAR              0x1583
 #define PA_RXTERMINATION       0x1584
 #define PA_MAXRXPWMGEAR                0x1586
 #define PA_MAXRXHSGEAR         0x1587
+#define PA_PACPREQTIMEOUT      0x1590
+#define PA_PACPREQEOBTIMEOUT   0x1591
+#define PA_REMOTEVERINFO       0x15A0
+#define PA_LOGICALLANEMAP      0x15A1
+#define PA_SLEEPNOCONFIGTIME   0x15A2
+#define PA_STALLNOCONFIGTIME   0x15A3
+#define PA_SAVECONFIGTIME      0x15A4
 #define PA_RXHSUNTERMCAP       0x15A5
 #define PA_RXLSTERMCAP         0x15A6
 #define PA_GRANULARITY         0x15AA
-#define PA_PACPREQTIMEOUT      0x1590
-#define PA_PACPREQEOBTIMEOUT   0x1591
 #define PA_HIBERN8TIME         0x15A7
 #define PA_LOCALVERINFO                0x15A9
 #define PA_GRANULARITY         0x15AA
 #define PA_TACTIVATE           0x15A8
-#define PA_PACPFRAMECOUNT      0x15C0
-#define PA_PACPERRORCOUNT      0x15C1
-#define PA_PHYTESTCONTROL      0x15C2
 #define PA_PWRMODEUSERDATA0    0x15B0
 #define PA_PWRMODEUSERDATA1    0x15B1
 #define PA_PWRMODEUSERDATA2    0x15B2
 #define PA_PWRMODEUSERDATA9    0x15B9
 #define PA_PWRMODEUSERDATA10   0x15BA
 #define PA_PWRMODEUSERDATA11   0x15BB
-#define PA_CONNECTEDTXDATALANES        0x1561
-#define PA_CONNECTEDRXDATALANES        0x1581
-#define PA_LOGICALLANEMAP      0x15A1
-#define PA_SLEEPNOCONFIGTIME   0x15A2
-#define PA_STALLNOCONFIGTIME   0x15A3
-#define PA_SAVECONFIGTIME      0x15A4
+#define PA_PACPFRAMECOUNT      0x15C0
+#define PA_PACPERRORCOUNT      0x15C1
+#define PA_PHYTESTCONTROL      0x15C2
 #define PA_TXHSADAPTTYPE       0x15D4
 
 /* Adpat type for PA_TXHSADAPTTYPE attribute */
 #define PA_HIBERN8_TIME_UNIT_US                100
 
 /*Other attributes*/
+#define VS_POWERSTATE          0xD083
 #define VS_MPHYCFGUPDT         0xD085
 #define VS_DEBUGOMC            0xD09E
-#define VS_POWERSTATE          0xD083
 
 #define PA_GRANULARITY_MIN_VAL 1
 #define PA_GRANULARITY_MAX_VAL 6
@@ -229,6 +228,7 @@ enum ufs_hs_gear_tag {
        UFS_HS_G2,              /* HS Gear 2 */
        UFS_HS_G3,              /* HS Gear 3 */
        UFS_HS_G4,              /* HS Gear 4 */
+       UFS_HS_G5               /* HS Gear 5 */
 };
 
 enum ufs_unipro_ver {
@@ -246,27 +246,27 @@ enum ufs_unipro_ver {
 /*
  * Data Link Layer Attributes
  */
+#define DL_TXPREEMPTIONCAP     0x2000
+#define DL_TC0TXMAXSDUSIZE     0x2001
+#define DL_TC0RXINITCREDITVAL  0x2002
+#define DL_TC1TXMAXSDUSIZE     0x2003
+#define DL_TC1RXINITCREDITVAL  0x2004
+#define DL_TC0TXBUFFERSIZE     0x2005
+#define DL_TC1TXBUFFERSIZE     0x2006
 #define DL_TC0TXFCTHRESHOLD    0x2040
 #define DL_FC0PROTTIMEOUTVAL   0x2041
 #define DL_TC0REPLAYTIMEOUTVAL 0x2042
 #define DL_AFC0REQTIMEOUTVAL   0x2043
 #define DL_AFC0CREDITTHRESHOLD 0x2044
 #define DL_TC0OUTACKTHRESHOLD  0x2045
+#define DL_PEERTC0PRESENT      0x2046
+#define DL_PEERTC0RXINITCREVAL 0x2047
 #define DL_TC1TXFCTHRESHOLD    0x2060
 #define DL_FC1PROTTIMEOUTVAL   0x2061
 #define DL_TC1REPLAYTIMEOUTVAL 0x2062
 #define DL_AFC1REQTIMEOUTVAL   0x2063
 #define DL_AFC1CREDITTHRESHOLD 0x2064
 #define DL_TC1OUTACKTHRESHOLD  0x2065
-#define DL_TXPREEMPTIONCAP     0x2000
-#define DL_TC0TXMAXSDUSIZE     0x2001
-#define DL_TC0RXINITCREDITVAL  0x2002
-#define DL_TC0TXBUFFERSIZE     0x2005
-#define DL_PEERTC0PRESENT      0x2046
-#define DL_PEERTC0RXINITCREVAL 0x2047
-#define DL_TC1TXMAXSDUSIZE     0x2003
-#define DL_TC1RXINITCREDITVAL  0x2004
-#define DL_TC1TXBUFFERSIZE     0x2006
 #define DL_PEERTC1PRESENT      0x2066
 #define DL_PEERTC1RXINITCREVAL 0x2067