]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - drivers/scsi/cxlflash/main.c
cxlflash: Fix to avoid lock instrumentation rejection
[mirror_ubuntu-zesty-kernel.git] / drivers / scsi / cxlflash / main.c
index b44212b6d9428a7804c8b16979d8cbc2ce0f7519..1e5bf0ca81da1043a3be9d752271baf9c0a85836 100644 (file)
@@ -34,7 +34,6 @@ MODULE_AUTHOR("Manoj N. Kumar <manoj@linux.vnet.ibm.com>");
 MODULE_AUTHOR("Matthew R. Ochs <mrochs@linux.vnet.ibm.com>");
 MODULE_LICENSE("GPL");
 
-
 /**
  * cmd_checkout() - checks out an AFU command
  * @afu:       AFU to checkout from.
@@ -58,8 +57,8 @@ static struct afu_cmd *cmd_checkout(struct afu *afu)
                cmd = &afu->cmd[k];
 
                if (!atomic_dec_if_positive(&cmd->free)) {
-                       pr_debug("%s: returning found index=%d\n",
-                                __func__, cmd->slot);
+                       pr_devel("%s: returning found index=%d cmd=%p\n",
+                                __func__, cmd->slot, cmd);
                        memset(cmd->buf, 0, CMD_BUFSIZE);
                        memset(cmd->rcb.cdb, 0, sizeof(cmd->rcb.cdb));
                        return cmd;
@@ -93,7 +92,7 @@ static void cmd_checkin(struct afu_cmd *cmd)
                return;
        }
 
-       pr_debug("%s: released cmd %p index=%d\n", __func__, cmd, cmd->slot);
+       pr_devel("%s: released cmd %p index=%d\n", __func__, cmd, cmd->slot);
 }
 
 /**
@@ -107,6 +106,7 @@ static void process_cmd_err(struct afu_cmd *cmd, struct scsi_cmnd *scp)
 {
        struct sisl_ioarcb *ioarcb;
        struct sisl_ioasa *ioasa;
+       u32 resid;
 
        if (unlikely(!cmd))
                return;
@@ -115,9 +115,10 @@ static void process_cmd_err(struct afu_cmd *cmd, struct scsi_cmnd *scp)
        ioasa = &(cmd->sa);
 
        if (ioasa->rc.flags & SISL_RC_FLAGS_UNDERRUN) {
-               pr_debug("%s: cmd underrun cmd = %p scp = %p\n",
-                        __func__, cmd, scp);
-               scp->result = (DID_ERROR << 16);
+               resid = ioasa->resid;
+               scsi_set_resid(scp, resid);
+               pr_debug("%s: cmd underrun cmd = %p scp = %p, resid = %d\n",
+                        __func__, cmd, scp, resid);
        }
 
        if (ioasa->rc.flags & SISL_RC_FLAGS_OVERRUN) {
@@ -127,7 +128,7 @@ static void process_cmd_err(struct afu_cmd *cmd, struct scsi_cmnd *scp)
        }
 
        pr_debug("%s: cmd failed afu_rc=%d scsi_rc=%d fc_rc=%d "
-                "afu_extra=0x%X, scsi_entra=0x%X, fc_extra=0x%X\n",
+                "afu_extra=0x%X, scsi_extra=0x%X, fc_extra=0x%X\n",
                 __func__, ioasa->rc.afu_rc, ioasa->rc.scsi_rc,
                 ioasa->rc.fc_rc, ioasa->afu_extra, ioasa->scsi_extra,
                 ioasa->fc_extra);
@@ -158,8 +159,7 @@ static void process_cmd_err(struct afu_cmd *cmd, struct scsi_cmnd *scp)
                                /* If the SISL_RC_FLAGS_OVERRUN flag was set,
                                 * then we will handle this error else where.
                                 * If not then we must handle it here.
-                                * This is probably an AFU bug. We will
-                                * attempt a retry to see if that resolves it.
+                                * This is probably an AFU bug.
                                 */
                                scp->result = (DID_ERROR << 16);
                        }
