diff options
author | Matthew R. Ochs <mrochs@linux.vnet.ibm.com> | 2015-10-21 15:13:37 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Odin.com> | 2015-10-30 17:12:22 +0900 |
commit | ef51074a4efef50873fb8939e7feba5dd55488da (patch) | |
tree | db9bcf7908479139aa3dff76068514a7983f7313 /drivers/scsi/cxlflash | |
parent | 8396012ff77affe4def5f0e5757b6c4e8107b33e (diff) |
cxlflash: Fix host link up event handling
Following a link up event, the LUNs available to the host may
have changed. Without rescanning the host, the LUN topology is
unknown to the user. In such a state, the user would be unable
to locate provisioned resources.
To remedy, the host should be rescanned after a link up event.
Signed-off-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>
Reviewed-by: Brian King <brking@linux.vnet.ibm.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: James Bottomley <JBottomley@Odin.com>
Diffstat (limited to 'drivers/scsi/cxlflash')
-rw-r--r-- | drivers/scsi/cxlflash/common.h | 1 | ||||
-rw-r--r-- | drivers/scsi/cxlflash/main.c | 17 | ||||
-rw-r--r-- | drivers/scsi/cxlflash/main.h | 1 |
3 files changed, 15 insertions, 4 deletions
diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h index 7a0cb5c0dad4..faf7f56f0fb3 100644 --- a/drivers/scsi/cxlflash/common.h +++ b/drivers/scsi/cxlflash/common.h @@ -102,6 +102,7 @@ struct cxlflash_cfg { enum cxlflash_init_state init_state; enum cxlflash_lr_state lr_state; int lr_port; + atomic_t scan_host_needed; struct cxl_afu *cxl_afu; diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 5503a403cdc0..98fdac1e1c45 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -1119,17 +1119,17 @@ static const struct asyc_intr_info ainfo[] = { {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_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 */ }; @@ -1350,6 +1350,11 @@ static irqreturn_t cxlflash_async_err_irq(int irq, void *data) 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: @@ -2309,6 +2314,7 @@ 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) { @@ -2351,6 +2357,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); } /** diff --git a/drivers/scsi/cxlflash/main.h b/drivers/scsi/cxlflash/main.h index cf0e80938b13..60324566c14f 100644 --- a/drivers/scsi/cxlflash/main.h +++ b/drivers/scsi/cxlflash/main.h @@ -99,6 +99,7 @@ struct asyc_intr_info { u8 action; #define CLR_FC_ERROR 0x01 #define LINK_RESET 0x02 +#define SCAN_HOST 0x04 }; #ifndef CONFIG_CXL_EEH |