#define pr_fmt(fmt) …
#include <linux/module.h>
#include <linux/parser.h>
#include <uapi/scsi/fc/fc_fs.h>
#include "../host/nvme.h"
#include "../target/nvmet.h"
#include <linux/nvme-fc-driver.h>
#include <linux/nvme-fc.h>
enum { … };
struct fcloop_ctrl_options { … };
static const match_table_t opt_tokens = …;
static int fcloop_verify_addr(substring_t *s)
{ … }
static int
fcloop_parse_options(struct fcloop_ctrl_options *opts,
const char *buf)
{ … }
static int
fcloop_parse_nm_options(struct device *dev, u64 *nname, u64 *pname,
const char *buf)
{ … }
#define LPORT_OPTS …
#define RPORT_OPTS …
#define TGTPORT_OPTS …
static DEFINE_SPINLOCK(fcloop_lock);
static LIST_HEAD(fcloop_lports);
static LIST_HEAD(fcloop_nports);
struct fcloop_lport { … };
struct fcloop_lport_priv { … };
struct fcloop_rport { … };
struct fcloop_tport { … };
struct fcloop_nport { … };
struct fcloop_lsreq { … };
struct fcloop_rscn { … };
enum { … };
struct fcloop_fcpreq { … };
struct fcloop_ini_fcpreq { … };
static inline struct fcloop_lsreq *
ls_rsp_to_lsreq(struct nvmefc_ls_rsp *lsrsp)
{ … }
static inline struct fcloop_fcpreq *
tgt_fcp_req_to_fcpreq(struct nvmefc_tgt_fcp_req *tgt_fcpreq)
{ … }
static int
fcloop_create_queue(struct nvme_fc_local_port *localport,
unsigned int qidx, u16 qsize,
void **handle)
{ … }
static void
fcloop_delete_queue(struct nvme_fc_local_port *localport,
unsigned int idx, void *handle)
{ … }
static void
fcloop_rport_lsrqst_work(struct work_struct *work)
{ … }
static int
fcloop_h2t_ls_req(struct nvme_fc_local_port *localport,
struct nvme_fc_remote_port *remoteport,
struct nvmefc_ls_req *lsreq)
{ … }
static int
fcloop_h2t_xmt_ls_rsp(struct nvmet_fc_target_port *targetport,
struct nvmefc_ls_rsp *lsrsp)
{ … }
static void
fcloop_tport_lsrqst_work(struct work_struct *work)
{ … }
static int
fcloop_t2h_ls_req(struct nvmet_fc_target_port *targetport, void *hosthandle,
struct nvmefc_ls_req *lsreq)
{ … }
static int
fcloop_t2h_xmt_ls_rsp(struct nvme_fc_local_port *localport,
struct nvme_fc_remote_port *remoteport,
struct nvmefc_ls_rsp *lsrsp)
{ … }
static void
fcloop_t2h_host_release(void *hosthandle)
{ … }
static int
fcloop_t2h_host_traddr(void *hosthandle, u64 *wwnn, u64 *wwpn)
{ … }
static void
fcloop_tgt_rscn_work(struct work_struct *work)
{ … }
static void
fcloop_tgt_discovery_evt(struct nvmet_fc_target_port *tgtport)
{ … }
static void
fcloop_tfcp_req_free(struct kref *ref)
{ … }
static void
fcloop_tfcp_req_put(struct fcloop_fcpreq *tfcp_req)
{ … }
static int
fcloop_tfcp_req_get(struct fcloop_fcpreq *tfcp_req)
{ … }
static void
fcloop_call_host_done(struct nvmefc_fcp_req *fcpreq,
struct fcloop_fcpreq *tfcp_req, int status)
{ … }
static bool drop_fabric_opcode;
#define DROP_OPCODE_MASK …
static int drop_opcode = …;
static int drop_instance;
static int drop_amount;
static int drop_current_cnt;
static int check_for_drop(struct fcloop_fcpreq *tfcp_req)
{ … }
static void
fcloop_fcp_recv_work(struct work_struct *work)
{ … }
static void
fcloop_fcp_abort_recv_work(struct work_struct *work)
{ … }
static void
fcloop_tgt_fcprqst_done_work(struct work_struct *work)
{ … }
static int
fcloop_fcp_req(struct nvme_fc_local_port *localport,
struct nvme_fc_remote_port *remoteport,
void *hw_queue_handle,
struct nvmefc_fcp_req *fcpreq)
{ … }
static void
fcloop_fcp_copy_data(u8 op, struct scatterlist *data_sg,
struct scatterlist *io_sg, u32 offset, u32 length)
{ … }
static int
fcloop_fcp_op(struct nvmet_fc_target_port *tgtport,
struct nvmefc_tgt_fcp_req *tgt_fcpreq)
{ … }
static void
fcloop_tgt_fcp_abort(struct nvmet_fc_target_port *tgtport,
struct nvmefc_tgt_fcp_req *tgt_fcpreq)
{ … }
static void
fcloop_fcp_req_release(struct nvmet_fc_target_port *tgtport,
struct nvmefc_tgt_fcp_req *tgt_fcpreq)
{ … }
static void
fcloop_h2t_ls_abort(struct nvme_fc_local_port *localport,
struct nvme_fc_remote_port *remoteport,
struct nvmefc_ls_req *lsreq)
{ … }
static void
fcloop_t2h_ls_abort(struct nvmet_fc_target_port *targetport,
void *hosthandle, struct nvmefc_ls_req *lsreq)
{ … }
static void
fcloop_fcp_abort(struct nvme_fc_local_port *localport,
struct nvme_fc_remote_port *remoteport,
void *hw_queue_handle,
struct nvmefc_fcp_req *fcpreq)
{ … }
static void
fcloop_nport_free(struct kref *ref)
{ … }
static void
fcloop_nport_put(struct fcloop_nport *nport)
{ … }
static int
fcloop_nport_get(struct fcloop_nport *nport)
{ … }
static void
fcloop_localport_delete(struct nvme_fc_local_port *localport)
{ … }
static void
fcloop_remoteport_delete(struct nvme_fc_remote_port *remoteport)
{ … }
static void
fcloop_targetport_delete(struct nvmet_fc_target_port *targetport)
{ … }
#define FCLOOP_HW_QUEUES …
#define FCLOOP_SGL_SEGS …
#define FCLOOP_DMABOUND_4G …
static struct nvme_fc_port_template fctemplate = …;
static struct nvmet_fc_target_template tgttemplate = …;
static ssize_t
fcloop_create_local_port(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{ … }
static void
__unlink_local_port(struct fcloop_lport *lport)
{ … }
static int
__wait_localport_unreg(struct fcloop_lport *lport)
{ … }
static ssize_t
fcloop_delete_local_port(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{ … }
static struct fcloop_nport *
fcloop_alloc_nport(const char *buf, size_t count, bool remoteport)
{ … }
static ssize_t
fcloop_create_remote_port(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{ … }
static struct fcloop_rport *
__unlink_remote_port(struct fcloop_nport *nport)
{ … }
static int
__remoteport_unreg(struct fcloop_nport *nport, struct fcloop_rport *rport)
{ … }
static ssize_t
fcloop_delete_remote_port(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{ … }
static ssize_t
fcloop_create_target_port(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{ … }
static struct fcloop_tport *
__unlink_target_port(struct fcloop_nport *nport)
{ … }
static int
__targetport_unreg(struct fcloop_nport *nport, struct fcloop_tport *tport)
{ … }
static ssize_t
fcloop_delete_target_port(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{ … }
static ssize_t
fcloop_set_cmd_drop(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{ … }
static DEVICE_ATTR(add_local_port, 0200, NULL, fcloop_create_local_port);
static DEVICE_ATTR(del_local_port, 0200, NULL, fcloop_delete_local_port);
static DEVICE_ATTR(add_remote_port, 0200, NULL, fcloop_create_remote_port);
static DEVICE_ATTR(del_remote_port, 0200, NULL, fcloop_delete_remote_port);
static DEVICE_ATTR(add_target_port, 0200, NULL, fcloop_create_target_port);
static DEVICE_ATTR(del_target_port, 0200, NULL, fcloop_delete_target_port);
static DEVICE_ATTR(set_cmd_drop, 0200, NULL, fcloop_set_cmd_drop);
static struct attribute *fcloop_dev_attrs[] = …;
static const struct attribute_group fclopp_dev_attrs_group = …;
static const struct attribute_group *fcloop_dev_attr_groups[] = …;
static const struct class fcloop_class = …;
static struct device *fcloop_device;
static int __init fcloop_init(void)
{ … }
static void __exit fcloop_exit(void)
{ … }
module_init(…) …;
module_exit(fcloop_exit);
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;