@@ -183,7 +183,7 @@ static void process_cmd_err(struct afu_cmd *cmd, struct scsi_cmnd *scp)
                /* We have an AFU error */
                switch (ioasa->rc.afu_rc) {
                case SISL_AFU_RC_NO_CHANNELS:
-                       scp->result = (DID_MEDIUM_ERROR << 16);
+                       scp->result = (DID_NO_CONNECT << 16);
                        break;
                case SISL_AFU_RC_DATA_DMA_ERR:
                        switch (ioasa->afu_extra) {
@@ -217,7 +217,6 @@ static void process_cmd_err(struct afu_cmd *cmd, struct scsi_cmnd *scp)
 static void cmd_complete(struct afu_cmd *cmd)
 {
        struct scsi_cmnd *scp;
-       u32 resid;
        ulong lock_flags;
        struct afu *afu = cmd->parent;
        struct cxlflash_cfg *cfg = afu->parent;
@@ -229,31 +228,26 @@ static void cmd_complete(struct afu_cmd *cmd)
 
        if (cmd->rcb.scp) {
                scp = cmd->rcb.scp;
-               if (unlikely(cmd->sa.rc.afu_rc ||
-                            cmd->sa.rc.scsi_rc ||
-                            cmd->sa.rc.fc_rc))
+               if (unlikely(cmd->sa.ioasc))
                        process_cmd_err(cmd, scp);
                else
                        scp->result = (DID_OK << 16);
 
-               resid = cmd->sa.resid;
                cmd_is_tmf = cmd->cmd_tmf;
                cmd_checkin(cmd); /* Don't use cmd after here */
 
-               pr_debug("%s: calling scsi_set_resid, scp=%p "
-                        "result=%X resid=%d\n", __func__,
-                        scp, scp->result, resid);
+               pr_debug_ratelimited("%s: calling scsi_done scp=%p result=%X "
+                                    "ioasc=%d\n", __func__, scp, scp->result,
+                                    cmd->sa.ioasc);
 
-               scsi_set_resid(scp, resid);
                scsi_dma_unmap(scp);
                scp->scsi_done(scp);
 
                if (cmd_is_tmf) {
-                       spin_lock_irqsave(&cfg->tmf_waitq.lock, lock_flags);
+                       spin_lock_irqsave(&cfg->tmf_slock, lock_flags);
                        cfg->tmf_active = false;
                        wake_up_all_locked(&cfg->tmf_waitq);
-                       spin_unlock_irqrestore(&cfg->tmf_waitq.lock,
-                                              lock_flags);
+                       spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
                }
        } else
                complete(&cmd->cevent);
@@ -309,7 +303,7 @@ write_rrin:
                if (rrin != 0x1)
                        break;
                /* Double delay each time */
-               udelay(2 ^ nretry);
+               udelay(2 << nretry);
        } while (nretry++ < MC_ROOM_RETRY_CNT);
 }
 
@@ -319,7 +313,7 @@ write_rrin:
  * @cmd:       AFU command to send.
  *
  * Return:
- *     0 on success or SCSI_MLQUEUE_HOST_BUSY
+ *     0 on success, SCSI_MLQUEUE_HOST_BUSY on failure
  */
 static int send_cmd(struct afu *afu, struct afu_cmd *cmd)
 {
@@ -406,8 +400,7 @@ static void wait_resp(struct afu *afu, struct afu_cmd *cmd)
  * @tmfcmd:    TMF command to send.
  *
  * Return:
- *     0 on success
- *     SCSI_MLQUEUE_HOST_BUSY when host is busy
+ *     0 on success, SCSI_MLQUEUE_HOST_BUSY on failure
  */
 static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
 {
@@ -417,25 +410,27 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
        short lflag = 0;
        struct Scsi_Host *host = scp->device->host;
        struct cxlflash_cfg *cfg = (struct cxlflash_cfg *)host->hostdata;
+       struct device *dev = &cfg->dev->dev;
        ulong lock_flags;
        int rc = 0;
+       ulong to;
 
        cmd = cmd_checkout(afu);
        if (unlikely(!cmd)) {
-               pr_err("%s: could not get a free command\n", __func__);
+               dev_err(dev, "%s: could not get a free command\n", __func__);
                rc = SCSI_MLQUEUE_HOST_BUSY;
                goto out;
        }
 
-       /* If a Task Management Function is active, do not send one more.
-        */
-       spin_lock_irqsave(&cfg->tmf_waitq.lock, lock_flags);
+       /* When Task Management Function is active do not send another */
+       spin_lock_irqsave(&cfg->tmf_slock, lock_flags);
        if (cfg->tmf_active)
-               wait_event_interruptible_locked_irq(cfg->tmf_waitq,
-                                                   !cfg->tmf_active);
+               wait_event_interruptible_lock_irq(cfg->tmf_waitq,
+                                                 !cfg->tmf_active,
+                                                 cfg->tmf_slock);
        cfg->tmf_active = true;
        cmd->cmd_tmf = true;
-       spin_unlock_irqrestore(&cfg->tmf_waitq.lock, lock_flags);
+       spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
 
        cmd->rcb.ctx_id = afu->ctx_hndl;
        cmd->rcb.port_sel = port_sel;
@@ -456,15 +451,24 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
        rc = send_cmd(afu, cmd);
        if (unlikely(rc)) {
                cmd_checkin(cmd);
-               spin_lock_irqsave(&cfg->tmf_waitq.lock, lock_flags);
+               spin_lock_irqsave(&cfg->tmf_slock, lock_flags);
                cfg->tmf_active = false;
-               spin_unlock_irqrestore(&cfg->tmf_waitq.lock, lock_flags);
+               spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
                goto out;
        }
 
-       spin_lock_irqsave(&cfg->tmf_waitq.lock, lock_flags);
-       wait_event_interruptible_locked_irq(cfg->tmf_waitq, !cfg->tmf_active);
-       spin_unlock_irqrestore(&cfg->tmf_waitq.lock, lock_flags);
+       spin_lock_irqsave(&cfg->tmf_slock, lock_flags);
+       to = msecs_to_jiffies(5000);
+       to = wait_event_interruptible_lock_irq_timeout(cfg->tmf_waitq,
+                                                      !cfg->tmf_active,
+                                                      cfg->tmf_slock,
+                                                      to);
+       if (!to) {
+               cfg->tmf_active = false;
+               dev_err(dev, "%s: TMF timed out!\n", __func__);
+               rc = -1;
+       }
+       spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
 out:
        return rc;
 }
@@ -485,15 +489,13 @@ static const char *cxlflash_driver_info(struct Scsi_Host *host)
  * @host:      SCSI host associated with device.
  * @scp:       SCSI command to send.
  *
- * Return:
- *     0 on success
- *     SCSI_MLQUEUE_HOST_BUSY when host is busy
+ * Return: 0 on success, SCSI_MLQUEUE_HOST_BUSY on failure
  */
 static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)
 {
        struct cxlflash_cfg *cfg = (struct cxlflash_cfg *)host->hostdata;
        struct afu *afu = cfg->afu;
-       struct pci_dev *pdev = cfg->dev;
+       struct device *dev = &cfg->dev->dev;
        struct afu_cmd *cmd;
        u32 port_sel = scp->device->channel + 1;
        int nseg, i, ncount;
@@ -502,34 +504,34 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)
        short lflag = 0;
        int rc = 0;
 
-       pr_debug("%s: (scp=%p) %d/%d/%d/%llu cdb=(%08X-%08X-%08X-%08X)\n",
-                __func__, scp, host->host_no, scp->device->channel,
-                scp->device->id, scp->device->lun,
-                get_unaligned_be32(&((u32 *)scp->cmnd)[0]),
-                get_unaligned_be32(&((u32 *)scp->cmnd)[1]),
-                get_unaligned_be32(&((u32 *)scp->cmnd)[2]),
-                get_unaligned_be32(&((u32 *)scp->cmnd)[3]));
+       dev_dbg_ratelimited(dev, "%s: (scp=%p) %d/%d/%d/%llu "
+                           "cdb=(%08X-%08X-%08X-%08X)\n",
+                           __func__, scp, host->host_no, scp->device->channel,
+                           scp->device->id, scp->device->lun,
+                           get_unaligned_be32(&((u32 *)scp->cmnd)[0]),
+                           get_unaligned_be32(&((u32 *)scp->cmnd)[1]),
+                           get_unaligned_be32(&((u32 *)scp->cmnd)[2]),
+                           get_unaligned_be32(&((u32 *)scp->cmnd)[3]));
 
-       /* If a Task Management Function is active, wait for it to complete
+       /*
+        * If a Task Management Function is active, wait for it to complete
         * before continuing with regular commands.
         */
-       spin_lock_irqsave(&cfg->tmf_waitq.lock, lock_flags);
+       spin_lock_irqsave(&cfg->tmf_slock, lock_flags);
        if (cfg->tmf_active) {
-               spin_unlock_irqrestore(&cfg->tmf_waitq.lock, lock_flags);
+               spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
                rc = SCSI_MLQUEUE_HOST_BUSY;
                goto out;
        }
-       spin_unlock_irqrestore(&cfg->tmf_waitq.lock, lock_flags);
+       spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
 
        switch (cfg->state) {
        case STATE_RESET:
-               dev_dbg_ratelimited(&cfg->dev->dev, "%s: device is in reset!\n",
-                                   __func__);
+               dev_dbg_ratelimited(dev, "%s: device is in reset!\n", __func__);
                rc = SCSI_MLQUEUE_HOST_BUSY;
                goto out;
        case STATE_FAILTERM:
-               dev_dbg_ratelimited(&cfg->dev->dev, "%s: device has failed!\n",
-                                   __func__);
+               dev_dbg_ratelimited(dev, "%s: device has failed!\n", __func__);
                scp->result = (DID_NO_CONNECT << 16);
                scp->scsi_done(scp);
                rc = 0;
@@ -540,7 +542,7 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)
 
        cmd = cmd_checkout(afu);
        if (unlikely(!cmd)) {
-               pr_err("%s: could not get a free command\n", __func__);
+               dev_err(dev, "%s: could not get a free command\n", __func__);
                rc = SCSI_MLQUEUE_HOST_BUSY;
                goto out;
        }
@@ -562,7 +564,7 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)
 
        nseg = scsi_dma_map(scp);
        if (unlikely(nseg < 0)) {
-               dev_err(&pdev->dev, "%s: Fail DMA map! nseg=%d\n",
+               dev_err(dev, "%s: Fail DMA map! nseg=%d\n",
                        __func__, nseg);
                rc = SCSI_MLQUEUE_HOST_BUSY;
                goto out;
@@ -585,12 +587,13 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)
        }
 
 out:
+       pr_devel("%s: returning rc=%d\n", __func__, rc);
        return rc;
 }
 
 /**
  * cxlflash_wait_for_pci_err_recovery() - wait for error recovery during probe
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  */
 static void cxlflash_wait_for_pci_err_recovery(struct cxlflash_cfg *cfg)
 {
@@ -604,7 +607,7 @@ static void cxlflash_wait_for_pci_err_recovery(struct cxlflash_cfg *cfg)
 
 /**
  * free_mem() - free memory associated with the AFU
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  */
 static void free_mem(struct cxlflash_cfg *cfg)
 {
@@ -626,7 +629,7 @@ static void free_mem(struct cxlflash_cfg *cfg)
 
 /**
  * stop_afu() - stops the AFU command timers and unmaps the MMIO space
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  *
  * Safe to call with AFU in a partially allocated/initialized state.
  */
@@ -640,7 +643,7 @@ static void stop_afu(struct cxlflash_cfg *cfg)
                        complete(&afu->cmd[i].cevent);
 
                if (likely(afu->afu_map)) {
-                       cxl_psa_unmap((void *)afu->afu_map);
+                       cxl_psa_unmap((void __iomem *)afu->afu_map);
                        afu->afu_map = NULL;
                }
        }
@@ -648,7 +651,7 @@ static void stop_afu(struct cxlflash_cfg *cfg)
 
 /**
  * term_mc() - terminates the master context
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  * @level:     Depth of allocation, where to begin waterfall tear down.
  *
  * Safe to call with AFU/MC in partially allocated/initialized state.
@@ -657,9 +660,10 @@ static void term_mc(struct cxlflash_cfg *cfg, enum undo_level level)
 {
        int rc = 0;
        struct afu *afu = cfg->afu;
+       struct device *dev = &cfg->dev->dev;
 
        if (!afu || !cfg->mcctx) {
-               pr_err("%s: returning from term_mc with NULL afu or MC\n",
+               dev_err(dev, "%s: returning from term_mc with NULL afu or MC\n",
                       __func__);
                return;
        }
@@ -683,7 +687,7 @@ static void term_mc(struct cxlflash_cfg *cfg, enum undo_level level)
 
 /**
  * term_afu() - terminates the AFU
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  *
  * Safe to call with AFU/MC in partially allocated/initialized state.
  */
@@ -711,11 +715,12 @@ static void cxlflash_remove(struct pci_dev *pdev)
        /* If a Task Management Function is active, wait for it to complete
         * before continuing with remove.
         */
-       spin_lock_irqsave(&cfg->tmf_waitq.lock, lock_flags);
+       spin_lock_irqsave(&cfg->tmf_slock, lock_flags);
        if (cfg->tmf_active)
-               wait_event_interruptible_locked_irq(cfg->tmf_waitq,
-                                                   !cfg->tmf_active);
-       spin_unlock_irqrestore(&cfg->tmf_waitq.lock, lock_flags);
+               wait_event_interruptible_lock_irq(cfg->tmf_waitq,
+                                                 !cfg->tmf_active,
+                                                 cfg->tmf_slock);
+       spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
 
        cfg->state = STATE_FAILTERM;
        cxlflash_stop_term_user_contexts(cfg);
@@ -724,16 +729,16 @@ static void cxlflash_remove(struct pci_dev *pdev)
        case INIT_STATE_SCSI:
                cxlflash_term_local_luns(cfg);
                scsi_remove_host(cfg->host);
-               scsi_host_put(cfg->host);
-               /* Fall through */
+               /* fall through */
        case INIT_STATE_AFU:
                term_afu(cfg);
+               cancel_work_sync(&cfg->work_q);
        case INIT_STATE_PCI:
                pci_release_regions(cfg->dev);
                pci_disable_device(pdev);
        case INIT_STATE_NONE:
-               flush_work(&cfg->work_q);
                free_mem(cfg);
+               scsi_host_put(cfg->host);
                break;
        }
 
@@ -742,7 +747,7 @@ static void cxlflash_remove(struct pci_dev *pdev)
 
 /**
  * alloc_mem() - allocates the AFU and its command pool
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  *
  * A partially allocated state remains on failure.
  *
@@ -755,15 +760,14 @@ static int alloc_mem(struct cxlflash_cfg *cfg)
        int rc = 0;
        int i;
        char *buf = NULL;
+       struct device *dev = &cfg->dev->dev;
 
-       /* This allocation is about 12K, i.e. only 1 64k page
-        * and upto 4 4k pages
-        */
+       /* AFU is ~12k, i.e. only one 64k page or up to four 4k pages */
        cfg->afu = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
                                            get_order(sizeof(struct afu)));
        if (unlikely(!cfg->afu)) {
-               pr_err("%s: cannot get %d free pages\n",
-                      __func__, get_order(sizeof(struct afu)));
+               dev_err(dev, "%s: cannot get %d free pages\n",
+                       __func__, get_order(sizeof(struct afu)));
                rc = -ENOMEM;
                goto out;
        }
