- Version descriptors added

- Multi-transport support added to scst_local
 - Sysfs attributes "version" and "trace_level" added to scst_local



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@2060 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2010-09-06 21:21:49 +00:00
parent 8536db4580
commit 961d59ff40
8 changed files with 466 additions and 46 deletions
+6
View File
@@ -3746,6 +3746,11 @@ static struct scst_trace_log iscsi_local_trace_tbl[] = {
#define ISCSI_TRACE_TBL_HELP ", d_write, conn, conn_dbg, iov, pdu, net_page"
#endif
static uint16_t iscsi_get_scsi_transport_version(struct scst_cmd *scst_cmd)
{
return 0x0960; /* iSCSI */
}
struct scst_tgt_template iscsi_template = {
.name = "iscsi",
.sg_tablesize = 0xFFFF /* no limit */,
@@ -3785,6 +3790,7 @@ struct scst_tgt_template iscsi_template = {
.task_mgmt_fn_done = iscsi_task_mgmt_fn_done,
.report_aen = iscsi_report_aen,
.get_initiator_port_transport_id = iscsi_get_initiator_port_transport_id,
.get_scsi_transport_version = iscsi_get_scsi_transport_version,
};
static __init int iscsi_run_threads(int count, char *name, int (*fn)(void *))
+7 -1
View File
@@ -66,7 +66,7 @@ static void mvst_host_action(struct mvs_info *mvi,
enum mvst_tgt_host_action_t action, u8 phyid);
static int mvst_start_sas_target(struct mvs_info *mvi, u8 id);
static int mvst_restart_free_list(struct mvs_info *mvi, u8 slot_id);
static uint16_t mvst_get_scsi_transport_version(struct scst_cmd *scst_cmd);
struct kmem_cache *mvst_cmd_cachep;
struct mvst_msg_queue tgt_msg_queue;
@@ -89,12 +89,18 @@ struct scst_tgt_template tgt_template = {
.on_free_cmd = mvst_on_free_cmd,
.task_mgmt_fn_done = mvst_task_mgmt_fn_done,
.report_aen = mvst_report_event,
.get_scsi_transport_version = mvst_get_scsi_transport_version,
};
/*
* Functions
*/
static uint16_t mvst_get_scsi_transport_version(struct scst_cmd *scst_cmd)
{
return 0x0BE0; /* SAS */
}
static u64 mvst_get_be_sas_addr(u8 *sas_addr)
{
u64 lo = cpu_to_be32((u32)(*(u32 *)&sas_addr[0]));
+15
View File
@@ -96,6 +96,8 @@ static int q2t_cut_cmd_data_head(struct q2t_cmd *cmd, unsigned int offset);
static void q2t_clear_tgt_db(struct q2t_tgt *tgt, bool local_only);
static void q2t_on_hw_pending_cmd_timeout(struct scst_cmd *scst_cmd);
static int q2t_unreg_sess(struct q2t_sess *sess);
static uint16_t q2t_get_scsi_transport_version(struct scst_cmd *scst_cmd);
static uint16_t q2t_get_phys_transport_version(struct scst_cmd *scst_cmd);
#ifndef CONFIG_SCST_PROC
@@ -170,6 +172,8 @@ static struct scst_tgt_template tgt2x_template = {
.on_free_cmd = q2t_on_free_cmd,
.task_mgmt_fn_done = q2t_task_mgmt_fn_done,
.get_initiator_port_transport_id = q2t_get_initiator_port_transport_id,
.get_scsi_transport_version = q2t_get_scsi_transport_version,
.get_phys_transport_version = q2t_get_phys_transport_version,
.on_hw_pending_cmd_timeout = q2t_on_hw_pending_cmd_timeout,
.enable_target = q2t_enable_tgt,
.is_target_enabled = q2t_is_tgt_enabled,
@@ -5503,6 +5507,17 @@ static void q2t_proc_log_entry_clean(struct scst_tgt_template *templ)
#endif /* CONFIG_SCST_PROC */
static uint16_t q2t_get_scsi_transport_version(struct scst_cmd *scst_cmd)
{
/* FCP-2 (speculative, there's no info what FW supports) */
return 0x0900;
}
static uint16_t q2t_get_phys_transport_version(struct scst_cmd *scst_cmd)
{
return 0x0DA0; /* FC-FS */
}
static int __init q2t_init(void)
{
int res = 0;
+6
View File
@@ -1581,6 +1581,11 @@ out:
return (res);
}
static uint16_t isp_get_scsi_transport_version(struct scst_cmd *scst_cmd)
{
return 0x0900; /* FCP-2 */
}
static struct scst_tgt_template isp_tgt_template =
{
.sg_tablesize = SG_ALL, /* we set this value lately based on hardware */
@@ -1598,6 +1603,7 @@ static struct scst_tgt_template isp_tgt_template =
.rdy_to_xfer = isp_rdy_to_xfer,
.on_free_cmd = isp_on_free_cmd,
.task_mgmt_fn_done = isp_task_mgmt_fn_done,
.get_scsi_transport_version = isp_get_scsi_transport_version,
//.report_aen = isp_report_aen,
.get_initiator_port_transport_id = isp_get_initiator_port_transport_id,
+22
View File
@@ -884,6 +884,22 @@ struct scst_tgt_template {
*/
ssize_t (*mgmt_cmd) (char *cmd);
/*
* Should return physical transport version. Used in the corresponding
* INQUIRY version descriptor. See SPC for the list of available codes.
*
* OPTIONAL
*/
uint16_t (*get_phys_transport_version) (struct scst_cmd *cmd);
/*
* Should return SCSI transport version. Used in the corresponding
* INQUIRY version descriptor. See SPC for the list of available codes.
*
* OPTIONAL
*/
uint16_t (*get_scsi_transport_version) (struct scst_cmd *cmd);
/*
* Name of the template. Must be unique to identify
* the template. MUST HAVE
@@ -2747,6 +2763,12 @@ static inline void scst_cmd_set_ext_cdb(struct scst_cmd *cmd,
cmd->ext_cdb_len = ext_cdb_len;
}
/* Returns cmd's target */
static inline struct scst_tgt *scst_cmd_get_tgt(struct scst_cmd *cmd)
{
return cmd->tgt;
}
/* Returns cmd's session */
static inline struct scst_session *scst_cmd_get_session(struct scst_cmd *cmd)
{
+50 -1
View File
@@ -217,6 +217,7 @@ struct scst_vdisk_dev {
must be <= SCSI Model + 1 */
char *filename; /* File name, protected by
scst_mutex and suspended activities */
uint16_t command_set_version;
unsigned int t10_dev_id_set:1; /* true if t10_dev_id manually set */
char t10_dev_id[16+8+2]; /* T10 device ID */
char usn[MAX_USN_LEN];
@@ -1396,7 +1397,7 @@ static void vdisk_exec_inquiry(struct scst_cmd *cmd)
goto out_put;
}
} else {
int len;
int len, num;
if (cmd->cdb[2] != 0) {
TRACE_DBG("INQUIRY: Unsupported page %x", cmd->cdb[2]);
@@ -1433,6 +1434,46 @@ static void vdisk_exec_inquiry(struct scst_cmd *cmd)
* aligned.
*/
memcpy(&buf[32], SCST_FIO_REV, 4);
/** Version descriptors **/
buf[4] += 58 - 36;
num = 0;
/* SAM-3 T10/1561-D revision 14 */
buf[58 + num] = 0x0;
buf[58 + num + 1] = 0x76;
num += 2;
/* Physical transport */
if (cmd->tgtt->get_phys_transport_version != NULL) {
uint16_t v = cmd->tgtt->get_phys_transport_version(cmd);
if (v != 0) {
*((uint16_t *)&buf[58 + num]) = cpu_to_be16(v);
num += 2;
}
}
/* SCSI transport */
if (cmd->tgtt->get_scsi_transport_version != NULL) {
*((uint16_t *)&buf[58 + num]) =
cpu_to_be16(cmd->tgtt->get_scsi_transport_version(cmd));
num += 2;
}
/* SPC-3 T10/1416-D revision 23 */
buf[58 + num] = 0x3;
buf[58 + num + 1] = 0x12;
num += 2;
/* Device command set */
if (virt_dev->command_set_version != 0) {
*((uint16_t *)&buf[58 + num]) =
cpu_to_be16(virt_dev->command_set_version);
num += 2;
}
buf[4] += num;
resp_len = buf[4] + 5;
}
@@ -3216,6 +3257,8 @@ static int vdev_fileio_add_device(const char *device_name, char *params)
if (res != 0)
goto out;
virt_dev->command_set_version = 0x04C0; /* SBC-3 */
virt_dev->wt_flag = DEF_WRITE_THROUGH;
virt_dev->nv_cache = DEF_NV_CACHE;
virt_dev->o_direct_flag = DEF_O_DIRECT;
@@ -3277,6 +3320,8 @@ static int vdev_blockio_add_device(const char *device_name, char *params)
if (res != 0)
goto out;
virt_dev->command_set_version = 0x04C0; /* SBC-3 */
virt_dev->blockio = 1;
res = vdev_parse_add_dev_params(virt_dev, params, allowed_params);
@@ -3329,6 +3374,8 @@ static int vdev_nullio_add_device(const char *device_name, char *params)
if (res != 0)
goto out;
virt_dev->command_set_version = 0x04C0; /* SBC-3 */
virt_dev->nullio = 1;
res = vdev_parse_add_dev_params(virt_dev, params, allowed_params);
@@ -3486,6 +3533,8 @@ static ssize_t __vcdrom_add_device(const char *device_name, char *params)
if (res != 0)
goto out;
virt_dev->command_set_version = 0x02A0; /* MMC-3 */
virt_dev->rd_only = 1;
virt_dev->removable = 1;
virt_dev->cdrom_empty = 1;
+354 -44
View File
@@ -59,7 +59,7 @@
#ifdef CONFIG_SCST_DEBUG
#define SCST_LOCAL_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \
TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_DEBUG | \
TRACE_LINE | TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_DEBUG | \
TRACE_MINOR | TRACE_SPECIAL)
#else
# ifdef CONFIG_SCST_TRACING
@@ -130,6 +130,8 @@ static int num_aborts;
static int num_dev_resets;
static int num_target_resets;
static DEFINE_MUTEX(scst_local_mutex);
/*
* We put AEN items on a list on the scst_local_host_info structure so they
* can be processed via a work function. We do not actually need the LUN, since
@@ -155,6 +157,16 @@ struct scst_local_host_info {
struct work_struct local_work;
spinlock_t lock;
struct list_head work_list;
uint16_t scsi_transport_version, phys_transport_version;
uint8_t *transport_id;
int transport_id_len;
};
struct scst_local_sess_info {
struct scst_local_host_info *host;
int number;
uint8_t *transport_id;
int transport_id_len;
};
#define to_scst_lcl_host(d) \
@@ -185,6 +197,8 @@ struct scst_local_tgt_specific {
static struct kmem_cache *tgt_specific_pool;
#endif
static atomic_t scst_local_sess_number = ATOMIC_INIT(0);
static LIST_HEAD(scst_local_host_list);
static DEFINE_SPINLOCK(scst_local_host_list_lock);
@@ -710,14 +724,17 @@ static int scst_local_report_aen(struct scst_aen *aen)
{
int res = 0;
int event_fn = scst_aen_get_event_fn(aen);
struct scst_local_host_info *scst_lcl_host = scst_sess_get_tgt_priv(
scst_aen_get_sess(aen));
/*__be64 lun = scst_aen_get_lun(aen);*/
struct scst_local_host_info *scst_lcl_host;
struct scst_local_sess_info *sess;
struct scst_local_work_item *work_item = NULL;
long unsigned flags;
TRACE_ENTRY();
sess = (struct scst_local_sess_info *)scst_sess_get_tgt_priv(
scst_aen_get_sess(aen));
scst_lcl_host = sess->host;
switch (event_fn) {
case SCST_AEN_SCSI:
/*
@@ -749,25 +766,16 @@ static int scst_local_report_aen(struct scst_aen *aen)
return res;
}
static int scst_local_get_initiator_port_transport_id(
struct scst_session *scst_sess,
uint8_t **transport_id)
static int scst_local_get_sas_transport_id(
struct scst_local_sess_info *sess,
uint8_t **transport_id, int *len)
{
int res = 0;
int tr_id_size = 0, sess = -1, i = 0;
int tr_id_size = 0;
uint8_t *tr_id = NULL;
struct scst_local_host_info *scst_lcl_host;
TRACE_ENTRY();
if (scst_sess == NULL) {
res = SCSI_TRANSPORTID_PROTOCOLID_SAS;
goto out;
}
scst_lcl_host = (struct scst_local_host_info *)
scst_sess_get_tgt_priv(scst_sess);
tr_id_size = 24; /* A SAS TransportID */
tr_id = kzalloc(tr_id_size, GFP_KERNEL);
@@ -780,23 +788,6 @@ static int scst_local_get_initiator_port_transport_id(
tr_id[0] = 0x00 | SCSI_TRANSPORTID_PROTOCOLID_SAS;
for (i = 0; i < scst_local_num_tgts; i++) {
/*
* We are called before the session is returned below
*/
if (scst_lcl_host->session[i] == NULL) {
sess = i;
break;
}
}
if (sess == -1) {
printk(KERN_INFO "%s: Unable to find a matching session\n",
__func__);
res = -ENOENT;
goto out;
}
/*
* Assemble a valid SAS address = 0x5OOUUIIR12345678 ... Does SCST
* have one?
@@ -805,13 +796,14 @@ static int scst_local_get_initiator_port_transport_id(
tr_id[4] = 0x5F;
tr_id[5] = 0xEE;
tr_id[6] = 0xDE;
tr_id[7] = 0x40 | ((sess >> 4) & 0x0F);
tr_id[8] = 0x0F | (sess & 0xF0);
tr_id[7] = 0x40 | ((sess->number >> 4) & 0x0F);
tr_id[8] = 0x0F | (sess->number & 0xF0);
tr_id[9] = 0xAD;
tr_id[10] = 0xE0;
tr_id[11] = 0x50;
*transport_id = tr_id;
*len = tr_id_size;
TRACE_DBG("Created tid '%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'",
tr_id[4], tr_id[5], tr_id[6], tr_id[7],
@@ -822,6 +814,53 @@ out:
return res;
}
static int scst_local_get_initiator_port_transport_id(
struct scst_session *scst_sess,
uint8_t **transport_id)
{
int res = 0;
int tr_id_size = 0;
uint8_t *tr_id = NULL;
struct scst_local_sess_info *sess;
TRACE_ENTRY();
if (scst_sess == NULL) {
res = SCSI_TRANSPORTID_PROTOCOLID_SAS;
goto out;
}
sess = (struct scst_local_sess_info *)scst_sess_get_tgt_priv(scst_sess);
mutex_lock(&scst_local_mutex);
if (sess->transport_id == NULL) {
res = scst_local_get_sas_transport_id(sess,
transport_id, &tr_id_size);
goto out_unlock;
}
tr_id_size = sess->transport_id_len;
sBUG_ON(tr_id_size == 0);
tr_id = kzalloc(tr_id_size, GFP_KERNEL);
if (tr_id == NULL) {
PRINT_ERROR("Allocation of TransportID (size %d) failed",
tr_id_size);
res = -ENOMEM;
goto out;
}
memcpy(tr_id, sess->transport_id, sess->transport_id_len);
out_unlock:
mutex_unlock(&scst_local_mutex);
out:
TRACE_EXIT_RES(res);
return res;
}
static void scst_local_release_adapter(struct device *dev)
{
struct scst_local_host_info *scst_lcl_host;
@@ -831,9 +870,14 @@ static void scst_local_release_adapter(struct device *dev)
scst_lcl_host = to_scst_lcl_host(dev);
if (scst_lcl_host) {
for (i = 0; i < scst_local_num_tgts; i++)
if (scst_lcl_host->session[i])
if (scst_lcl_host->session[i]) {
struct scst_local_sess_info *sess;
sess = scst_sess_get_tgt_priv(
scst_lcl_host->session[i]);
scst_unregister_session(
scst_lcl_host->session[i], TRUE, NULL);
kfree(sess);
}
scst_unregister_target(scst_lcl_host->target);
cancel_work_sync(&scst_lcl_host->local_work);
kfree(scst_lcl_host);
@@ -858,11 +902,10 @@ static int scst_local_add_adapter(void)
TRACE_ENTRY();
scst_lcl_host = kzalloc(sizeof(struct scst_local_host_info),
GFP_KERNEL);
scst_lcl_host = kzalloc(sizeof(*scst_lcl_host), GFP_KERNEL);
if (NULL == scst_lcl_host) {
printk(KERN_ERR "%s out of memory at line %d\n",
__func__, __LINE__);
PRINT_ERROR("Unable to alloc scst_lcl_host (size %d)",
sizeof(*scst_lcl_host));
return -ENOMEM;
}
@@ -882,17 +925,32 @@ static int scst_local_add_adapter(void)
goto cleanup;
}
scst_tgt_set_tgt_priv(scst_lcl_host->target, scst_lcl_host);
/*
* Create a session for each device
*/
for (i = 0; i < scst_local_num_tgts; i++) {
struct scst_local_sess_info *sess;
sess = kzalloc(sizeof(*sess), GFP_KERNEL);
if (NULL == sess) {
PRINT_ERROR("Unable to alloc scst_lcl_host (size %d)",
sizeof(*sess));
goto cleanup;
}
sess->host = scst_lcl_host;
sess->number = atomic_inc_return(&scst_local_sess_number);
sprintf(name, "scstlclhst%d:%d", scst_local_add_host, i);
scst_lcl_host->session[i] = scst_register_session(
scst_lcl_host->target,
0, name, (void *)scst_lcl_host,
0, name, (void *)sess,
NULL, NULL);
if (!scst_lcl_host->session[i]) {
printk(KERN_WARNING "scst_register_session failed:\n");
kfree(sess);
error = -1;
goto unregister_target;
}
@@ -1395,12 +1453,259 @@ static void scst_local_targ_task_mgmt_done(struct scst_mgmt_cmd *mgmt_cmd)
return;
}
#ifndef CONFIG_SCST_PROC
static ssize_t scst_local_version_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
sprintf(buf, "%s/%s\n", SCST_LOCAL_VERSION, scst_local_version_date);
#ifdef CONFIG_SCST_EXTRACHECKS
strcat(buf, "EXTRACHECKS\n");
#endif
#ifdef CONFIG_SCST_TRACING
strcat(buf, "TRACING\n");
#endif
#ifdef CONFIG_SCST_DEBUG
strcat(buf, "DEBUG\n");
#endif
TRACE_EXIT();
return strlen(buf);
}
static struct kobj_attribute scst_local_version_attr =
__ATTR(version, S_IRUGO, scst_local_version_show, NULL);
static ssize_t scst_local_scsi_transport_version_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct scst_tgt *scst_tgt;
struct scst_local_host_info *host;
ssize_t size;
scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
host = (struct scst_local_host_info *)scst_tgt_get_tgt_priv(scst_tgt);
if (host->scsi_transport_version != 0)
size = sprintf(buf, "0x%x\n%s", host->scsi_transport_version,
SCST_SYSFS_KEY_MARK "\n");
else
size = sprintf(buf, "0x%x\n", 0x0BE0); /* SAS */
return size;
}
static ssize_t scst_local_scsi_transport_version_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buffer, size_t size)
{
ssize_t res;
struct scst_tgt *scst_tgt;
struct scst_local_host_info *host;
unsigned long val;
scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
host = (struct scst_local_host_info *)scst_tgt_get_tgt_priv(scst_tgt);
res = strict_strtoul(buffer, 0, &val);
if (res != 0) {
PRINT_ERROR("strict_strtoul() for %s failed: %d", buffer, res);
goto out;
}
host->scsi_transport_version = val;
res = size;
out:
return res;
}
static struct kobj_attribute scst_local_scsi_transport_version_attr =
__ATTR(scsi_transport_version, S_IRUGO| S_IWUSR,
scst_local_scsi_transport_version_show,
scst_local_scsi_transport_version_store);
static ssize_t scst_local_phys_transport_version_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct scst_tgt *scst_tgt;
struct scst_local_host_info *host;
scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
host = (struct scst_local_host_info *)scst_tgt_get_tgt_priv(scst_tgt);
return sprintf(buf, "0x%x\n%s", host->phys_transport_version,
(host->phys_transport_version != 0) ?
SCST_SYSFS_KEY_MARK "\n" : "");
}
static ssize_t scst_local_phys_transport_version_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buffer, size_t size)
{
ssize_t res;
struct scst_tgt *scst_tgt;
struct scst_local_host_info *host;
unsigned long val;
scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
host = (struct scst_local_host_info *)scst_tgt_get_tgt_priv(scst_tgt);
res = strict_strtoul(buffer, 0, &val);
if (res != 0) {
PRINT_ERROR("strict_strtoul() for %s failed: %d", buffer, res);
goto out;
}
host->phys_transport_version = val;
res = size;
out:
return res;
}
static struct kobj_attribute scst_local_phys_transport_version_attr =
__ATTR(phys_transport_version, S_IRUGO| S_IWUSR,
scst_local_phys_transport_version_show,
scst_local_phys_transport_version_store);
static ssize_t scst_local_transport_id_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
ssize_t res;
struct scst_session *scst_sess;
struct scst_local_sess_info *sess;
uint8_t *tr_id;
int tr_id_len, i;
scst_sess = container_of(kobj, struct scst_session, sess_kobj);
sess = (struct scst_local_sess_info *)scst_sess_get_tgt_priv(scst_sess);
mutex_lock(&scst_local_mutex);
if (sess->transport_id != NULL) {
tr_id = sess->transport_id;
tr_id_len = sess->transport_id_len;
} else {
res = scst_local_get_sas_transport_id(sess, &tr_id, &tr_id_len);
if (res != 0)
goto out_unlock;
}
res = 0;
for (i = 0; i < tr_id_len; i++)
res += sprintf(&buf[res], "%c", tr_id[i]);
if (sess->transport_id != NULL)
res += sprintf(&buf[res], "\n%s", SCST_SYSFS_KEY_MARK "\n");
else
kfree(tr_id);
out_unlock:
mutex_unlock(&scst_local_mutex);
return res;
}
static ssize_t scst_local_transport_id_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buffer, size_t size)
{
ssize_t res;
struct scst_session *scst_sess;
struct scst_local_sess_info *sess;
scst_sess = container_of(kobj, struct scst_session, sess_kobj);
sess = (struct scst_local_sess_info *)scst_sess_get_tgt_priv(scst_sess);
mutex_lock(&scst_local_mutex);
if (sess->transport_id != NULL) {
kfree(sess->transport_id);
sess->transport_id = NULL;
sess->transport_id_len = 0;
}
if (size == 0)
goto out_res;
sess->transport_id = kzalloc(size, GFP_KERNEL);
if (sess->transport_id == NULL) {
PRINT_ERROR("Allocation of transport_id (size %d) failed",
size);
res = -ENOMEM;
goto out_unlock;
}
sess->transport_id_len = size;
memcpy(sess->transport_id, buffer, sess->transport_id_len);
out_res:
res = size;
out_unlock:
mutex_unlock(&scst_local_mutex);
return res;
}
static struct kobj_attribute scst_local_transport_id_attr =
__ATTR(transport_id, S_IRUGO| S_IWUSR,
scst_local_transport_id_show,
scst_local_transport_id_store);
static const struct attribute *scst_local_tgtt_attrs[] = {
&scst_local_version_attr.attr,
NULL,
};
static const struct attribute *scst_local_tgt_attrs[] = {
&scst_local_scsi_transport_version_attr.attr,
&scst_local_phys_transport_version_attr.attr,
NULL,
};
static const struct attribute *scst_local_sess_attrs[] = {
&scst_local_transport_id_attr.attr,
NULL,
};
#endif /* CONFIG_SCST_PROC */
static uint16_t scst_local_get_scsi_transport_version(struct scst_cmd *scst_cmd)
{
struct scst_local_host_info *host;
host = (struct scst_local_host_info *)scst_tgt_get_tgt_priv(
scst_cmd_get_tgt(scst_cmd));
if (host->scsi_transport_version == 0)
return 0x0BE0; /* SAS */
else
return host->scsi_transport_version;
}
static uint16_t scst_local_get_phys_transport_version(struct scst_cmd *scst_cmd)
{
struct scst_local_host_info *host;
host = (struct scst_local_host_info *)scst_tgt_get_tgt_priv(
scst_cmd_get_tgt(scst_cmd));
return host->phys_transport_version;
}
static struct scst_tgt_template scst_local_targ_tmpl = {
.name = "scst_local_tgt",
.sg_tablesize = 0xffff,
.xmit_response_atomic = 1,
#ifndef CONFIG_SCST_PROC
.enabled_attr_not_needed = 1,
.tgtt_attrs = scst_local_tgtt_attrs,
.tgt_attrs = scst_local_tgt_attrs,
.sess_attrs = scst_local_sess_attrs,
#endif
.detect = scst_local_targ_detect,
.release = scst_local_targ_release,
@@ -1409,8 +1714,13 @@ static struct scst_tgt_template scst_local_targ_tmpl = {
.on_free_cmd = scst_local_targ_on_free_cmd,
.task_mgmt_fn_done = scst_local_targ_task_mgmt_done,
.report_aen = scst_local_report_aen,
.get_initiator_port_transport_id
= scst_local_get_initiator_port_transport_id,
.get_initiator_port_transport_id = scst_local_get_initiator_port_transport_id,
.get_scsi_transport_version = scst_local_get_scsi_transport_version,
.get_phys_transport_version = scst_local_get_phys_transport_version,
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
.default_trace_flags = SCST_LOCAL_DEFAULT_LOG_FLAGS,
.trace_flags = &trace_flag,
#endif
};
/*
+6
View File
@@ -3495,6 +3495,11 @@ static int srpt_release(struct scst_tgt *scst_tgt)
return 0;
}
static uint16_t srpt_get_scsi_transport_version(struct scst_cmd *scst_cmd)
{
return 0x0940; /* SRP */
}
/* SCST target template for the SRP target implementation. */
static struct scst_tgt_template srpt_template = {
.name = DRV_NAME,
@@ -3516,6 +3521,7 @@ static struct scst_tgt_template srpt_template = {
.on_free_cmd = srpt_on_free_cmd,
.task_mgmt_fn_done = srpt_tsk_mgmt_done,
.get_initiator_port_transport_id = srpt_get_initiator_port_transport_id,
.get_scsi_transport_version = srpt_get_scsi_transport_version,
};
/**