#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/configfs.h>
#include <scsi/scsi.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_cmnd.h>
#include <target/target_core_base.h>
#include <target/target_core_fabric.h>
#include "tcm_loop.h"
#define to_tcm_loop_hba(hba) …
static struct kmem_cache *tcm_loop_cmd_cache;
static int tcm_loop_hba_no_cnt;
static int tcm_loop_queue_status(struct se_cmd *se_cmd);
static unsigned int tcm_loop_nr_hw_queues = …;
module_param_named(nr_hw_queues, tcm_loop_nr_hw_queues, uint, 0644);
static unsigned int tcm_loop_can_queue = …;
module_param_named(can_queue, tcm_loop_can_queue, uint, 0644);
static unsigned int tcm_loop_cmd_per_lun = …;
module_param_named(cmd_per_lun, tcm_loop_cmd_per_lun, uint, 0644);
static int tcm_loop_check_stop_free(struct se_cmd *se_cmd)
{ … }
static void tcm_loop_release_cmd(struct se_cmd *se_cmd)
{ … }
static int tcm_loop_show_info(struct seq_file *m, struct Scsi_Host *host)
{ … }
static int tcm_loop_driver_probe(struct device *);
static void tcm_loop_driver_remove(struct device *);
static const struct bus_type tcm_loop_lld_bus = …;
static struct device_driver tcm_loop_driverfs = …;
static struct device *tcm_loop_primary;
static void tcm_loop_target_queue_cmd(struct tcm_loop_cmd *tl_cmd)
{ … }
static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc)
{ … }
static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
u64 lun, int task, enum tcm_tmreq_table tmr)
{ … }
static int tcm_loop_abort_task(struct scsi_cmnd *sc)
{ … }
static int tcm_loop_device_reset(struct scsi_cmnd *sc)
{ … }
static int tcm_loop_target_reset(struct scsi_cmnd *sc)
{ … }
static const struct scsi_host_template tcm_loop_driver_template = …;
static int tcm_loop_driver_probe(struct device *dev)
{ … }
static void tcm_loop_driver_remove(struct device *dev)
{ … }
static void tcm_loop_release_adapter(struct device *dev)
{ … }
static int tcm_loop_setup_hba_bus(struct tcm_loop_hba *tl_hba, int tcm_loop_host_id)
{ … }
static int tcm_loop_alloc_core_bus(void)
{ … }
static void tcm_loop_release_core_bus(void)
{ … }
static inline struct tcm_loop_tpg *tl_tpg(struct se_portal_group *se_tpg)
{ … }
static char *tcm_loop_get_endpoint_wwn(struct se_portal_group *se_tpg)
{ … }
static u16 tcm_loop_get_tag(struct se_portal_group *se_tpg)
{ … }
static int tcm_loop_check_demo_mode(struct se_portal_group *se_tpg)
{ … }
static int tcm_loop_check_prot_fabric_only(struct se_portal_group *se_tpg)
{ … }
static u32 tcm_loop_sess_get_index(struct se_session *se_sess)
{ … }
static int tcm_loop_get_cmd_state(struct se_cmd *se_cmd)
{ … }
static int tcm_loop_write_pending(struct se_cmd *se_cmd)
{ … }
static int tcm_loop_queue_data_or_status(const char *func,
struct se_cmd *se_cmd, u8 scsi_status)
{ … }
static int tcm_loop_queue_data_in(struct se_cmd *se_cmd)
{ … }
static int tcm_loop_queue_status(struct se_cmd *se_cmd)
{ … }
static void tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd)
{ … }
static void tcm_loop_aborted_task(struct se_cmd *se_cmd)
{ … }
static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba)
{ … }
static int tcm_loop_port_link(
struct se_portal_group *se_tpg,
struct se_lun *lun)
{ … }
static void tcm_loop_port_unlink(
struct se_portal_group *se_tpg,
struct se_lun *se_lun)
{ … }
static ssize_t tcm_loop_tpg_attrib_fabric_prot_type_show(
struct config_item *item, char *page)
{ … }
static ssize_t tcm_loop_tpg_attrib_fabric_prot_type_store(
struct config_item *item, const char *page, size_t count)
{ … }
CONFIGFS_ATTR(…);
static struct configfs_attribute *tcm_loop_tpg_attrib_attrs[] = …;
static int tcm_loop_alloc_sess_cb(struct se_portal_group *se_tpg,
struct se_session *se_sess, void *p)
{ … }
static int tcm_loop_make_nexus(
struct tcm_loop_tpg *tl_tpg,
const char *name)
{ … }
static int tcm_loop_drop_nexus(
struct tcm_loop_tpg *tpg)
{ … }
static ssize_t tcm_loop_tpg_nexus_show(struct config_item *item, char *page)
{ … }
static ssize_t tcm_loop_tpg_nexus_store(struct config_item *item,
const char *page, size_t count)
{ … }
static ssize_t tcm_loop_tpg_transport_status_show(struct config_item *item,
char *page)
{ … }
static ssize_t tcm_loop_tpg_transport_status_store(struct config_item *item,
const char *page, size_t count)
{ … }
static ssize_t tcm_loop_tpg_address_show(struct config_item *item,
char *page)
{ … }
CONFIGFS_ATTR(…);
CONFIGFS_ATTR(…);
CONFIGFS_ATTR_RO(…);
static struct configfs_attribute *tcm_loop_tpg_attrs[] = …;
static struct se_portal_group *tcm_loop_make_naa_tpg(struct se_wwn *wwn,
const char *name)
{ … }
static void tcm_loop_drop_naa_tpg(
struct se_portal_group *se_tpg)
{ … }
static struct se_wwn *tcm_loop_make_scsi_hba(
struct target_fabric_configfs *tf,
struct config_group *group,
const char *name)
{ … }
static void tcm_loop_drop_scsi_hba(
struct se_wwn *wwn)
{ … }
static ssize_t tcm_loop_wwn_version_show(struct config_item *item, char *page)
{ … }
CONFIGFS_ATTR_RO(…);
static struct configfs_attribute *tcm_loop_wwn_attrs[] = …;
static const struct target_core_fabric_ops loop_ops = …;
static int __init tcm_loop_fabric_init(void)
{ … }
static void __exit tcm_loop_fabric_exit(void)
{ … }
MODULE_DESCRIPTION(…) …;
MODULE_AUTHOR(…) …;
MODULE_LICENSE(…) …;
module_init(…) …;
module_exit(tcm_loop_fabric_exit);