@@ -774,7 +778,8 @@ static int alloc_mem(struct cxlflash_cfg *cfg)
                if (!((u64)buf & (PAGE_SIZE - 1))) {
                        buf = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
                        if (unlikely(!buf)) {
-                               pr_err("%s: Allocate command buffers fail!\n",
+                               dev_err(dev,
+                                       "%s: Allocate command buffers fail!\n",
                                       __func__);
                                rc = -ENOMEM;
                                free_mem(cfg);
@@ -793,12 +798,9 @@ out:
 
 /**
  * init_pci() - initializes the host as a PCI device
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  *
- * Return:
- *     0 on success
- *     -EIO on unable to communicate with device
- *     A return code from the PCI sub-routines
+ * Return: 0 on success, -errno on failure
  */
 static int init_pci(struct cxlflash_cfg *cfg)
 {
@@ -878,11 +880,9 @@ out_release_regions:
 
 /**
  * init_scsi() - adds the host to the SCSI stack and kicks off host scan
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  *
- * Return:
- *     0 on success
- *     A return code from adding the host
+ * Return: 0 on success, -errno on failure
  */
 static int init_scsi(struct cxlflash_cfg *cfg)
 {
@@ -911,7 +911,7 @@ out:
  * that the FC link layer has synced, completed the handshaking process, and
  * is ready for login to start.
  */
-static void set_port_online(u64 *fc_regs)
+static void set_port_online(__be64 __iomem *fc_regs)
 {
        u64 cmdcfg;
 
@@ -927,7 +927,7 @@ static void set_port_online(u64 *fc_regs)
  *
  * The provided MMIO region must be mapped prior to call.
  */
-static void set_port_offline(u64 *fc_regs)
+static void set_port_offline(__be64 __iomem *fc_regs)
 {
        u64 cmdcfg;
 
@@ -951,7 +951,7 @@ static void set_port_offline(u64 *fc_regs)
  *     FALSE (0) when the specified port fails to come online after timeout
  *     -EINVAL when @delay_us is less than 1000
  */
-static int wait_port_online(u64 *fc_regs, u32 delay_us, u32 nretry)
+static int wait_port_online(__be64 __iomem *fc_regs, u32 delay_us, u32 nretry)
 {
        u64 status;
 
@@ -982,7 +982,7 @@ static int wait_port_online(u64 *fc_regs, u32 delay_us, u32 nretry)
  *     FALSE (0) when the specified port fails to go offline after timeout
  *     -EINVAL when @delay_us is less than 1000
  */
-static int wait_port_offline(u64 *fc_regs, u32 delay_us, u32 nretry)
+static int wait_port_offline(__be64 __iomem *fc_regs, u32 delay_us, u32 nretry)
 {
        u64 status;
 
@@ -1017,9 +1017,10 @@ static int wait_port_offline(u64 *fc_regs, u32 delay_us, u32 nretry)
  *     0 when the WWPN is successfully written and the port comes back online
  *     -1 when the port fails to go offline or come back up online
  */
-static int afu_set_wwpn(struct afu *afu, int port, u64 *fc_regs, u64 wwpn)
+static int afu_set_wwpn(struct afu *afu, int port, __be64 __iomem *fc_regs,
+                       u64 wwpn)
 {
-       int ret = 0;
+       int rc = 0;
 
        set_port_offline(fc_regs);
 
@@ -1027,33 +1028,26 @@ static int afu_set_wwpn(struct afu *afu, int port, u64 *fc_regs, u64 wwpn)
                               FC_PORT_STATUS_RETRY_CNT)) {
                pr_debug("%s: wait on port %d to go offline timed out\n",
                         __func__, port);
-               ret = -1; /* but continue on to leave the port back online */
+               rc = -1; /* but continue on to leave the port back online */
        }
 
-       if (ret == 0)
+       if (rc == 0)
                writeq_be(wwpn, &fc_regs[FC_PNAME / 8]);
 
+       /* Always return success after programming WWPN */
+       rc = 0;
+
        set_port_online(fc_regs);
 
        if (!wait_port_online(fc_regs, FC_PORT_STATUS_RETRY_INTERVAL_US,
                              FC_PORT_STATUS_RETRY_CNT)) {
-               pr_debug("%s: wait on port %d to go online timed out\n",
-                        __func__, port);
-               ret = -1;
-
-               /*
-                * Override for internal lun!!!
-                */
-               if (afu->internal_lun) {
-                       pr_debug("%s: Overriding port %d online timeout!!!\n",
-                                __func__, port);
-                       ret = 0;
-               }
+               pr_err("%s: wait on port %d to go online timed out\n",
+                      __func__, port);
        }
 
-       pr_debug("%s: returning rc=%d\n", __func__, ret);
+       pr_debug("%s: returning rc=%d\n", __func__, rc);
 
-       return ret;
+       return rc;
 }
 
 /**
@@ -1069,7 +1063,7 @@ static int afu_set_wwpn(struct afu *afu, int port, u64 *fc_regs, u64 wwpn)
  * the alternate port exclusively while the reset takes place.
  * failure to come online is overridden.
  */
-static void afu_link_reset(struct afu *afu, int port, u64 *fc_regs)
+static void afu_link_reset(struct afu *afu, int port, __be64 __iomem *fc_regs)
 {
        u64 port_sel;
 
@@ -1106,19 +1100,19 @@ static const struct asyc_intr_info ainfo[] = {
        {SISL_ASTATUS_FC0_OTHER, "other error", 0, CLR_FC_ERROR | LINK_RESET},
        {SISL_ASTATUS_FC0_LOGO, "target initiated LOGO", 0, 0},
        {SISL_ASTATUS_FC0_CRC_T, "CRC threshold exceeded", 0, LINK_RESET},
-       {SISL_ASTATUS_FC0_LOGI_R, "login timed out, retrying", 0, 0},
+       {SISL_ASTATUS_FC0_LOGI_R, "login timed out, retrying", 0, LINK_RESET},
        {SISL_ASTATUS_FC0_LOGI_F, "login failed", 0, CLR_FC_ERROR},
-       {SISL_ASTATUS_FC0_LOGI_S, "login succeeded", 0, 0},
+       {SISL_ASTATUS_FC0_LOGI_S, "login succeeded", 0, SCAN_HOST},
        {SISL_ASTATUS_FC0_LINK_DN, "link down", 0, 0},
-       {SISL_ASTATUS_FC0_LINK_UP, "link up", 0, 0},
+       {SISL_ASTATUS_FC0_LINK_UP, "link up", 0, SCAN_HOST},
        {SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET},
        {SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0},
        {SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET},
        {SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, 0},
        {SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR},
-       {SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, 0},
+       {SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, SCAN_HOST},
        {SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0},
-       {SISL_ASTATUS_FC1_LINK_UP, "link up", 1, 0},
+       {SISL_ASTATUS_FC1_LINK_UP, "link up", 1, SCAN_HOST},
        {0x0, "", 0, 0}         /* terminator */
 };
 
@@ -1280,47 +1274,46 @@ static irqreturn_t cxlflash_rrq_irq(int irq, void *data)
 static irqreturn_t cxlflash_async_err_irq(int irq, void *data)
 {
        struct afu *afu = (struct afu *)data;
-       struct cxlflash_cfg *cfg;
+       struct cxlflash_cfg *cfg = afu->parent;
+       struct device *dev = &cfg->dev->dev;
        u64 reg_unmasked;
        const struct asyc_intr_info *info;
-       struct sisl_global_map *global = &afu->afu_map->global;
+       struct sisl_global_map __iomem *global = &afu->afu_map->global;
        u64 reg;
        u8 port;
        int i;
 
-       cfg = afu->parent;
-
        reg = readq_be(&global->regs.aintr_status);
        reg_unmasked = (reg & SISL_ASTATUS_UNMASK);
 
        if (reg_unmasked == 0) {
-               pr_err("%s: spurious interrupt, aintr_status 0x%016llX\n",
-                      __func__, reg);
+               dev_err(dev, "%s: spurious interrupt, aintr_status 0x%016llX\n",
+                       __func__, reg);
                goto out;
        }
 
-       /* it is OK to clear AFU status before FC_ERROR */
+       /* FYI, it is 'okay' to clear AFU status before FC_ERROR */
        writeq_be(reg_unmasked, &global->regs.aintr_clear);
 
-       /* check each bit that is on */
+       /* Check each bit that is on */
        for (i = 0; reg_unmasked; i++, reg_unmasked = (reg_unmasked >> 1)) {
                info = find_ainfo(1ULL << i);
-               if ((reg_unmasked & 0x1) || !info)
+               if (((reg_unmasked & 0x1) == 0) || !info)
                        continue;
 
                port = info->port;
 
-               pr_err("%s: FC Port %d -> %s, fc_status 0x%08llX\n",
-                      __func__, port, info->desc,
+               dev_err(dev, "%s: FC Port %d -> %s, fc_status 0x%08llX\n",
+                       __func__, port, info->desc,
                       readq_be(&global->fc_regs[port][FC_STATUS / 8]));
 
                /*
-                * do link reset first, some OTHER errors will set FC_ERROR
+                * Do link reset first, some OTHER errors will set FC_ERROR
                 * again if cleared before or w/o a reset
                 */
                if (info->action & LINK_RESET) {
-                       pr_err("%s: FC Port %d: resetting link\n",
-                              __func__, port);
+                       dev_err(dev, "%s: FC Port %d: resetting link\n",
+                               __func__, port);
                        cfg->lr_state = LINK_RESET_REQUIRED;
                        cfg->lr_port = port;
                        schedule_work(&cfg->work_q);
@@ -1330,26 +1323,31 @@ static irqreturn_t cxlflash_async_err_irq(int irq, void *data)
                        reg = readq_be(&global->fc_regs[port][FC_ERROR / 8]);
 
                        /*
-                        * since all errors are unmasked, FC_ERROR and FC_ERRCAP
+                        * Since all errors are unmasked, FC_ERROR and FC_ERRCAP
                         * should be the same and tracing one is sufficient.
                         */
 
-                       pr_err("%s: fc %d: clearing fc_error 0x%08llX\n",
-                              __func__, port, reg);
+                       dev_err(dev, "%s: fc %d: clearing fc_error 0x%08llX\n",
+                               __func__, port, reg);
 
                        writeq_be(reg, &global->fc_regs[port][FC_ERROR / 8]);
                        writeq_be(0, &global->fc_regs[port][FC_ERRCAP / 8]);
                }
+
+               if (info->action & SCAN_HOST) {
+                       atomic_inc(&cfg->scan_host_needed);
+                       schedule_work(&cfg->work_q);
+               }
        }
 
 out:
-       pr_debug("%s: returning rc=%d, afu=%p\n", __func__, IRQ_HANDLED, afu);
+       dev_dbg(dev, "%s: returning IRQ_HANDLED, afu=%p\n", __func__, afu);
        return IRQ_HANDLED;
 }
 
 /**
  * start_context() - starts the master context
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  *
  * Return: A success or failure value from CXL services.
  */
@@ -1367,12 +1365,10 @@ static int start_context(struct cxlflash_cfg *cfg)
 
 /**
  * read_vpd() - obtains the WWPNs from VPD
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  * @wwpn:      Array of size NUM_FC_PORTS to pass back WWPNs
  *
- * Return:
- *     0 on success
- *     -ENODEV when VPD or WWPN keywords not found
+ * Return: 0 on success, -errno on failure
  */
 static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[])
 {
@@ -1387,7 +1383,7 @@ static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[])
        /* Get the VPD data from the device */
        vpd_size = pci_read_vpd(dev, 0, sizeof(vpd_data), vpd_data);
        if (unlikely(vpd_size <= 0)) {
-               pr_err("%s: Unable to read VPD (size = %ld)\n",
+               dev_err(&dev->dev, "%s: Unable to read VPD (size = %ld)\n",
                       __func__, vpd_size);
                rc = -ENODEV;
                goto out;
@@ -1397,7 +1393,8 @@ static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[])
        ro_start = pci_vpd_find_tag(vpd_data, 0, vpd_size,
                                    PCI_VPD_LRDT_RO_DATA);
        if (unlikely(ro_start < 0)) {
-               pr_err("%s: VPD Read-only data not found\n", __func__);
+               dev_err(&dev->dev, "%s: VPD Read-only data not found\n",
+                       __func__);
                rc = -ENODEV;
                goto out;
        }
@@ -1426,8 +1423,8 @@ static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[])
 
                i = pci_vpd_find_info_keyword(vpd_data, i, j, wwpn_vpd_tags[k]);
                if (unlikely(i < 0)) {
-                       pr_err("%s: Port %d WWPN not found in VPD\n",
-                              __func__, k);
+                       dev_err(&dev->dev, "%s: Port %d WWPN not found "
+                               "in VPD\n", __func__, k);
                        rc = -ENODEV;
                        goto out;
                }
@@ -1435,7 +1432,8 @@ static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[])
                j = pci_vpd_info_field_size(&vpd_data[i]);
                i += PCI_VPD_INFO_FLD_HDR_SIZE;
                if (unlikely((i + j > vpd_size) || (j != WWPN_LEN))) {
-                       pr_err("%s: Port %d WWPN incomplete or VPD corrupt\n",
+                       dev_err(&dev->dev, "%s: Port %d WWPN incomplete or "
+                               "VPD corrupt\n",
                               __func__, k);
                        rc = -ENODEV;
                        goto out;
@@ -1444,8 +1442,8 @@ static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[])
                memcpy(tmp_buf, &vpd_data[i], WWPN_LEN);
                rc = kstrtoul(tmp_buf, WWPN_LEN, (ulong *)&wwpn[k]);
                if (unlikely(rc)) {
-                       pr_err("%s: Fail to convert port %d WWPN to integer\n",
-                              __func__, k);
+                       dev_err(&dev->dev, "%s: Fail to convert port %d WWPN "
+                               "to integer\n", __func__, k);
                        rc = -ENODEV;
                        goto out;
                }
@@ -1458,7 +1456,7 @@ out:
 
 /**
  * init_pcr() - initialize the provisioning and control registers
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  *
  * Also sets up fast access to the mapped registers and initializes AFU
  * command fields that never change.
@@ -1466,28 +1464,27 @@ out:
 static void init_pcr(struct cxlflash_cfg *cfg)
 {
        struct afu *afu = cfg->afu;
-       struct sisl_ctrl_map *ctrl_map;
+       struct sisl_ctrl_map __iomem *ctrl_map;
        int i;
 
        for (i = 0; i < MAX_CONTEXT; i++) {
                ctrl_map = &afu->afu_map->ctrls[i].ctrl;
-               /* disrupt any clients that could be running */
-               /* e. g. clients that survived a master restart */
+               /* Disrupt any clients that could be running */
+               /* e.g. clients that survived a master restart */
                writeq_be(0, &ctrl_map->rht_start);
                writeq_be(0, &ctrl_map->rht_cnt_id);
                writeq_be(0, &ctrl_map->ctx_cap);
        }
 
-       /* copy frequently used fields into afu */
+       /* Copy frequently used fields into afu */
        afu->ctx_hndl = (u16) cxl_process_element(cfg->mcctx);
-       /* ctx_hndl is 16 bits in CAIA */
        afu->host_map = &afu->afu_map->hosts[afu->ctx_hndl].host;
        afu->ctrl_map = &afu->afu_map->ctrls[afu->ctx_hndl].ctrl;
 
        /* Program the Endian Control for the master context */
        writeq_be(SISL_ENDIAN_CTRL, &afu->host_map->endian_ctrl);
 
-       /* initialize cmd fields that never change */
+       /* Initialize cmd fields that never change */
        for (i = 0; i < CXLFLASH_NUM_CMDS; i++) {
                afu->cmd[i].rcb.ctx_id = afu->ctx_hndl;
                afu->cmd[i].rcb.msi = SISL_MSI_RRQ_UPDATED;
@@ -1497,11 +1494,12 @@ static void init_pcr(struct cxlflash_cfg *cfg)
 
 /**
  * init_global() - initialize AFU global registers
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  */
 static int init_global(struct cxlflash_cfg *cfg)
 {
        struct afu *afu = cfg->afu;
+       struct device *dev = &cfg->dev->dev;
        u64 wwpn[NUM_FC_PORTS]; /* wwpn of AFU ports */
        int i = 0, num_ports = 0;
        int rc = 0;
@@ -1509,13 +1507,13 @@ static int init_global(struct cxlflash_cfg *cfg)
 
        rc = read_vpd(cfg, &wwpn[0]);
        if (rc) {
-               pr_err("%s: could not read vpd rc=%d\n", __func__, rc);
+               dev_err(dev, "%s: could not read vpd rc=%d\n", __func__, rc);
                goto out;
        }
 
        pr_debug("%s: wwpn0=0x%llX wwpn1=0x%llX\n", __func__, wwpn[0], wwpn[1]);
 
-       /* set up RRQ in AFU for master issued cmds */
+       /* Set up RRQ in AFU for master issued cmds */
        writeq_be((u64) afu->hrrq_start, &afu->host_map->rrq_start);
        writeq_be((u64) afu->hrrq_end, &afu->host_map->rrq_end);
 
@@ -1528,9 +1526,9 @@ static int init_global(struct cxlflash_cfg *cfg)
        /* checker on if dual afu */
        writeq_be(reg, &afu->afu_map->global.regs.afu_config);
 
-       /* global port select: select either port */
+       /* Global port select: select either port */
        if (afu->internal_lun) {
-               /* only use port 0 */
+               /* Only use port 0 */
                writeq_be(PORT0, &afu->afu_map->global.regs.afu_port_sel);
                num_ports = NUM_FC_PORTS - 1;
        } else {
@@ -1539,20 +1537,20 @@ static int init_global(struct cxlflash_cfg *cfg)
        }
 
        for (i = 0; i < num_ports; i++) {
-               /* unmask all errors (but they are still masked at AFU) */
+               /* Unmask all errors (but they are still masked at AFU) */
                writeq_be(0, &afu->afu_map->global.fc_regs[i][FC_ERRMSK / 8]);
-               /* clear CRC error cnt & set a threshold */
+               /* Clear CRC error cnt & set a threshold */
                (void)readq_be(&afu->afu_map->global.
                               fc_regs[i][FC_CNT_CRCERR / 8]);
                writeq_be(MC_CRC_THRESH, &afu->afu_map->global.fc_regs[i]
                          [FC_CRC_THRESH / 8]);
 
-               /* set WWPNs. If already programmed, wwpn[i] is 0 */
+               /* Set WWPNs. If already programmed, wwpn[i] is 0 */
                if (wwpn[i] != 0 &&
                    afu_set_wwpn(afu, i,
                                 &afu->afu_map->global.fc_regs[i][0],
                                 wwpn[i])) {
-                       pr_err("%s: failed to set WWPN on port %d\n",
+                       dev_err(dev, "%s: failed to set WWPN on port %d\n",
                               __func__, i);
                        rc = -EIO;
                        goto out;
@@ -1561,18 +1559,17 @@ static int init_global(struct cxlflash_cfg *cfg)
                 * offline/online transitions and a PLOGI
                 */
                msleep(100);
-
        }
 
-       /* set up master's own CTX_CAP to allow real mode, host translation */
-       /* tbls, afu cmds and read/write GSCSI cmds. */
+       /* Set up master's own CTX_CAP to allow real mode, host translation */
+       /* tables, afu cmds and read/write GSCSI cmds. */
        /* First, unlock ctx_cap write by reading mbox */
        (void)readq_be(&afu->ctrl_map->mbox_r); /* unlock ctx_cap */
        writeq_be((SISL_CTX_CAP_REAL_MODE | SISL_CTX_CAP_HOST_XLATE |
                   SISL_CTX_CAP_READ_CMD | SISL_CTX_CAP_WRITE_CMD |
                   SISL_CTX_CAP_AFU_CMD | SISL_CTX_CAP_GSCSI_CMD),
                  &afu->ctrl_map->ctx_cap);
-       /* init heartbeat */
+       /* Initialize heartbeat */
        afu->hb = readq_be(&afu->afu_map->global.regs.afu_hb);
 
 out:
@@ -1581,7 +1578,7 @@ out:
 
 /**
  * start_afu() - initializes and starts the AFU
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  */
 static int start_afu(struct cxlflash_cfg *cfg)
 {
@@ -1601,7 +1598,10 @@ static int start_afu(struct cxlflash_cfg *cfg)
 
        init_pcr(cfg);
 
-       /* initialize RRQ pointers */
+       /* After an AFU reset, RRQ entries are stale, clear them */
+       memset(&afu->rrq_entry, 0, sizeof(afu->rrq_entry));
+
+       /* Initialize RRQ pointers */
        afu->hrrq_start = &afu->rrq_entry[0];
        afu->hrrq_end = &afu->rrq_entry[NUM_RRQ_ENTRY - 1];
        afu->hrrq_curr = afu->hrrq_start;
@@ -1615,12 +1615,9 @@ static int start_afu(struct cxlflash_cfg *cfg)
 
 /**
  * init_mc() - create and register as the master context
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  *
- * Return:
- *     0 on success
- *     -ENOMEM when unable to obtain a context from CXL services
- *     A failure value from CXL services.
+ * Return: 0 on success, -errno on failure
  */
 static int init_mc(struct cxlflash_cfg *cfg)
 {
@@ -1704,15 +1701,12 @@ out:
 
 /**
  * init_afu() - setup as master context and start AFU
- * @cxlflash:  Internal structure associated with the host.
+ * @cfg:       Internal structure associated with the host.
  *
  * This routine is a higher level of control for configuring the
  * AFU on probe and reset paths.
  *
- * Return:
- *     0 on success
- *     -ENOMEM when unable to map the AFU MMIO space
- *     A failure value from internal services.
+ * Return: 0 on success, -errno on failure
  */
 static int init_afu(struct cxlflash_cfg *cfg)
 {
@@ -1727,36 +1721,38 @@ static int init_afu(struct cxlflash_cfg *cfg)
        if (rc) {
                dev_err(dev, "%s: call to init_mc failed, rc=%d!\n",
                        __func__, rc);
-               goto err1;
+               goto out;
        }
 
-       /* Map the entire MMIO space of the AFU.
-        */
+       /* Map the entire MMIO space of the AFU */
        afu->afu_map = cxl_psa_map(cfg->mcctx);
        if (!afu->afu_map) {
-               rc = -ENOMEM;
-               term_mc(cfg, UNDO_START);
                dev_err(dev, "%s: call to cxl_psa_map failed!\n", __func__);
+               rc = -ENOMEM;
                goto err1;
        }
 
-       /* don't byte reverse on reading afu_version, else the string form */
-       /*     will be backwards */
-       reg = afu->afu_map->global.regs.afu_version;
-       memcpy(afu->version, &reg, 8);
+       /* No byte reverse on reading afu_version or string will be backwards */
+       reg = readq(&afu->afu_map->global.regs.afu_version);
+       memcpy(afu->version, &reg, sizeof(reg));
        afu->interface_version =
            readq_be(&afu->afu_map->global.regs.interface_version);
-       pr_debug("%s: afu version %s, interface version 0x%llX\n",
-                __func__, afu->version, afu->interface_version);
+       if ((afu->interface_version + 1) == 0) {
+               pr_err("Back level AFU, please upgrade. AFU version %s "
+                      "interface version 0x%llx\n", afu->version,
+                      afu->interface_version);
+               rc = -EINVAL;
+               goto err2;
+       }
+
+       pr_debug("%s: afu version %s, interface version 0x%llX\n", __func__,
+                afu->version, afu->interface_version);
 
        rc = start_afu(cfg);
        if (rc) {
                dev_err(dev, "%s: call to start_afu failed, rc=%d!\n",
                        __func__, rc);
-               term_mc(cfg, UNDO_START);
-               cxl_psa_unmap((void *)afu->afu_map);
-               afu->afu_map = NULL;
-               goto err1;
+               goto err2;
        }
 
        afu_err_intr_init(cfg->afu);
@@ -1764,9 +1760,16 @@ static int init_afu(struct cxlflash_cfg *cfg)
 
        /* Restore the LUN mappings */
        cxlflash_restore_luntable(cfg);
-err1:
+out:
        pr_debug("%s: returning rc=%d\n", __func__, rc);
        return rc;
+
+err2:
+       cxl_psa_unmap((void __iomem *)afu->afu_map);
+       afu->afu_map = NULL;
+err1:
+       term_mc(cfg, UNDO_START);
+       goto out;
 }
 
 /**
@@ -1777,7 +1780,7 @@ err1:
  * @mode:      Type of sync to issue (lightweight, heavyweight, global).
  *
  * The AFU can only take 1 sync command at a time. This routine enforces this
- * limitation by using a mutex to provide exlusive access to the AFU during
+ * limitation by using a mutex to provide exclusive access to the AFU during
  * the sync. This design point requires calling threads to not be on interrupt
  * context due to the possibility of sleeping during concurrent sync operations.
  *
@@ -1795,6 +1798,7 @@ int cxlflash_afu_sync(struct afu *afu, ctx_hndl_t ctx_hndl_u,
                      res_hndl_t res_hndl_u, u8 mode)
 {
        struct cxlflash_cfg *cfg = afu->parent;
+       struct device *dev = &cfg->dev->dev;
        struct afu_cmd *cmd = NULL;
        int rc = 0;
        int retry_cnt = 0;
@@ -1813,7 +1817,7 @@ retry:
                udelay(1000 * retry_cnt);
                if (retry_cnt < MC_RETRY_CNT)
                        goto retry;
-               pr_err("%s: could not get a free command\n", __func__);
+               dev_err(dev, "%s: could not get a free command\n", __func__);
                rc = -1;
                goto out;
        }
@@ -1833,8 +1837,8 @@ retry:
        cmd->rcb.cdb[1] = mode;
 
        /* The cdb is aligned, no unaligned accessors required */
-       *((u16 *)&cmd->rcb.cdb[2]) = swab16(ctx_hndl_u);
-       *((u32 *)&cmd->rcb.cdb[4]) = swab32(res_hndl_u);
+       *((__be16 *)&cmd->rcb.cdb[2]) = cpu_to_be16(ctx_hndl_u);
+       *((__be32 *)&cmd->rcb.cdb[4]) = cpu_to_be32(res_hndl_u);
 
        rc = send_cmd(afu, cmd);
        if (unlikely(rc))
@@ -1842,7 +1846,7 @@ retry:
 
        wait_resp(afu, cmd);
 
-       /* set on timeout */
+       /* Set on timeout */
        if (unlikely((cmd->sa.ioasc != 0) ||
                     (cmd->sa.host_use_b[0] & B_ERROR)))
                rc = -1;
@@ -1858,9 +1862,7 @@ out:
  * afu_reset() - resets the AFU
  * @cfg:       Internal structure associated with the host.
  *
- * Return:
- *     0 on success
- *     A failure value from internal services.
+ * Return: 0 on success, -errno on failure
  */
 static int afu_reset(struct cxlflash_cfg *cfg)
 {
@@ -1902,6 +1904,7 @@ static int cxlflash_eh_device_reset_handler(struct scsi_cmnd *scp)
                 get_unaligned_be32(&((u32 *)scp->cmnd)[2]),
                 get_unaligned_be32(&((u32 *)scp->cmnd)[3]));
 
+retry:
        switch (cfg->state) {
        case STATE_NORMAL:
                rcr = send_tmf(afu, scp, TMF_LUN_RESET);
@@ -1910,9 +1913,7 @@ static int cxlflash_eh_device_reset_handler(struct scsi_cmnd *scp)
                break;
        case STATE_RESET:
                wait_event(cfg->reset_waitq, cfg->state != STATE_RESET);
-               if (cfg->state == STATE_NORMAL)
-                       break;
-               /* fall through */
+               goto retry;
        default:
                rc = FAILED;
                break;
@@ -1949,7 +1950,6 @@ static int cxlflash_eh_host_reset_handler(struct scsi_cmnd *scp)
        switch (cfg->state) {
        case STATE_NORMAL:
                cfg->state = STATE_RESET;
-               scsi_block_requests(cfg->host);
                cxlflash_mark_contexts_error(cfg);
                rcr = afu_reset(cfg);
                if (rcr) {
@@ -1958,7 +1958,6 @@ static int cxlflash_eh_host_reset_handler(struct scsi_cmnd *scp)
                } else
                        cfg->state = STATE_NORMAL;
                wake_up_all(&cfg->reset_waitq);
-               scsi_unblock_requests(cfg->host);
                break;
        case STATE_RESET:
                wait_event(cfg->reset_waitq, cfg->state != STATE_RESET);
@@ -2264,7 +2263,7 @@ static struct scsi_host_template driver_template = {
        .cmd_per_lun = 16,
        .can_queue = CXLFLASH_MAX_CMDS,
        .this_id = -1,
-       .sg_tablesize = SG_NONE,        /* No scatter gather support. */
+       .sg_tablesize = SG_NONE,        /* No scatter gather support */
        .max_sectors = CXLFLASH_MAX_SECTORS,
        .use_clustering = ENABLE_CLUSTERING,
        .shost_attrs = cxlflash_host_attrs,
@@ -2295,12 +2294,14 @@ MODULE_DEVICE_TABLE(pci, cxlflash_pci_table);
  * - Link reset which cannot be performed on interrupt context due to
  * blocking up to a few seconds
  * - Read AFU command room
+ * - Rescan the host
  */
 static void cxlflash_worker_thread(struct work_struct *work)
 {
        struct cxlflash_cfg *cfg = container_of(work, struct cxlflash_cfg,
                                                work_q);
        struct afu *afu = cfg->afu;
+       struct device *dev = &cfg->dev->dev;
        int port;
        ulong lock_flags;
 
@@ -2314,15 +2315,15 @@ static void cxlflash_worker_thread(struct work_struct *work)
        if (cfg->lr_state == LINK_RESET_REQUIRED) {
                port = cfg->lr_port;
                if (port < 0)
-                       pr_err("%s: invalid port index %d\n", __func__, port);
+                       dev_err(dev, "%s: invalid port index %d\n",
+                               __func__, port);
                else {
                        spin_unlock_irqrestore(cfg->host->host_lock,
                                               lock_flags);
 
                        /* The reset can block... */
                        afu_link_reset(afu, port,
-                                      &afu->afu_map->
-                                      global.fc_regs[port][0]);
+                                      &afu->afu_map->global.fc_regs[port][0]);
                        spin_lock_irqsave(cfg->host->host_lock, lock_flags);
                }
 
@@ -2335,6 +2336,9 @@ static void cxlflash_worker_thread(struct work_struct *work)
        }
 
        spin_unlock_irqrestore(cfg->host->host_lock, lock_flags);
+
+       if (atomic_dec_if_positive(&cfg->scan_host_needed) >= 0)
+               scsi_scan_host(cfg->host);
 }
 
 /**
@@ -2342,7 +2346,7 @@ static void cxlflash_worker_thread(struct work_struct *work)
  * @pdev:      PCI device associated with the host.
  * @dev_id:    PCI device id associated with device.
  *
- * Return: 0 on success / non-zero on failure
+ * Return: 0 on success, -errno on failure
  */
 static int cxlflash_probe(struct pci_dev *pdev,
                          const struct pci_device_id *dev_id)
@@ -2377,14 +2381,16 @@ static int cxlflash_probe(struct pci_dev *pdev,
        cfg->host = host;
        rc = alloc_mem(cfg);
        if (rc) {
-               dev_err(&pdev->dev, "%s: call to scsi_host_alloc failed!\n",
+               dev_err(&pdev->dev, "%s: call to alloc_mem failed!\n",
                        __func__);
                rc = -ENOMEM;
+               scsi_host_put(cfg->host);
                goto out;
        }
 
        cfg->init_state = INIT_STATE_NONE;
        cfg->dev = pdev;
+       cfg->cxl_fops = cxlflash_cxl_fops;
 
        /*
         * The promoted LUNs move to the top of the LUN table. The rest stay
@@ -2397,7 +2403,6 @@ static int cxlflash_probe(struct pci_dev *pdev,
        cfg->last_lun_index[1] = CXLFLASH_NUM_VLUNS/2 - 1;
 
        cfg->dev_id = (struct pci_device_id *)dev_id;
-       cfg->mcctx = NULL;
 
        init_waitqueue_head(&cfg->tmf_waitq);
        init_waitqueue_head(&cfg->reset_waitq);
@@ -2405,6 +2410,7 @@ static int cxlflash_probe(struct pci_dev *pdev,
        INIT_WORK(&cfg->work_q, cxlflash_worker_thread);
        cfg->lr_state = LINK_RESET_INVALID;
        cfg->lr_port = -1;
+       spin_lock_init(&cfg->tmf_slock);
        mutex_init(&cfg->ctx_tbl_list_mutex);
        mutex_init(&cfg->ctx_recovery_mutex);
        init_rwsem(&cfg->ioctl_rwsem);
@@ -2413,13 +2419,14 @@ static int cxlflash_probe(struct pci_dev *pdev,
 
        pci_set_drvdata(pdev, cfg);
 
-       /* Use the special service provided to look up the physical
+       /*
+        * Use the special service provided to look up the physical
         * PCI device, since we are called on the probe of the virtual
         * PCI host bus (vphb)
         */
        phys_dev = cxl_get_phys_dev(pdev);
        if (!dev_is_pci(phys_dev)) {
-               pr_err("%s: not a pci dev\n", __func__);
+               dev_err(&pdev->dev, "%s: not a pci dev\n", __func__);
                rc = -ENODEV;
                goto out_remove;
        }
@@ -2443,7 +2450,6 @@ static int cxlflash_probe(struct pci_dev *pdev,
        }
        cfg->init_state = INIT_STATE_AFU;
 
-
        rc = init_scsi(cfg);
        if (rc) {
                dev_err(&pdev->dev, "%s: call to init_scsi "
@@ -2575,7 +2581,7 @@ static struct pci_driver cxlflash_driver = {
 /**
  * init_cxlflash() - module entry point
  *
- * Return: 0 on success / non-zero on failure
+ * Return: 0 on success, -errno on failure
  */
 static int __init init_cxlflash(void)
 {