* [PATCH v2 1/7] nvmet: add transport discovery change op
2019-05-14 21:58 [PATCH v2 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
@ 2019-05-14 21:58 ` James Smart
2019-05-29 22:21 ` Sagi Grimberg
2019-05-14 21:58 ` [PATCH v2 2/7] nvmet_fc: add transport discovery change event callback support James Smart
` (6 subsequent siblings)
7 siblings, 1 reply; 15+ messages in thread
From: James Smart @ 2019-05-14 21:58 UTC (permalink / raw)
Some transports, such as FC-NVME, support discovery controller change
events without the use of a persistent discovery controller. FC receives
events via RSCN from the FC Fabric Controller or subsystem FC port.
This patch adds a nvmet transport op that is called whenever a
discovery change event occurs in the nvmet layer.
To facilitate the callback without adding another layer to cross into
core.c to reference the transport ops, the port structure snapshots
the transport ops when the port is enabled and clears them when disabled.
Signed-off-by: James Smart <jsmart2021 at gmail.com>
Reviewed-by: Hannes Reinecke <hare at suse.com>
---
drivers/nvme/target/core.c | 2 ++
drivers/nvme/target/discovery.c | 4 ++++
drivers/nvme/target/nvmet.h | 2 ++
3 files changed, 8 insertions(+)
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 7734a6acff85..43e8c4adc1f4 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -311,6 +311,7 @@ int nvmet_enable_port(struct nvmet_port *port)
port->inline_data_size = 0;
port->enabled = true;
+ port->tr_ops = ops;
return 0;
}
@@ -321,6 +322,7 @@ void nvmet_disable_port(struct nvmet_port *port)
lockdep_assert_held(&nvmet_config_sem);
port->enabled = false;
+ port->tr_ops = NULL;
ops = nvmet_transports[port->disc_addr.trtype];
ops->remove_port(port);
diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c
index 5baf269f3f8a..8efca26b4776 100644
--- a/drivers/nvme/target/discovery.c
+++ b/drivers/nvme/target/discovery.c
@@ -41,6 +41,10 @@ void nvmet_port_disc_changed(struct nvmet_port *port,
__nvmet_disc_changed(port, ctrl);
}
mutex_unlock(&nvmet_disc_subsys->lock);
+
+ /* If transport can signal change, notify transport */
+ if (port->tr_ops && port->tr_ops->discovery_chg)
+ port->tr_ops->discovery_chg(port);
}
static void __nvmet_subsys_disc_changed(struct nvmet_port *port,
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index c25d88fc9dec..dc270944bb25 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -140,6 +140,7 @@ struct nvmet_port {
void *priv;
bool enabled;
int inline_data_size;
+ const struct nvmet_fabrics_ops *tr_ops;
};
static inline struct nvmet_port *to_nvmet_port(struct config_item *item)
@@ -277,6 +278,7 @@ struct nvmet_fabrics_ops {
void (*disc_traddr)(struct nvmet_req *req,
struct nvmet_port *port, char *traddr);
u16 (*install_queue)(struct nvmet_sq *nvme_sq);
+ void (*discovery_chg)(struct nvmet_port *port);
};
#define NVMET_MAX_INLINE_BIOVEC 8
--
2.13.7
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v2 1/7] nvmet: add transport discovery change op
2019-05-14 21:58 ` [PATCH v2 1/7] nvmet: add transport discovery change op James Smart
@ 2019-05-29 22:21 ` Sagi Grimberg
2019-05-29 22:27 ` James Smart
0 siblings, 1 reply; 15+ messages in thread
From: Sagi Grimberg @ 2019-05-29 22:21 UTC (permalink / raw)
> diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c
> index 5baf269f3f8a..8efca26b4776 100644
> --- a/drivers/nvme/target/discovery.c
> +++ b/drivers/nvme/target/discovery.c
> @@ -41,6 +41,10 @@ void nvmet_port_disc_changed(struct nvmet_port *port,
> __nvmet_disc_changed(port, ctrl);
> }
> mutex_unlock(&nvmet_disc_subsys->lock);
> +
> + /* If transport can signal change, notify transport */
> + if (port->tr_ops && port->tr_ops->discovery_chg)
> + port->tr_ops->discovery_chg(port);
So you are shooting for both transport and disc aen to happen
at the same time?
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 1/7] nvmet: add transport discovery change op
2019-05-29 22:21 ` Sagi Grimberg
@ 2019-05-29 22:27 ` James Smart
2019-05-29 22:42 ` Sagi Grimberg
0 siblings, 1 reply; 15+ messages in thread
From: James Smart @ 2019-05-29 22:27 UTC (permalink / raw)
On 5/29/2019 3:21 PM, Sagi Grimberg wrote:
>
>> diff --git a/drivers/nvme/target/discovery.c
>> b/drivers/nvme/target/discovery.c
>> index 5baf269f3f8a..8efca26b4776 100644
>> --- a/drivers/nvme/target/discovery.c
>> +++ b/drivers/nvme/target/discovery.c
>> @@ -41,6 +41,10 @@ void nvmet_port_disc_changed(struct nvmet_port *port,
>> ????????? __nvmet_disc_changed(port, ctrl);
>> ????? }
>> ????? mutex_unlock(&nvmet_disc_subsys->lock);
>> +
>> +??? /* If transport can signal change, notify transport */
>> +??? if (port->tr_ops && port->tr_ops->discovery_chg)
>> +??????? port->tr_ops->discovery_chg(port);
>
> So you are shooting for both transport and disc aen to happen
> at the same time?
they could if the discovery controller is a persistent one.
-- james
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 1/7] nvmet: add transport discovery change op
2019-05-29 22:27 ` James Smart
@ 2019-05-29 22:42 ` Sagi Grimberg
2019-05-29 22:58 ` James Smart
0 siblings, 1 reply; 15+ messages in thread
From: Sagi Grimberg @ 2019-05-29 22:42 UTC (permalink / raw)
>>> diff --git a/drivers/nvme/target/discovery.c
>>> b/drivers/nvme/target/discovery.c
>>> index 5baf269f3f8a..8efca26b4776 100644
>>> --- a/drivers/nvme/target/discovery.c
>>> +++ b/drivers/nvme/target/discovery.c
>>> @@ -41,6 +41,10 @@ void nvmet_port_disc_changed(struct nvmet_port *port,
>>> ????????? __nvmet_disc_changed(port, ctrl);
>>> ????? }
>>> ????? mutex_unlock(&nvmet_disc_subsys->lock);
>>> +
>>> +??? /* If transport can signal change, notify transport */
>>> +??? if (port->tr_ops && port->tr_ops->discovery_chg)
>>> +??????? port->tr_ops->discovery_chg(port);
>>
>> So you are shooting for both transport and disc aen to happen
>> at the same time?
>
> they could if the discovery controller is a persistent one.
That's fine I suppose.
So the series looks pretty reasonable to me. Any feedback from
the FC folks?
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 1/7] nvmet: add transport discovery change op
2019-05-29 22:42 ` Sagi Grimberg
@ 2019-05-29 22:58 ` James Smart
2019-05-30 1:04 ` Sagi Grimberg
0 siblings, 1 reply; 15+ messages in thread
From: James Smart @ 2019-05-29 22:58 UTC (permalink / raw)
On 5/29/2019 3:42 PM, Sagi Grimberg wrote:
>
>>>> diff --git a/drivers/nvme/target/discovery.c
>>>> b/drivers/nvme/target/discovery.c
>>>> index 5baf269f3f8a..8efca26b4776 100644
>>>> --- a/drivers/nvme/target/discovery.c
>>>> +++ b/drivers/nvme/target/discovery.c
>>>> @@ -41,6 +41,10 @@ void nvmet_port_disc_changed(struct nvmet_port
>>>> *port,
>>>> ????????? __nvmet_disc_changed(port, ctrl);
>>>> ????? }
>>>> ????? mutex_unlock(&nvmet_disc_subsys->lock);
>>>> +
>>>> +??? /* If transport can signal change, notify transport */
>>>> +??? if (port->tr_ops && port->tr_ops->discovery_chg)
>>>> +??????? port->tr_ops->discovery_chg(port);
>>>
>>> So you are shooting for both transport and disc aen to happen
>>> at the same time?
>>
>> they could if the discovery controller is a persistent one.
>
> That's fine I suppose.
>
> So the series looks pretty reasonable to me. Any feedback from
> the FC folks?
in what way ?
no disagreements here on the list. Already present in the FC-NVME spec.
-- james
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 1/7] nvmet: add transport discovery change op
2019-05-29 22:58 ` James Smart
@ 2019-05-30 1:04 ` Sagi Grimberg
0 siblings, 0 replies; 15+ messages in thread
From: Sagi Grimberg @ 2019-05-30 1:04 UTC (permalink / raw)
>> That's fine I suppose.
>>
>> So the series looks pretty reasonable to me. Any feedback from
>> the FC folks?
>
> in what way ?
>
> no disagreements here on the list. Already present in the FC-NVME spec.
Just wanted to understand if no disagreements because no one looked, or
because it makes sense to everyone..
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 2/7] nvmet_fc: add transport discovery change event callback support
2019-05-14 21:58 [PATCH v2 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
2019-05-14 21:58 ` [PATCH v2 1/7] nvmet: add transport discovery change op James Smart
@ 2019-05-14 21:58 ` James Smart
2019-05-14 21:58 ` [PATCH v2 3/7] nvme-fcloop: Add support for nvmet discovery_event op James Smart
` (5 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: James Smart @ 2019-05-14 21:58 UTC (permalink / raw)
This patch adds support for the nvmet discovery_change transport op.
In turn, the transport adds it's own LLDD api callback discovery_event
op to request the LLDD to generate an RSCN for the discovery change.
Signed-off-by: James Smart <jsmart2021 at gmail.com>
Reviewed-by: Hannes Reinecke <hare at suse.com>
---
drivers/nvme/target/fc.c | 11 +++++++++++
include/linux/nvme-fc-driver.h | 6 ++++++
2 files changed, 17 insertions(+)
diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c
index 508661af0f50..1f252c9a953a 100644
--- a/drivers/nvme/target/fc.c
+++ b/drivers/nvme/target/fc.c
@@ -2549,6 +2549,16 @@ nvmet_fc_remove_port(struct nvmet_port *port)
kfree(pe);
}
+static void
+nvmet_fc_discovery_chg(struct nvmet_port *port)
+{
+ struct nvmet_fc_port_entry *pe = port->priv;
+ struct nvmet_fc_tgtport *tgtport = pe->tgtport;
+
+ if (tgtport && tgtport->ops->discovery_event)
+ tgtport->ops->discovery_event(&tgtport->fc_target_port);
+}
+
static const struct nvmet_fabrics_ops nvmet_fc_tgt_fcp_ops = {
.owner = THIS_MODULE,
.type = NVMF_TRTYPE_FC,
@@ -2557,6 +2567,7 @@ static const struct nvmet_fabrics_ops nvmet_fc_tgt_fcp_ops = {
.remove_port = nvmet_fc_remove_port,
.queue_response = nvmet_fc_fcp_nvme_cmd_done,
.delete_ctrl = nvmet_fc_delete_ctrl,
+ .discovery_chg = nvmet_fc_discovery_chg,
};
static int __init nvmet_fc_init_module(void)
diff --git a/include/linux/nvme-fc-driver.h b/include/linux/nvme-fc-driver.h
index 2bb349035431..5bbcb7afef39 100644
--- a/include/linux/nvme-fc-driver.h
+++ b/include/linux/nvme-fc-driver.h
@@ -797,6 +797,11 @@ struct nvmet_fc_target_port {
* nvmefc_tgt_fcp_req.
* Entrypoint is Optional.
*
+ * @discovery_event: Called by the transport to generate an RSCN
+ * change notifications to NVME initiators. The RSCN notifications
+ * should cause the initiator to rescan the discovery controller
+ * on the targetport.
+ *
* @max_hw_queues: indicates the maximum number of hw queues the LLDD
* supports for cpu affinitization.
* Value is Mandatory. Must be at least 1.
@@ -838,6 +843,7 @@ struct nvmet_fc_target_template {
struct nvmefc_tgt_fcp_req *fcpreq);
void (*defer_rcv)(struct nvmet_fc_target_port *tgtport,
struct nvmefc_tgt_fcp_req *fcpreq);
+ void (*discovery_event)(struct nvmet_fc_target_port *tgtport);
u32 max_hw_queues;
u16 max_sgl_segments;
--
2.13.7
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v2 3/7] nvme-fcloop: Add support for nvmet discovery_event op
2019-05-14 21:58 [PATCH v2 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
2019-05-14 21:58 ` [PATCH v2 1/7] nvmet: add transport discovery change op James Smart
2019-05-14 21:58 ` [PATCH v2 2/7] nvmet_fc: add transport discovery change event callback support James Smart
@ 2019-05-14 21:58 ` James Smart
2019-05-14 21:58 ` [PATCH v2 4/7] lpfc: Add support to generate RSCN events for nport James Smart
` (4 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: James Smart @ 2019-05-14 21:58 UTC (permalink / raw)
Update fcloop to support the discovery_event operation and
invoke a nvme rescan. In a real fc adapter, this would generate an
RSCN, which the host would receive and convert into a nvme rescan
on the remote port specified in the rscn payload.
Signed-off-by: James Smart <jsmart2021 at gmail.com>
Reviewed-by: Hannes Reinecke <hare at suse.com>
---
drivers/nvme/target/fcloop.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c
index 381b5a90c48b..6ddcd090ec07 100644
--- a/drivers/nvme/target/fcloop.c
+++ b/drivers/nvme/target/fcloop.c
@@ -231,6 +231,11 @@ struct fcloop_lsreq {
int status;
};
+struct fcloop_rscn {
+ struct fcloop_tport *tport;
+ struct work_struct work;
+};
+
enum {
INI_IO_START = 0,
INI_IO_ACTIVE = 1,
@@ -348,6 +353,37 @@ fcloop_xmt_ls_rsp(struct nvmet_fc_target_port *tport,
return 0;
}
+/*
+ * Simulate reception of RSCN and converting it to a initiator transport
+ * call to rescan a remote port.
+ */
+static void
+fcloop_tgt_rscn_work(struct work_struct *work)
+{
+ struct fcloop_rscn *tgt_rscn =
+ container_of(work, struct fcloop_rscn, work);
+ struct fcloop_tport *tport = tgt_rscn->tport;
+
+ if (tport->remoteport)
+ nvme_fc_rescan_remoteport(tport->remoteport);
+ kfree(tgt_rscn);
+}
+
+void
+fcloop_tgt_discovery_evt(struct nvmet_fc_target_port *tgtport)
+{
+ struct fcloop_rscn *tgt_rscn;
+
+ tgt_rscn = kzalloc(sizeof(*tgt_rscn), GFP_KERNEL);
+ if (!tgt_rscn)
+ return;
+
+ tgt_rscn->tport = tgtport->private;
+ INIT_WORK(&tgt_rscn->work, fcloop_tgt_rscn_work);
+
+ schedule_work(&tgt_rscn->work);
+}
+
static void
fcloop_tfcp_req_free(struct kref *ref)
{
@@ -839,6 +875,7 @@ static struct nvmet_fc_target_template tgttemplate = {
.fcp_op = fcloop_fcp_op,
.fcp_abort = fcloop_tgt_fcp_abort,
.fcp_req_release = fcloop_fcp_req_release,
+ .discovery_event = fcloop_tgt_discovery_evt,
.max_hw_queues = FCLOOP_HW_QUEUES,
.max_sgl_segments = FCLOOP_SGL_SEGS,
.max_dif_sgl_segments = FCLOOP_SGL_SEGS,
--
2.13.7
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v2 4/7] lpfc: Add support to generate RSCN events for nport
2019-05-14 21:58 [PATCH v2 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
` (2 preceding siblings ...)
2019-05-14 21:58 ` [PATCH v2 3/7] nvme-fcloop: Add support for nvmet discovery_event op James Smart
@ 2019-05-14 21:58 ` James Smart
2019-05-14 21:58 ` [PATCH v2 5/7] lpfc: add nvmet discovery_event op support James Smart
` (3 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: James Smart @ 2019-05-14 21:58 UTC (permalink / raw)
This patch adds general RSCN support:
- The ability to transmit an RSCN to the port on the other end of
the link (regular port if pt2pt, or fabric controller if fabric).
- And general recognition of an RSCN ELS when an ELS is received.
Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
Signed-off-by: James Smart <jsmart2021 at gmail.com>
Reviewed-by: Hannes Reinecke <hare at suse.com>
---
drivers/scsi/lpfc/lpfc.h | 1 +
drivers/scsi/lpfc/lpfc_crtn.h | 2 +
drivers/scsi/lpfc/lpfc_els.c | 122 +++++++++++++++++++++++++++++++++++++++
drivers/scsi/lpfc/lpfc_hbadisc.c | 35 +++++++++++
drivers/scsi/lpfc/lpfc_hw.h | 2 +
drivers/scsi/lpfc/lpfc_sli.c | 1 +
6 files changed, 163 insertions(+)
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 41d849f283f6..9246e0212a86 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -274,6 +274,7 @@ struct lpfc_stats {
uint32_t elsXmitADISC;
uint32_t elsXmitLOGO;
uint32_t elsXmitSCR;
+ uint32_t elsXmitRSCN;
uint32_t elsXmitRNID;
uint32_t elsXmitFARP;
uint32_t elsXmitFARPR;
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index e0b14d791b8c..4b8eb9107b85 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -141,6 +141,7 @@ int lpfc_issue_els_adisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
int lpfc_issue_els_logo(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
int lpfc_issue_els_npiv_logo(struct lpfc_vport *, struct lpfc_nodelist *);
int lpfc_issue_els_scr(struct lpfc_vport *, uint32_t, uint8_t);
+int lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry);
int lpfc_issue_fabric_reglogin(struct lpfc_vport *);
int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
int lpfc_ct_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
@@ -355,6 +356,7 @@ void lpfc_mbox_timeout_handler(struct lpfc_hba *);
struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t);
struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *,
struct lpfc_name *);
+struct lpfc_nodelist *lpfc_findnode_mapped(struct lpfc_vport *vport);
int lpfc_sli_issue_mbox_wait(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index fc077cb87900..c9a40e05edcc 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -30,6 +30,8 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_fc.h>
+#include <uapi/scsi/fc/fc_fs.h>
+#include <uapi/scsi/fc/fc_els.h>
#include "lpfc_hw4.h"
#include "lpfc_hw.h"
@@ -3082,6 +3084,116 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
}
/**
+ * lpfc_issue_els_rscn - Issue an RSCN to the Fabric Controller (Fabric)
+ * or the other nport (pt2pt).
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @retry: number of retries to the command IOCB.
+ *
+ * This routine issues a RSCN to the Fabric Controller (DID 0xFFFFFD)
+ * when connected to a fabric, or to the remote port when connected
+ * in point-to-point mode. When sent to the Fabric Controller, it will
+ * replay the RSCN to registered recipients.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the RSCN ELS command.
+ *
+ * Return code
+ * 0 - Successfully issued RSCN command
+ * 1 - Failed to issue RSCN command
+ **/
+int
+lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry)
+{
+ struct lpfc_hba *phba = vport->phba;
+ struct lpfc_iocbq *elsiocb;
+ struct lpfc_nodelist *ndlp;
+ struct {
+ struct fc_els_rscn rscn;
+ struct fc_els_rscn_page portid;
+ } *event;
+ uint32_t nportid;
+ uint16_t cmdsize = sizeof(*event);
+
+ /* Not supported for private loop */
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP &&
+ !(vport->fc_flag & FC_PUBLIC_LOOP))
+ return 1;
+
+ if (vport->fc_flag & FC_PT2PT) {
+ /* find any mapped nport - that would be the other nport */
+ ndlp = lpfc_findnode_mapped(vport);
+ if (!ndlp)
+ return 1;
+ } else {
+ nportid = FC_FID_FCTRL;
+ /* find the fabric controller node */
+ ndlp = lpfc_findnode_did(vport, nportid);
+ if (!ndlp) {
+ /* if one didn't exist, make one */
+ ndlp = lpfc_nlp_init(vport, nportid);
+ if (!ndlp)
+ return 1;
+ lpfc_enqueue_node(vport, ndlp);
+ } else if (!NLP_CHK_NODE_ACT(ndlp)) {
+ ndlp = lpfc_enable_node(vport, ndlp,
+ NLP_STE_UNUSED_NODE);
+ if (!ndlp)
+ return 1;
+ }
+ }
+
+ elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
+ ndlp->nlp_DID, ELS_CMD_RSCN_XMT);
+
+ if (!elsiocb) {
+ /* This will trigger the release of the node just
+ * allocated
+ */
+ lpfc_nlp_put(ndlp);
+ return 1;
+ }
+
+ event = ((struct lpfc_dmabuf *)elsiocb->context2)->virt;
+
+ event->rscn.rscn_cmd = ELS_RSCN;
+ event->rscn.rscn_page_len = sizeof(struct fc_els_rscn_page);
+ event->rscn.rscn_plen = cpu_to_be16(cmdsize);
+
+ nportid = vport->fc_myDID;
+ /* appears that page flags must be 0 for fabric to broadcast RSCN */
+ event->portid.rscn_page_flags = 0;
+ event->portid.rscn_fid[0] = (nportid & 0x00FF0000) >> 16;
+ event->portid.rscn_fid[1] = (nportid & 0x0000FF00) >> 8;
+ event->portid.rscn_fid[2] = nportid & 0x000000FF;
+
+ lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
+ "Issue RSCN: did:x%x",
+ ndlp->nlp_DID, 0, 0);
+
+ phba->fc_stat.elsXmitRSCN++;
+ elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
+ if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
+ IOCB_ERROR) {
+ /* The additional lpfc_nlp_put will cause the following
+ * lpfc_els_free_iocb routine to trigger the rlease of
+ * the node.
+ */
+ lpfc_nlp_put(ndlp);
+ lpfc_els_free_iocb(phba, elsiocb);
+ return 1;
+ }
+ /* This will cause the callback-function lpfc_cmpl_els_cmd to
+ * trigger the release of node.
+ */
+ if (!(vport->fc_flag & FC_PT2PT))
+ lpfc_nlp_put(ndlp);
+
+ return 0;
+}
+
+/**
* lpfc_issue_els_farpr - Issue a farp to an node on a vport
* @vport: pointer to a host virtual N_Port data structure.
* @nportid: N_Port identifier to the remote node.
@@ -6321,6 +6433,16 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
fc_host_post_event(shost, fc_get_event_number(),
FCH_EVT_RSCN, lp[i]);
+ /* Check if RSCN is coming from a direct-connected remote NPort */
+ if (vport->fc_flag & FC_PT2PT) {
+ /* If so, just ACC it, no other action needed for now */
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "2024 pt2pt RSCN %08x Data: x%x x%x\n",
+ *lp, vport->fc_flag, payload_len);
+ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
+ return 0;
+ }
+
/* If we are about to begin discovery, just ACC the RSCN.
* Discovery processing will satisfy it.
*/
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index aa4961a2caf8..9b016666601f 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -5261,6 +5261,41 @@ lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did)
}
struct lpfc_nodelist *
+lpfc_findnode_mapped(struct lpfc_vport *vport)
+{
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+ struct lpfc_nodelist *ndlp;
+ uint32_t data1;
+ unsigned long iflags;
+
+ spin_lock_irqsave(shost->host_lock, iflags);
+
+ list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
+ if (ndlp->nlp_state == NLP_STE_UNMAPPED_NODE ||
+ ndlp->nlp_state == NLP_STE_MAPPED_NODE) {
+ data1 = (((uint32_t)ndlp->nlp_state << 24) |
+ ((uint32_t)ndlp->nlp_xri << 16) |
+ ((uint32_t)ndlp->nlp_type << 8) |
+ ((uint32_t)ndlp->nlp_rpi & 0xff));
+ spin_unlock_irqrestore(shost->host_lock, iflags);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+ "2025 FIND node DID "
+ "Data: x%p x%x x%x x%x %p\n",
+ ndlp, ndlp->nlp_DID,
+ ndlp->nlp_flag, data1,
+ ndlp->active_rrqs_xri_bitmap);
+ return ndlp;
+ }
+ }
+ spin_unlock_irqrestore(shost->host_lock, iflags);
+
+ /* FIND node did <did> NOT FOUND */
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+ "2026 FIND mapped did NOT FOUND.\n");
+ return NULL;
+}
+
+struct lpfc_nodelist *
lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index ec1227018913..5e5b3318042e 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -599,6 +599,7 @@ struct fc_vft_header {
#define ELS_CMD_RPL 0x57000000
#define ELS_CMD_FAN 0x60000000
#define ELS_CMD_RSCN 0x61040000
+#define ELS_CMD_RSCN_XMT 0x61040008
#define ELS_CMD_SCR 0x62000000
#define ELS_CMD_RNID 0x78000000
#define ELS_CMD_LIRR 0x7A000000
@@ -639,6 +640,7 @@ struct fc_vft_header {
#define ELS_CMD_RPL 0x57
#define ELS_CMD_FAN 0x60
#define ELS_CMD_RSCN 0x0461
+#define ELS_CMD_RSCN_XMT 0x08000461
#define ELS_CMD_SCR 0x62
#define ELS_CMD_RNID 0x78
#define ELS_CMD_LIRR 0x7A
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 57b4a463b589..cbe7a0f36f4b 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -9373,6 +9373,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) {
if (pcmd && (*pcmd == ELS_CMD_FLOGI ||
*pcmd == ELS_CMD_SCR ||
+ *pcmd == ELS_CMD_RSCN_XMT ||
*pcmd == ELS_CMD_FDISC ||
*pcmd == ELS_CMD_LOGO ||
*pcmd == ELS_CMD_PLOGI)) {
--
2.13.7
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v2 5/7] lpfc: add nvmet discovery_event op support
2019-05-14 21:58 [PATCH v2 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
` (3 preceding siblings ...)
2019-05-14 21:58 ` [PATCH v2 4/7] lpfc: Add support to generate RSCN events for nport James Smart
@ 2019-05-14 21:58 ` James Smart
2019-05-14 21:58 ` [PATCH v2 6/7] lpfc: Add support for translating an RSCN rcv into a discovery rescan James Smart
` (2 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: James Smart @ 2019-05-14 21:58 UTC (permalink / raw)
This patch adds support for the nvmet discovery op. When the callback
routine is called, the driver will call the routine to generate an RSCN
to the port on the other end of the link.
Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
Signed-off-by: James Smart <jsmart2021 at gmail.com>
Reviewed-by: Hannes Reinecke <hare at suse.com>
---
drivers/scsi/lpfc/lpfc_nvmet.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 361e2b103648..1eb02a0b8db6 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -1141,6 +1141,22 @@ lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport,
spin_unlock_irqrestore(&ctxp->ctxlock, iflag);
}
+static void
+lpfc_nvmet_discovery_event(struct nvmet_fc_target_port *tgtport)
+{
+ struct lpfc_nvmet_tgtport *tgtp;
+ struct lpfc_hba *phba;
+ uint32_t rc;
+
+ tgtp = tgtport->private;
+ phba = tgtp->phba;
+
+ rc = lpfc_issue_els_rscn(phba->pport, 0);
+ lpfc_printf_log(phba, KERN_ERR, LOG_NVME,
+ "6420 NVMET subsystem change: Notification %s\n",
+ (rc) ? "Failed" : "Sent");
+}
+
static struct nvmet_fc_target_template lpfc_tgttemplate = {
.targetport_delete = lpfc_nvmet_targetport_delete,
.xmt_ls_rsp = lpfc_nvmet_xmt_ls_rsp,
@@ -1148,6 +1164,7 @@ static struct nvmet_fc_target_template lpfc_tgttemplate = {
.fcp_abort = lpfc_nvmet_xmt_fcp_abort,
.fcp_req_release = lpfc_nvmet_xmt_fcp_release,
.defer_rcv = lpfc_nvmet_defer_rcv,
+ .discovery_event = lpfc_nvmet_discovery_event,
.max_hw_queues = 1,
.max_sgl_segments = LPFC_NVMET_DEFAULT_SEGS,
--
2.13.7
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v2 6/7] lpfc: Add support for translating an RSCN rcv into a discovery rescan
2019-05-14 21:58 [PATCH v2 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
` (4 preceding siblings ...)
2019-05-14 21:58 ` [PATCH v2 5/7] lpfc: add nvmet discovery_event op support James Smart
@ 2019-05-14 21:58 ` James Smart
2019-05-14 21:58 ` [PATCH v2 7/7] lpfc: Add sysfs interface to post NVME RSCN James Smart
2019-05-29 23:12 ` [PATCH v2 0/7] nvmet/nvmet_fc: add events for discovery controller rescan Arun Easi
7 siblings, 0 replies; 15+ messages in thread
From: James Smart @ 2019-05-14 21:58 UTC (permalink / raw)
This patch updates RSCN receive processing to check for the remote
port being an NVME port, and if so, invoke the nvme_fc callback to
rescan the remote port. The rescan will generate a discovery udev
event.
Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
Signed-off-by: James Smart <jsmart2021 at gmail.com>
Reviewed-by: Hannes Reinecke <hare at suse.com>
---
v2: correct rport role to check for nvme discovery not just nvme target
---
drivers/scsi/lpfc/lpfc_crtn.h | 2 ++
drivers/scsi/lpfc/lpfc_els.c | 5 +++++
drivers/scsi/lpfc/lpfc_nvme.c | 44 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+)
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 4b8eb9107b85..866374801140 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -557,6 +557,8 @@ void lpfc_ras_stop_fwlog(struct lpfc_hba *phba);
int lpfc_check_fwlog_support(struct lpfc_hba *phba);
/* NVME interfaces. */
+void lpfc_nvme_rescan_port(struct lpfc_vport *vport,
+ struct lpfc_nodelist *ndlp);
void lpfc_nvme_unregister_port(struct lpfc_vport *vport,
struct lpfc_nodelist *ndlp);
int lpfc_nvme_register_port(struct lpfc_vport *vport,
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index c9a40e05edcc..c8b305c1aafb 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -6329,6 +6329,8 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
continue;
}
+ if (ndlp->nlp_fc4_type & NLP_FC4_NVME)
+ lpfc_nvme_rescan_port(vport, ndlp);
lpfc_disc_state_machine(vport, ndlp, NULL,
NLP_EVT_DEVICE_RECOVERY);
@@ -6440,6 +6442,9 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
"2024 pt2pt RSCN %08x Data: x%x x%x\n",
*lp, vport->fc_flag, payload_len);
lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
+
+ if (ndlp->nlp_fc4_type & NLP_FC4_NVME)
+ lpfc_nvme_rescan_port(vport, ndlp);
return 0;
}
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 1aa00d2c3f74..e6c945e29557 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -2399,6 +2399,50 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
#endif
}
+/**
+ * lpfc_nvme_rescan_port - Check to see if we should rescan this remoteport
+ *
+ * If the ndlp represents an NVME Target, that we are logged into,
+ * ping the NVME FC Transport layer to initiate a device rescan
+ * on this remote NPort.
+ */
+void
+lpfc_nvme_rescan_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
+{
+#if (IS_ENABLED(CONFIG_NVME_FC))
+ struct lpfc_nvme_rport *rport;
+ struct nvme_fc_remote_port *remoteport;
+
+ rport = ndlp->nrport;
+
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
+ "6170 Rescan NPort DID x%06x type x%x "
+ "state x%x rport %p\n",
+ ndlp->nlp_DID, ndlp->nlp_type, ndlp->nlp_state, rport);
+ if (!rport)
+ goto input_err;
+ remoteport = rport->remoteport;
+ if (!remoteport)
+ goto input_err;
+
+ /* Only rescan if we are an NVME target in the MAPPED state */
+ if (remoteport->port_role & FC_PORT_ROLE_NVME_DISCOVERY &&
+ ndlp->nlp_state == NLP_STE_MAPPED_NODE) {
+ nvme_fc_rescan_remoteport(remoteport);
+
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC,
+ "6172 NVME rescanned DID x%06x "
+ "port_state x%x\n",
+ ndlp->nlp_DID, remoteport->port_state);
+ }
+ return;
+input_err:
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC,
+ "6169 State error: lport %p, rport%p FCID x%06x\n",
+ vport->localport, ndlp->rport, ndlp->nlp_DID);
+#endif
+}
+
/* lpfc_nvme_unregister_port - unbind the DID and port_role from this rport.
*
* There is no notion of Devloss or rport recovery from the current
--
2.13.7
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v2 7/7] lpfc: Add sysfs interface to post NVME RSCN
2019-05-14 21:58 [PATCH v2 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
` (5 preceding siblings ...)
2019-05-14 21:58 ` [PATCH v2 6/7] lpfc: Add support for translating an RSCN rcv into a discovery rescan James Smart
@ 2019-05-14 21:58 ` James Smart
2019-05-29 23:12 ` [PATCH v2 0/7] nvmet/nvmet_fc: add events for discovery controller rescan Arun Easi
7 siblings, 0 replies; 15+ messages in thread
From: James Smart @ 2019-05-14 21:58 UTC (permalink / raw)
To support scenarios which aren't bound to nvmetcli add port scenarios,
which is currently where the nvmet_fc transport invokes the discovery
event callbacks, a syfs attribute is added to lpfc which can be written
to cause an RSCN to be generated for the nport.
Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
Signed-off-by: James Smart <jsmart2021 at gmail.com>
Reviewed-by: Hannes Reinecke <hare at suse.com>
---
drivers/scsi/lpfc/lpfc.h | 1 +
drivers/scsi/lpfc/lpfc_attr.c | 60 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 9246e0212a86..5ef0efb830d2 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -820,6 +820,7 @@ struct lpfc_hba {
uint32_t cfg_use_msi;
uint32_t cfg_auto_imax;
uint32_t cfg_fcp_imax;
+ uint32_t cfg_force_rscn;
uint32_t cfg_cq_poll_threshold;
uint32_t cfg_cq_max_proc_limit;
uint32_t cfg_fcp_cpu_map;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index ce3e541434dc..8b09e82ddfcf 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -4912,6 +4912,64 @@ static DEVICE_ATTR(lpfc_req_fw_upgrade, S_IRUGO | S_IWUSR,
lpfc_request_firmware_upgrade_store);
/**
+ * lpfc_force_rscn_store
+ *
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: unused string
+ * @count: unused variable.
+ *
+ * Description:
+ * Force the switch to send a RSCN to all other NPorts in our zone
+ * If we are direct connect pt2pt, build the RSCN command ourself
+ * and send to the other NPort. Not supported for private loop.
+ *
+ * Returns:
+ * 0 - on success
+ * -EIO - if command is not sent
+ **/
+static ssize_t
+lpfc_force_rscn_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct Scsi_Host *shost = class_to_shost(dev);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
+ int i;
+
+ i = lpfc_issue_els_rscn(vport, 0);
+ if (i)
+ return -EIO;
+ return strlen(buf);
+}
+
+/*
+ * lpfc_force_rscn: Force an RSCN to be sent to all remote NPorts
+ * connected to the HBA.
+ *
+ * Value range is any ascii value
+ */
+static int lpfc_force_rscn;
+module_param(lpfc_force_rscn, int, 0644);
+MODULE_PARM_DESC(lpfc_force_rscn,
+ "Force an RSCN to be sent to all remote NPorts");
+lpfc_param_show(force_rscn)
+
+/**
+ * lpfc_force_rscn_init - Force an RSCN to be sent to all remote NPorts
+ * @phba: lpfc_hba pointer.
+ * @val: unused value.
+ *
+ * Returns:
+ * zero if val saved.
+ **/
+static int
+lpfc_force_rscn_init(struct lpfc_hba *phba, int val)
+{
+ return 0;
+}
+static DEVICE_ATTR_RW(lpfc_force_rscn);
+
+/**
* lpfc_fcp_imax_store
*
* @dev: class device that is converted into a Scsi_host.
@@ -5911,6 +5969,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_nvme_oas,
&dev_attr_lpfc_nvme_embed_cmd,
&dev_attr_lpfc_fcp_imax,
+ &dev_attr_lpfc_force_rscn,
&dev_attr_lpfc_cq_poll_threshold,
&dev_attr_lpfc_cq_max_proc_limit,
&dev_attr_lpfc_fcp_cpu_map,
@@ -6958,6 +7017,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
+ lpfc_force_rscn_init(phba, lpfc_force_rscn);
lpfc_cq_poll_threshold_init(phba, lpfc_cq_poll_threshold);
lpfc_cq_max_proc_limit_init(phba, lpfc_cq_max_proc_limit);
lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map);
--
2.13.7
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v2 0/7] nvmet/nvmet_fc: add events for discovery controller rescan
2019-05-14 21:58 [PATCH v2 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
` (6 preceding siblings ...)
2019-05-14 21:58 ` [PATCH v2 7/7] lpfc: Add sysfs interface to post NVME RSCN James Smart
@ 2019-05-29 23:12 ` Arun Easi
2019-05-30 18:04 ` Sagi Grimberg
7 siblings, 1 reply; 15+ messages in thread
From: Arun Easi @ 2019-05-29 23:12 UTC (permalink / raw)
Apologies for the delay, wanted to test out some of these changes, but
it looks it would be a bit longer.
Anyway, the series look good to me.
-- arun
On Tue, 14 May 2019, 2:58pm, James Smart wrote:
> A transport may have a transport-specific mechanism that can signal
> when discovery controller content has changed and request a host
> to rescan to the discovery controller.
>
> FC is such a transport. RSCNs may be generated by the subsystem's FC
> port and sent to the initiator or fabric controller. If a fabric, the
> fabric controller will broadcast the RSCN to registered hosts. A host,
> upon receiving the RSCN, would validate connectivity then initiate a
> discovery controller rescan.
>
> These patches:
> - Modify the nvmet core layer to call a transport callback whenever
> a port discovery change occurs. To facilitate the callback and
> avoid new routines between core. and discovery.c the port structure
> now has a copy of the transport ops structure.
> - Modify the nvmet-fc transport to support the nvmet callback, and add
> its own internal lldd api to request the lldd to generate an RSCN.
> - Update nvme-fcloop test harness to support the lldd api and invoke
> the rescan on the host.
> - Modify the lpfc driver to support the new interfaces:
> - Adds a new routine to transmit an RSCN to the other port (pt2pt)
> or fabric controller. Add recognition for receipt of an RSCN.
> - Add support for the nvmet lldd api for discovery event, which
> invokes the RSCN transmit.
> - Ties into the RSCN receipt and requests the nvme_fc transport
> to rescan the remote port (discovery event will be posted).
> - Adds a sysfs routine to enable manual generation of an RSCN.
>
> v2:
> Revise lpfc patch 6 to check for port role nvme discovery not just
> nvme target
>
>
> James Smart (7):
> nvmet: add transport discovery change op
> nvmet_fc: add transport discovery change event callback support
> nvme-fcloop: Add support for nvmet discovery_event op
> lpfc: Add support to generate RSCN events for nport
> lpfc: add nvmet discovery_event op support
> lpfc: Add support for translating an RSCN rcv into a discovery rescan
> lpfc: Add sysfs interface to post NVME RSCN
>
> drivers/nvme/target/core.c | 2 +
> drivers/nvme/target/discovery.c | 4 ++
> drivers/nvme/target/fc.c | 11 ++++
> drivers/nvme/target/fcloop.c | 37 ++++++++++++
> drivers/nvme/target/nvmet.h | 2 +
> drivers/scsi/lpfc/lpfc.h | 2 +
> drivers/scsi/lpfc/lpfc_attr.c | 60 ++++++++++++++++++
> drivers/scsi/lpfc/lpfc_crtn.h | 4 ++
> drivers/scsi/lpfc/lpfc_els.c | 127 +++++++++++++++++++++++++++++++++++++++
> drivers/scsi/lpfc/lpfc_hbadisc.c | 35 +++++++++++
> drivers/scsi/lpfc/lpfc_hw.h | 2 +
> drivers/scsi/lpfc/lpfc_nvme.c | 44 ++++++++++++++
> drivers/scsi/lpfc/lpfc_nvmet.c | 17 ++++++
> drivers/scsi/lpfc/lpfc_sli.c | 1 +
> include/linux/nvme-fc-driver.h | 6 ++
> 15 files changed, 354 insertions(+)
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread