Commit 72f96e0e authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus-core' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending

* 'for-linus-core' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (38 commits)
  target: Bump version to v4.1.0-rc1-ml
  target: remove custom hex2bin() implementation
  target: fix typo Assoication -> Association
  target: Update QUEUE ALGORITHM MODIFIER control page default
  target: ->map_task_SG conversion to ->map_control_SG and ->map_data_SG
  target: Follow up core updates from AGrover and HCH (round 4)
  target: Eliminate usage of struct se_mem
  target: Pass 2nd param of transport_split_cdb by value
  target: Enforce 1 page max for control cdb buffer sizes
  target: Make all control CDBs scatter-gather
  target: Implement Block Device Characteristics VPD page
  target: Fix reporting of supported VPD pages
  target: Allow for built-in target modules
  tcm_fc: Convert to wake_up_process and schedule_timeout_interruptible
  tcm_fc: Makefile cleanups
  loopback: Fix memory leak in tcm_loop_make_scsi_hba()
  loopback: Remove duplicate scsi/scsi_tcq.h include
  loopback: off by one in tcm_loop_make_naa_tpg()
  target/iblock: Remove unused iblock_dev members
  target/iblock: Use request_queue->nr_request for se_device defaults
  ...
parents 17413f5a fa495159
...@@ -3,9 +3,3 @@ config LOOPBACK_TARGET ...@@ -3,9 +3,3 @@ config LOOPBACK_TARGET
help help
Say Y here to enable the TCM Virtual SAS target and Linux/SCSI LLD Say Y here to enable the TCM Virtual SAS target and Linux/SCSI LLD
fabric loopback module. fabric loopback module.
config LOOPBACK_TARGET_CDB_DEBUG
bool "TCM loopback fabric module CDB debug code"
depends on LOOPBACK_TARGET
help
Say Y here to enable the TCM loopback fabric module CDB debug code
This diff is collapsed.
...@@ -16,12 +16,6 @@ ...@@ -16,12 +16,6 @@
*/ */
#define TL_SCSI_MAX_CMD_LEN 32 #define TL_SCSI_MAX_CMD_LEN 32
#ifdef CONFIG_LOOPBACK_TARGET_CDB_DEBUG
# define TL_CDB_DEBUG(x...) printk(KERN_INFO x)
#else
# define TL_CDB_DEBUG(x...)
#endif
struct tcm_loop_cmd { struct tcm_loop_cmd {
/* State of Linux/SCSI CDB+Data descriptor */ /* State of Linux/SCSI CDB+Data descriptor */
u32 sc_cmd_state; u32 sc_cmd_state;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
* *
******************************************************************************/ ******************************************************************************/
#include <linux/kernel.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
...@@ -61,9 +62,8 @@ u32 sas_get_pr_transport_id( ...@@ -61,9 +62,8 @@ u32 sas_get_pr_transport_id(
int *format_code, int *format_code,
unsigned char *buf) unsigned char *buf)
{ {
unsigned char binary, *ptr; unsigned char *ptr;
int i;
u32 off = 4;
/* /*
* Set PROTOCOL IDENTIFIER to 6h for SAS * Set PROTOCOL IDENTIFIER to 6h for SAS
*/ */
...@@ -74,10 +74,8 @@ u32 sas_get_pr_transport_id( ...@@ -74,10 +74,8 @@ u32 sas_get_pr_transport_id(
*/ */
ptr = &se_nacl->initiatorname[4]; /* Skip over 'naa. prefix */ ptr = &se_nacl->initiatorname[4]; /* Skip over 'naa. prefix */
for (i = 0; i < 16; i += 2) { hex2bin(&buf[4], ptr, 8);
binary = transport_asciihex_to_binaryhex(&ptr[i]);
buf[off++] = binary;
}
/* /*
* The SAS Transport ID is a hardcoded 24-byte length * The SAS Transport ID is a hardcoded 24-byte length
*/ */
...@@ -157,7 +155,7 @@ u32 fc_get_pr_transport_id( ...@@ -157,7 +155,7 @@ u32 fc_get_pr_transport_id(
int *format_code, int *format_code,
unsigned char *buf) unsigned char *buf)
{ {
unsigned char binary, *ptr; unsigned char *ptr;
int i; int i;
u32 off = 8; u32 off = 8;
/* /*
...@@ -172,12 +170,11 @@ u32 fc_get_pr_transport_id( ...@@ -172,12 +170,11 @@ u32 fc_get_pr_transport_id(
ptr = &se_nacl->initiatorname[0]; ptr = &se_nacl->initiatorname[0];
for (i = 0; i < 24; ) { for (i = 0; i < 24; ) {
if (!(strncmp(&ptr[i], ":", 1))) { if (!strncmp(&ptr[i], ":", 1)) {
i++; i++;
continue; continue;
} }
binary = transport_asciihex_to_binaryhex(&ptr[i]); hex2bin(&buf[off++], &ptr[i], 1);
buf[off++] = binary;
i += 2; i += 2;
} }
/* /*
...@@ -386,7 +383,7 @@ char *iscsi_parse_pr_out_transport_id( ...@@ -386,7 +383,7 @@ char *iscsi_parse_pr_out_transport_id(
* Reserved * Reserved
*/ */
if ((format_code != 0x00) && (format_code != 0x40)) { if ((format_code != 0x00) && (format_code != 0x40)) {
printk(KERN_ERR "Illegal format code: 0x%02x for iSCSI" pr_err("Illegal format code: 0x%02x for iSCSI"
" Initiator Transport ID\n", format_code); " Initiator Transport ID\n", format_code);
return NULL; return NULL;
} }
...@@ -406,7 +403,7 @@ char *iscsi_parse_pr_out_transport_id( ...@@ -406,7 +403,7 @@ char *iscsi_parse_pr_out_transport_id(
tid_len += padding; tid_len += padding;
if ((add_len + 4) != tid_len) { if ((add_len + 4) != tid_len) {
printk(KERN_INFO "LIO-Target Extracted add_len: %hu " pr_debug("LIO-Target Extracted add_len: %hu "
"does not match calculated tid_len: %u," "does not match calculated tid_len: %u,"
" using tid_len instead\n", add_len+4, tid_len); " using tid_len instead\n", add_len+4, tid_len);
*out_tid_len = tid_len; *out_tid_len = tid_len;
...@@ -420,8 +417,8 @@ char *iscsi_parse_pr_out_transport_id( ...@@ -420,8 +417,8 @@ char *iscsi_parse_pr_out_transport_id(
*/ */
if (format_code == 0x40) { if (format_code == 0x40) {
p = strstr((char *)&buf[4], ",i,0x"); p = strstr((char *)&buf[4], ",i,0x");
if (!(p)) { if (!p) {
printk(KERN_ERR "Unable to locate \",i,0x\" seperator" pr_err("Unable to locate \",i,0x\" seperator"
" for Initiator port identifier: %s\n", " for Initiator port identifier: %s\n",
(char *)&buf[4]); (char *)&buf[4]);
return NULL; return NULL;
......
This diff is collapsed.
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
#define FD_VERSION "4.0" #define FD_VERSION "4.0"
#define FD_MAX_DEV_NAME 256 #define FD_MAX_DEV_NAME 256
/* Maximum queuedepth for the FILEIO HBA */
#define FD_HBA_QUEUE_DEPTH 256
#define FD_DEVICE_QUEUE_DEPTH 32 #define FD_DEVICE_QUEUE_DEPTH 32
#define FD_MAX_DEVICE_QUEUE_DEPTH 128 #define FD_MAX_DEVICE_QUEUE_DEPTH 128
#define FD_BLOCKSIZE 512 #define FD_BLOCKSIZE 512
...@@ -18,8 +16,6 @@ struct fd_request { ...@@ -18,8 +16,6 @@ struct fd_request {
struct se_task fd_task; struct se_task fd_task;
/* SCSI CDB from iSCSI Command PDU */ /* SCSI CDB from iSCSI Command PDU */
unsigned char fd_scsi_cdb[TCM_MAX_COMMAND_SIZE]; unsigned char fd_scsi_cdb[TCM_MAX_COMMAND_SIZE];
/* FILEIO device */
struct fd_dev *fd_dev;
} ____cacheline_aligned; } ____cacheline_aligned;
#define FBDF_HAS_PATH 0x01 #define FBDF_HAS_PATH 0x01
......
/******************************************************************************* /*******************************************************************************
* Filename: target_core_hba.c * Filename: target_core_hba.c
* *
* This file copntains the iSCSI HBA Transport related functions. * This file contains the TCM HBA Transport related functions.
* *
* Copyright (c) 2003, 2004, 2005 PyX Technologies, Inc. * Copyright (c) 2003, 2004, 2005 PyX Technologies, Inc.
* Copyright (c) 2005, 2006, 2007 SBE, Inc. * Copyright (c) 2005, 2006, 2007 SBE, Inc.
...@@ -45,6 +45,11 @@ ...@@ -45,6 +45,11 @@
static LIST_HEAD(subsystem_list); static LIST_HEAD(subsystem_list);
static DEFINE_MUTEX(subsystem_mutex); static DEFINE_MUTEX(subsystem_mutex);
static u32 hba_id_counter;
static DEFINE_SPINLOCK(hba_lock);
static LIST_HEAD(hba_list);
int transport_subsystem_register(struct se_subsystem_api *sub_api) int transport_subsystem_register(struct se_subsystem_api *sub_api)
{ {
struct se_subsystem_api *s; struct se_subsystem_api *s;
...@@ -53,8 +58,8 @@ int transport_subsystem_register(struct se_subsystem_api *sub_api) ...@@ -53,8 +58,8 @@ int transport_subsystem_register(struct se_subsystem_api *sub_api)
mutex_lock(&subsystem_mutex); mutex_lock(&subsystem_mutex);
list_for_each_entry(s, &subsystem_list, sub_api_list) { list_for_each_entry(s, &subsystem_list, sub_api_list) {
if (!(strcmp(s->name, sub_api->name))) { if (!strcmp(s->name, sub_api->name)) {
printk(KERN_ERR "%p is already registered with" pr_err("%p is already registered with"
" duplicate name %s, unable to process" " duplicate name %s, unable to process"
" request\n", s, s->name); " request\n", s, s->name);
mutex_unlock(&subsystem_mutex); mutex_unlock(&subsystem_mutex);
...@@ -64,7 +69,7 @@ int transport_subsystem_register(struct se_subsystem_api *sub_api) ...@@ -64,7 +69,7 @@ int transport_subsystem_register(struct se_subsystem_api *sub_api)
list_add_tail(&sub_api->sub_api_list, &subsystem_list); list_add_tail(&sub_api->sub_api_list, &subsystem_list);
mutex_unlock(&subsystem_mutex); mutex_unlock(&subsystem_mutex);
printk(KERN_INFO "TCM: Registered subsystem plugin: %s struct module:" pr_debug("TCM: Registered subsystem plugin: %s struct module:"
" %p\n", sub_api->name, sub_api->owner); " %p\n", sub_api->name, sub_api->owner);
return 0; return 0;
} }
...@@ -104,21 +109,17 @@ core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags) ...@@ -104,21 +109,17 @@ core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags)
hba = kzalloc(sizeof(*hba), GFP_KERNEL); hba = kzalloc(sizeof(*hba), GFP_KERNEL);
if (!hba) { if (!hba) {
printk(KERN_ERR "Unable to allocate struct se_hba\n"); pr_err("Unable to allocate struct se_hba\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
INIT_LIST_HEAD(&hba->hba_dev_list); INIT_LIST_HEAD(&hba->hba_dev_list);
spin_lock_init(&hba->device_lock); spin_lock_init(&hba->device_lock);
spin_lock_init(&hba->hba_queue_lock);
mutex_init(&hba->hba_access_mutex); mutex_init(&hba->hba_access_mutex);
hba->hba_index = scsi_get_new_index(SCSI_INST_INDEX); hba->hba_index = scsi_get_new_index(SCSI_INST_INDEX);
hba->hba_flags |= hba_flags; hba->hba_flags |= hba_flags;
atomic_set(&hba->max_queue_depth, 0);
atomic_set(&hba->left_queue_depth, 0);
hba->transport = core_get_backend(plugin_name); hba->transport = core_get_backend(plugin_name);
if (!hba->transport) { if (!hba->transport) {
ret = -EINVAL; ret = -EINVAL;
...@@ -129,12 +130,12 @@ core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags) ...@@ -129,12 +130,12 @@ core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags)
if (ret < 0) if (ret < 0)
goto out_module_put; goto out_module_put;
spin_lock(&se_global->hba_lock); spin_lock(&hba_lock);
hba->hba_id = se_global->g_hba_id_counter++; hba->hba_id = hba_id_counter++;
list_add_tail(&hba->hba_list, &se_global->g_hba_list); list_add_tail(&hba->hba_node, &hba_list);
spin_unlock(&se_global->hba_lock); spin_unlock(&hba_lock);
printk(KERN_INFO "CORE_HBA[%d] - Attached HBA to Generic Target" pr_debug("CORE_HBA[%d] - Attached HBA to Generic Target"
" Core\n", hba->hba_id); " Core\n", hba->hba_id);
return hba; return hba;
...@@ -156,11 +157,11 @@ core_delete_hba(struct se_hba *hba) ...@@ -156,11 +157,11 @@ core_delete_hba(struct se_hba *hba)
hba->transport->detach_hba(hba); hba->transport->detach_hba(hba);
spin_lock(&se_global->hba_lock); spin_lock(&hba_lock);
list_del(&hba->hba_list); list_del(&hba->hba_node);
spin_unlock(&se_global->hba_lock); spin_unlock(&hba_lock);
printk(KERN_INFO "CORE_HBA[%d] - Detached HBA from Generic Target" pr_debug("CORE_HBA[%d] - Detached HBA from Generic Target"
" Core\n", hba->hba_id); " Core\n", hba->hba_id);
if (hba->transport->owner) if (hba->transport->owner)
......
This diff is collapsed.
...@@ -3,9 +3,6 @@ ...@@ -3,9 +3,6 @@
#define IBLOCK_VERSION "4.0" #define IBLOCK_VERSION "4.0"
#define IBLOCK_HBA_QUEUE_DEPTH 512
#define IBLOCK_DEVICE_QUEUE_DEPTH 32
#define IBLOCK_MAX_DEVICE_QUEUE_DEPTH 128
#define IBLOCK_MAX_CDBS 16 #define IBLOCK_MAX_CDBS 16
#define IBLOCK_LBA_SHIFT 9 #define IBLOCK_LBA_SHIFT 9
...@@ -15,18 +12,12 @@ struct iblock_req { ...@@ -15,18 +12,12 @@ struct iblock_req {
atomic_t ib_bio_cnt; atomic_t ib_bio_cnt;
atomic_t ib_bio_err_cnt; atomic_t ib_bio_err_cnt;
struct bio *ib_bio; struct bio *ib_bio;
struct iblock_dev *ib_dev;
} ____cacheline_aligned; } ____cacheline_aligned;
#define IBDF_HAS_UDEV_PATH 0x01 #define IBDF_HAS_UDEV_PATH 0x01
#define IBDF_HAS_FORCE 0x02
struct iblock_dev { struct iblock_dev {
unsigned char ibd_udev_path[SE_UDEV_PATH_LEN]; unsigned char ibd_udev_path[SE_UDEV_PATH_LEN];
int ibd_force;
int ibd_major;
int ibd_minor;
u32 ibd_depth;
u32 ibd_flags; u32 ibd_flags;
struct bio_set *ibd_bio_set; struct bio_set *ibd_bio_set;
struct block_device *ibd_bd; struct block_device *ibd_bd;
......
This diff is collapsed.
...@@ -49,7 +49,7 @@ extern int core_pr_dump_initiator_port(struct t10_pr_registration *, ...@@ -49,7 +49,7 @@ extern int core_pr_dump_initiator_port(struct t10_pr_registration *,
char *, u32); char *, u32);
extern int core_scsi2_emulate_crh(struct se_cmd *); extern int core_scsi2_emulate_crh(struct se_cmd *);
extern int core_scsi3_alloc_aptpl_registration( extern int core_scsi3_alloc_aptpl_registration(
struct t10_reservation_template *, u64, struct t10_reservation *, u64,
unsigned char *, unsigned char *, u32, unsigned char *, unsigned char *, u32,
unsigned char *, u16, u32, int, int, u8); unsigned char *, u16, u32, int, int, u8);
extern int core_scsi3_check_aptpl_registration(struct se_device *, extern int core_scsi3_check_aptpl_registration(struct se_device *,
......
This diff is collapsed.
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#define TARGET_CORE_PSCSI_H #define TARGET_CORE_PSCSI_H
#define PSCSI_VERSION "v4.0" #define PSCSI_VERSION "v4.0"
#define PSCSI_VIRTUAL_HBA_DEPTH 2048
/* used in pscsi_find_alloc_len() */ /* used in pscsi_find_alloc_len() */
#ifndef INQUIRY_DATA_SIZE #ifndef INQUIRY_DATA_SIZE
...@@ -24,13 +23,12 @@ ...@@ -24,13 +23,12 @@
struct pscsi_plugin_task { struct pscsi_plugin_task {
struct se_task pscsi_task; struct se_task pscsi_task;
unsigned char *pscsi_cdb;
unsigned char __pscsi_cdb[TCM_MAX_COMMAND_SIZE];
unsigned char pscsi_sense[SCSI_SENSE_BUFFERSIZE]; unsigned char pscsi_sense[SCSI_SENSE_BUFFERSIZE];
int pscsi_direction; int pscsi_direction;
int pscsi_result; int pscsi_result;
u32 pscsi_resid; u32 pscsi_resid;
struct request *pscsi_req; struct request *pscsi_req;
unsigned char pscsi_cdb[0];
} ____cacheline_aligned; } ____cacheline_aligned;
#define PDF_HAS_CHANNEL_ID 0x01 #define PDF_HAS_CHANNEL_ID 0x01
......
This diff is collapsed.
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
/* Largest piece of memory kmalloc can allocate */ /* Largest piece of memory kmalloc can allocate */
#define RD_MAX_ALLOCATION_SIZE 65536 #define RD_MAX_ALLOCATION_SIZE 65536
/* Maximum queuedepth for the Ramdisk HBA */
#define RD_HBA_QUEUE_DEPTH 256
#define RD_DEVICE_QUEUE_DEPTH 32 #define RD_DEVICE_QUEUE_DEPTH 32
#define RD_MAX_DEVICE_QUEUE_DEPTH 128 #define RD_MAX_DEVICE_QUEUE_DEPTH 128
#define RD_BLOCKSIZE 512 #define RD_BLOCKSIZE 512
...@@ -34,8 +32,6 @@ struct rd_request { ...@@ -34,8 +32,6 @@ struct rd_request {
u32 rd_page_count; u32 rd_page_count;
/* Scatterlist count */ /* Scatterlist count */
u32 rd_size; u32 rd_size;
/* Ramdisk device */
struct rd_dev *rd_dev;
} ____cacheline_aligned; } ____cacheline_aligned;
struct rd_dev_sg_table { struct rd_dev_sg_table {
......
...@@ -42,13 +42,13 @@ ...@@ -42,13 +42,13 @@
*/ */
void split_cdb_XX_6( void split_cdb_XX_6(
unsigned long long lba, unsigned long long lba,
u32 *sectors, u32 sectors,
unsigned char *cdb) unsigned char *cdb)
{ {
cdb[1] = (lba >> 16) & 0x1f; cdb[1] = (lba >> 16) & 0x1f;
cdb[2] = (lba >> 8) & 0xff; cdb[2] = (lba >> 8) & 0xff;
cdb[3] = lba & 0xff; cdb[3] = lba & 0xff;
cdb[4] = *sectors & 0xff; cdb[4] = sectors & 0xff;
} }
/* split_cdb_XX_10(): /* split_cdb_XX_10():
...@@ -57,11 +57,11 @@ void split_cdb_XX_6( ...@@ -57,11 +57,11 @@ void split_cdb_XX_6(
*/ */
void split_cdb_XX_10( void split_cdb_XX_10(
unsigned long long lba, unsigned long long lba,
u32 *sectors, u32 sectors,
unsigned char *cdb) unsigned char *cdb)
{ {
put_unaligned_be32(lba, &cdb[2]); put_unaligned_be32(lba, &cdb[2]);
put_unaligned_be16(*sectors, &cdb[7]); put_unaligned_be16(sectors, &cdb[7]);
} }
/* split_cdb_XX_12(): /* split_cdb_XX_12():
...@@ -70,11 +70,11 @@ void split_cdb_XX_10( ...@@ -70,11 +70,11 @@ void split_cdb_XX_10(
*/ */
void split_cdb_XX_12( void split_cdb_XX_12(
unsigned long long lba, unsigned long long lba,
u32 *sectors, u32 sectors,
unsigned char *cdb) unsigned char *cdb)
{ {
put_unaligned_be32(lba, &cdb[2]); put_unaligned_be32(lba, &cdb[2]);
put_unaligned_be32(*sectors, &cdb[6]); put_unaligned_be32(sectors, &cdb[6]);
} }
/* split_cdb_XX_16(): /* split_cdb_XX_16():
...@@ -83,11 +83,11 @@ void split_cdb_XX_12( ...@@ -83,11 +83,11 @@ void split_cdb_XX_12(
*/ */
void split_cdb_XX_16( void split_cdb_XX_16(
unsigned long long lba, unsigned long long lba,
u32 *sectors, u32 sectors,
unsigned char *cdb) unsigned char *cdb)
{ {
put_unaligned_be64(lba, &cdb[2]); put_unaligned_be64(lba, &cdb[2]);
put_unaligned_be32(*sectors, &cdb[10]); put_unaligned_be32(sectors, &cdb[10]);
} }
/* /*
...@@ -97,9 +97,9 @@ void split_cdb_XX_16( ...@@ -97,9 +97,9 @@ void split_cdb_XX_16(
*/ */
void split_cdb_XX_32( void split_cdb_XX_32(
unsigned long long lba, unsigned long long lba,
u32 *sectors, u32 sectors,
unsigned char *cdb) unsigned char *cdb)
{ {
put_unaligned_be64(lba, &cdb[12]); put_unaligned_be64(lba, &cdb[12]);
put_unaligned_be32(*sectors, &cdb[28]); put_unaligned_be32(sectors, &cdb[28]);
} }
#ifndef TARGET_CORE_SCDB_H #ifndef TARGET_CORE_SCDB_H
#define TARGET_CORE_SCDB_H #define TARGET_CORE_SCDB_H
extern void split_cdb_XX_6(unsigned long long, u32 *, unsigned char *); extern void split_cdb_XX_6(unsigned long long, u32, unsigned char *);
extern void split_cdb_XX_10(unsigned long long, u32 *, unsigned char *); extern void split_cdb_XX_10(unsigned long long, u32, unsigned char *);
extern void split_cdb_XX_12(unsigned long long, u32 *, unsigned char *); extern void split_cdb_XX_12(unsigned long long, u32, unsigned char *);
extern void split_cdb_XX_16(unsigned long long, u32 *, unsigned char *); extern void split_cdb_XX_16(unsigned long long, u32, unsigned char *);
extern void split_cdb_XX_32(unsigned long long, u32 *, unsigned char *); extern void split_cdb_XX_32(unsigned long long, u32, unsigned char *);
#endif /* TARGET_CORE_SCDB_H */ #endif /* TARGET_CORE_SCDB_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment