mirror of
https://github.com/torvalds/linux.git
synced 2026-09-28 03:52:02 +02:00
scsi: ibmvfc: implement NVMe/FC stubs for local/remote port registration
Implement the initial NVMe/FC local-port and remote-port registration functions that notify the NVMe-FC midlayr of port discovery and loss. Register the local port with the NVMe-FC transport, register discovered remote ports against that local port, and add matching unregister paths that wait for the NVMe-FC core to complete asynchronous deletion before dropping driver references. Also store driver-private host and target pointers in the registered NVMe-FC port objects. Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com> Link: https://patch.msgid.link/20260723000149.969416-24-tyreld@linux.ibm.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
0a3ab63e43
commit
13b7fdf327
|
|
@ -14,10 +14,18 @@
|
|||
|
||||
static void ibmvfc_nvme_localport_delete(struct nvme_fc_local_port *lport)
|
||||
{
|
||||
struct ibmvfc_host *vhost = lport->private;
|
||||
|
||||
vhost->nvme_local_port = NULL;
|
||||
complete(&vhost->nvme_delete_done);
|
||||
}
|
||||
|
||||
static void ibmvfc_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
|
||||
{
|
||||
struct ibmvfc_target *tgt = rport->private;
|
||||
|
||||
tgt->nvme_remote_port = NULL;
|
||||
complete(&tgt->nvme_delete_done);
|
||||
}
|
||||
|
||||
static int ibmvfc_nvme_ls_req(struct nvme_fc_local_port *lport,
|
||||
|
|
@ -70,28 +78,96 @@ static struct nvme_fc_port_template ibmvfc_nvme_fc_transport = {
|
|||
|
||||
int ibmvfc_nvme_register_remoteport(struct ibmvfc_target *tgt)
|
||||
{
|
||||
struct ibmvfc_host *vhost = tgt->vhost;
|
||||
struct nvme_fc_port_info pinfo;
|
||||
int rc;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_NVME_FC))
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
if (!vhost->nvme_local_port) {
|
||||
dev_err(vhost->dev, "Attempt to register NVMe fc remoteport without valid localport\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(&pinfo, 0, sizeof(struct nvme_fc_port_info));
|
||||
pinfo.node_name = tgt->ids.node_name;
|
||||
pinfo.port_name = tgt->ids.port_name;
|
||||
pinfo.port_id = tgt->ids.port_id;
|
||||
pinfo.port_role = FC_PORT_ROLE_NVME_TARGET;
|
||||
|
||||
rc = nvme_fc_register_remoteport(vhost->nvme_local_port, &pinfo,
|
||||
&tgt->nvme_remote_port);
|
||||
|
||||
if (!rc) {
|
||||
ibmvfc_log(vhost, 2, "register_remoteport: traddr=nn-0x%llx:pn-0x%llx PortID:%x\n",
|
||||
pinfo.node_name, pinfo.port_name, pinfo.port_id);
|
||||
tgt->nvme_remote_port->private = tgt;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ibmvfc_nvme_unregister_remoteport(struct ibmvfc_target *tgt)
|
||||
{
|
||||
struct ibmvfc_host *vhost = tgt->vhost;
|
||||
struct nvme_fc_remote_port *rport = tgt->nvme_remote_port;
|
||||
int rc;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_NVME_FC))
|
||||
return;
|
||||
|
||||
if (!tgt->nvme_remote_port)
|
||||
return;
|
||||
|
||||
ibmvfc_log(vhost, 2, "unregister_remoteport: traddr=nn-0x%llx:pn-0x%llx PortID:%x\n",
|
||||
rport->node_name, rport->port_name, rport->port_id);
|
||||
init_completion(&tgt->nvme_delete_done);
|
||||
rc = nvme_fc_unregister_remoteport(tgt->nvme_remote_port);
|
||||
|
||||
if (!rc) {
|
||||
wait_for_completion(&tgt->nvme_delete_done);
|
||||
}
|
||||
}
|
||||
|
||||
int ibmvfc_nvme_register(struct ibmvfc_host *vhost)
|
||||
{
|
||||
struct nvme_fc_port_info pinfo;
|
||||
int rc;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_NVME_FC))
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
pinfo.node_name = fc_host_node_name(vhost->host);
|
||||
pinfo.port_name = fc_host_port_name(vhost->host);
|
||||
pinfo.port_id = fc_host_port_id(vhost->host);
|
||||
pinfo.port_role = FC_PORT_ROLE_NVME_INITIATOR;
|
||||
pinfo.dev_loss_tmo = 0;
|
||||
|
||||
rc = nvme_fc_register_localport(&pinfo, &ibmvfc_nvme_fc_transport,
|
||||
vhost->dev, &vhost->nvme_local_port);
|
||||
|
||||
if (!rc) {
|
||||
ibmvfc_log(vhost, 2, "register_localport: host-traddr=nn-0x%llx:pn-0x%llx on portID:%x\n",
|
||||
pinfo.node_name, pinfo.port_name, pinfo.port_id);
|
||||
vhost->nvme_local_port->private = vhost;
|
||||
} else
|
||||
dev_err(vhost->dev, "Failed to register NVMe fc localport (%d)\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ibmvfc_nvme_unregister(struct ibmvfc_host *vhost)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_NVME_FC))
|
||||
return;
|
||||
|
||||
if (vhost->nvme_local_port) {
|
||||
init_completion(&vhost->nvme_delete_done);
|
||||
rc = nvme_fc_unregister_localport(vhost->nvme_local_port);
|
||||
if (!rc)
|
||||
wait_for_completion(&vhost->nvme_delete_done);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
#ifndef _IBMVFC_NVME_H
|
||||
#define _IBMVFC_NVME_H
|
||||
|
||||
#include <uapi/scsi/fc/fc_fs.h>
|
||||
#include <uapi/scsi/fc/fc_els.h>
|
||||
#include <scsi/fc/fc_fs.h>
|
||||
#include <scsi/fc/fc_els.h>
|
||||
#include <linux/nvme-fc-driver.h>
|
||||
|
||||
#include "ibmvfc.h"
|
||||
|
|
|
|||
|
|
@ -839,6 +839,8 @@ struct ibmvfc_target {
|
|||
void (*job_step) (struct ibmvfc_target *);
|
||||
struct timer_list timer;
|
||||
struct kref kref;
|
||||
struct completion nvme_delete_done;
|
||||
struct nvme_fc_remote_port *nvme_remote_port;
|
||||
};
|
||||
|
||||
/* a unit of work for the hosting partition */
|
||||
|
|
@ -1015,6 +1017,8 @@ struct ibmvfc_host {
|
|||
struct work_struct rport_add_work_q;
|
||||
wait_queue_head_t init_wait_q;
|
||||
wait_queue_head_t work_wait_q;
|
||||
struct nvme_fc_local_port *nvme_local_port;
|
||||
struct completion nvme_delete_done;
|
||||
};
|
||||
|
||||
static inline struct ibmvfc_host *ibmvfc_channels_to_vhost(struct ibmvfc_channels *channels)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user