linux/drivers/target/loopback/tcm_loop.c

/*******************************************************************************
 *
 * This file contains the Linux/SCSI LLD virtual SCSI initiator driver
 * for emulated SAS initiator ports
 *
 * © Copyright 2011-2013 Datera, Inc.
 *
 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
 *
 * Author: Nicholas A. Bellinger <[email protected]>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 ****************************************************************************/

#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);

/*
 * Called from struct target_core_fabric_ops->check_stop_free()
 */
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 =;
/*
 * Used with root_device_register() in tcm_loop_alloc_core_bus() below
 */
static struct device *tcm_loop_primary;

static void tcm_loop_target_queue_cmd(struct tcm_loop_cmd *tl_cmd)
{}

/*
 * ->queuecommand can be and usually is called from interrupt context, so
 * defer the actual submission to a workqueue.
 */
static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc)
{}

/*
 * Called from SCSI EH process context to issue a LUN_RESET TMR
 * to struct scsi_device
 */
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)
{}

/*
 * Called from SCSI EH process context to issue a LUN_RESET TMR
 * to struct scsi_device
 */
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)
{}

/*
 * Called from tcm_loop_make_scsi_hba() in tcm_loop_configfs.c
 */
static int tcm_loop_setup_hba_bus(struct tcm_loop_hba *tl_hba, int tcm_loop_host_id)
{}

/*
 * Called from tcm_loop_fabric_init() in tcl_loop_fabric.c to load the emulated
 * tcm_loop SCSI bus.
 */
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)
{}

/*
 * Returning (1) here allows for target_core_mod struct se_node_acl to be generated
 * based upon the incoming fabric dependent SCSI Initiator Port
 */
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)
{}

/* Start items for tcm_loop_port_cit */

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)
{}

/* End items for tcm_loop_port_cit */

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[] =;

/* Start items for tcm_loop_nexus_cit */

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)
{}

/* End items for tcm_loop_nexus_cit */

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[] =;

/* Start items for tcm_loop_naa_cit */

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)
{}

/* End items for tcm_loop_naa_cit */

/* Start items for tcm_loop_cit */

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)
{}

/* Start items for tcm_loop_cit */
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[] =;

/* End items for tcm_loop_cit */

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);