mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-25 07:51:28 +00:00
Implement qlini_mode qla2xxx module parameter with ini_mode_force_reverse sysfs attribute instead of CONFIG_SCSI_QLA2XXX_TARGET_DISABLE_INI_MODE compile-time option for better flexibility.
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1781 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -31,20 +31,8 @@ config SCSI_QLA2XXX_TARGET
|
||||
depends on SCSI_QLA_FC
|
||||
default y
|
||||
---help---
|
||||
This option enables target mode hooks used by the SCST QLA2x00tgt driver.
|
||||
Once the qla2x00tgt module is loaded, target mode can be enable via a
|
||||
sysfs interface under scsi_host, thus enabling target mode for specific
|
||||
cards.
|
||||
You will also need the SCST middle level drivers from
|
||||
http://scst.sourceforge.net/.
|
||||
This option enables target mode hooks used by the SCST qla2x00t
|
||||
driver. Once qla2x00tgt module is loaded, target mode for each
|
||||
port can be enable via sysfs interface.
|
||||
|
||||
config SCSI_QLA2XXX_TARGET_DISABLE_INI_MODE
|
||||
bool "Disable initiator mode for ports with enabled target mode"
|
||||
depends on SCSI_QLA2XXX_TARGET
|
||||
default y
|
||||
---help---
|
||||
This option disables initiator mode for hosts for which target mode was
|
||||
enabled. In other words, it disables possibility to use both target and
|
||||
initiator mode simultaneously on the same host. It is needed, because
|
||||
some switches don't handle well ports with both target and initiator
|
||||
modes enabled.
|
||||
You will also need the SCST middle level for qla2x00t.
|
||||
|
||||
@@ -107,6 +107,37 @@ http://sourceforge.net/mailarchive/forum.php?thread_name=4B4CD39F.6020401%40vlnb
|
||||
for more details why.
|
||||
|
||||
|
||||
Initiator and target modes
|
||||
--------------------------
|
||||
|
||||
When qla2xxx compiled with CONFIG_SCSI_QLA2XXX_TARGET enabled, it has
|
||||
parameter "ini_mode", which determines when initiator mode will be
|
||||
enabled. Possible values:
|
||||
|
||||
- "exclusive" (default ) - initiator mode will be enabled on load,
|
||||
disabled on enabling target mode and then on disabling target mode
|
||||
enabled back.
|
||||
|
||||
- "disabled" - initiator mode will never be enabled.
|
||||
|
||||
- "enabled" - initiator mode will always stay enabled.
|
||||
|
||||
Usage of mode "disabled" is recommended if you have incorrectly
|
||||
functioning remote for your target initiators, which if they once seen a
|
||||
port in initiator mode, later refuse to see it as a target.
|
||||
|
||||
Use mode "enabled" if you need your QLA adapters to work in both
|
||||
initiator and target modes at the same time.
|
||||
|
||||
In all the modes you can at any time use sysfs attribute
|
||||
ini_mode_force_reverse to force enable or disable initiator mode on any
|
||||
particular port. Setting this attribute to 1 will reverse current status
|
||||
of the initiator mode from enabled to disabled and vice versa.
|
||||
|
||||
You can always see which modes are currently active in active_mode sysfs
|
||||
attribute.
|
||||
|
||||
|
||||
Explicit conformation
|
||||
---------------------
|
||||
|
||||
|
||||
@@ -34,31 +34,27 @@ extern request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
|
||||
|
||||
extern struct qla_tgt_data qla_target;
|
||||
|
||||
/* Called under HW lock */
|
||||
static inline void qla_set_tgt_mode(scsi_qla_host_t *ha)
|
||||
{
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET_DISABLE_INI_MODE
|
||||
ha->host->active_mode = MODE_TARGET;
|
||||
#else
|
||||
ha->host->active_mode |= MODE_TARGET;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Called under HW lock */
|
||||
static inline void qla_clear_tgt_mode(scsi_qla_host_t *ha)
|
||||
{
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET_DISABLE_INI_MODE
|
||||
ha->host->active_mode = MODE_INITIATOR;
|
||||
#else
|
||||
ha->host->active_mode &= ~MODE_TARGET;
|
||||
#endif
|
||||
}
|
||||
void qla_set_tgt_mode(scsi_qla_host_t *ha);
|
||||
void qla_clear_tgt_mode(scsi_qla_host_t *ha);
|
||||
|
||||
static inline bool qla_tgt_mode_enabled(scsi_qla_host_t *ha)
|
||||
{
|
||||
return ha->host->active_mode & MODE_TARGET;
|
||||
}
|
||||
|
||||
static inline bool qla_ini_mode_enabled(scsi_qla_host_t *ha)
|
||||
{
|
||||
return ha->host->active_mode & MODE_INITIATOR;
|
||||
}
|
||||
|
||||
static inline void qla_reverse_ini_mode(scsi_qla_host_t *ha)
|
||||
{
|
||||
if (ha->host->active_mode & MODE_INITIATOR)
|
||||
ha->host->active_mode &= ~MODE_INITIATOR;
|
||||
else
|
||||
ha->host->active_mode |= MODE_INITIATOR;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* ISP Queue types left out of new QLogic driver (from old version)
|
||||
\********************************************************************/
|
||||
|
||||
@@ -44,13 +44,21 @@
|
||||
* Must be changed on any change in any initiator visible interfaces or
|
||||
* data in the target add-on
|
||||
*/
|
||||
#define QLA2X_TARGET_MAGIC 265
|
||||
#define QLA2X_TARGET_MAGIC 267
|
||||
|
||||
/*
|
||||
* Must be changed on any change in any target visible interfaces or
|
||||
* data in the initiator
|
||||
*/
|
||||
#define QLA2X_INITIATOR_MAGIC 57218
|
||||
#define QLA2X_INITIATOR_MAGIC 57219
|
||||
|
||||
#define QLA2X_INI_MODE_STR_EXCLUSIVE "exclusive"
|
||||
#define QLA2X_INI_MODE_STR_DISABLED "disabled"
|
||||
#define QLA2X_INI_MODE_STR_ENABLED "enabled"
|
||||
|
||||
#define QLA2X_INI_MODE_EXCLUSIVE 0
|
||||
#define QLA2X_INI_MODE_DISABLED 1
|
||||
#define QLA2X_INI_MODE_ENABLED 2
|
||||
|
||||
#define QLA2X00_COMMAND_COUNT_INIT 250
|
||||
#define QLA2X00_IMMED_NOTIFY_COUNT_INIT 250
|
||||
|
||||
@@ -214,6 +214,75 @@ static DEVICE_ATTR(explicit_conform_enabled,
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
static ssize_t
|
||||
qla2x00_show_ini_mode_force_reverse(struct device *dev,
|
||||
struct device_attribute *attr, char *buffer)
|
||||
{
|
||||
scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
|
||||
ulong max_size = PAGE_SIZE;
|
||||
ulong size;
|
||||
|
||||
size = scnprintf(buffer, max_size, "%x\n", ha->ini_mode_force_reverse);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qla2x00_store_ini_mode_force_reverse(struct device *dev,
|
||||
struct device_attribute *attr, const char *buffer, size_t size)
|
||||
{
|
||||
struct scsi_qla_host *ha = shost_priv(class_to_shost(dev));
|
||||
unsigned long flags;
|
||||
|
||||
if (buffer == NULL)
|
||||
return size;
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
|
||||
switch (buffer[0]) {
|
||||
case '0':
|
||||
if (!ha->ini_mode_force_reverse)
|
||||
goto out_unlock;
|
||||
ha->ini_mode_force_reverse = 0;
|
||||
qla_printk(KERN_INFO, ha, "qla2xxx(%ld): initiator mode force "
|
||||
"reverse disabled\n", ha->instance);
|
||||
qla_reverse_ini_mode(ha);
|
||||
break;
|
||||
case '1':
|
||||
if (ha->ini_mode_force_reverse)
|
||||
goto out_unlock;
|
||||
ha->ini_mode_force_reverse = 1;
|
||||
qla_printk(KERN_INFO, ha, "qla2xxx(%ld): initiator mode force "
|
||||
"reverse enabled\n", ha->instance);
|
||||
qla_reverse_ini_mode(ha);
|
||||
break;
|
||||
default:
|
||||
#if defined(QL_DEBUG_LEVEL_9) || defined(QL_DEBUG_LEVEL_11)
|
||||
qla_printk(KERN_ERR, ha, "%s: Requested action not understood: "
|
||||
"%s\n", __func__, buffer);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||
qla2xxx_wake_dpc(ha);
|
||||
qla2x00_wait_for_hba_online(ha);
|
||||
|
||||
out:
|
||||
return size;
|
||||
|
||||
out_unlock:
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
goto out;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(ini_mode_force_reverse,
|
||||
S_IRUGO|S_IWUSR,
|
||||
qla2x00_show_ini_mode_force_reverse,
|
||||
qla2x00_store_ini_mode_force_reverse);
|
||||
|
||||
static ssize_t
|
||||
qla2x00_show_resource_counts(struct device *dev,
|
||||
struct device_attribute *attr, char *buffer)
|
||||
@@ -1338,6 +1407,7 @@ struct device_attribute *qla2x00_host_attrs[] = {
|
||||
&dev_attr_target_mode_enabled,
|
||||
&dev_attr_explicit_conform_enabled,
|
||||
#endif
|
||||
&dev_attr_ini_mode_force_reverse,
|
||||
&dev_attr_resource_counts,
|
||||
&dev_attr_port_database,
|
||||
#endif
|
||||
|
||||
@@ -2352,6 +2352,7 @@ typedef struct scsi_qla_host {
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
|
||||
unsigned int enable_explicit_conf :1;
|
||||
unsigned int host_shutting_down :1;
|
||||
unsigned int ini_mode_force_reverse :1;
|
||||
|
||||
dma_addr_t atio_dma; /* Physical address. */
|
||||
atio_t *atio_ring; /* Base virtual address */
|
||||
|
||||
@@ -546,11 +546,10 @@ qla2x00_rff_id(scsi_qla_host_t *ha)
|
||||
* FC-4 Feature bit 0 indicates target functionality to the name server.
|
||||
*/
|
||||
if (qla_tgt_mode_enabled(ha)) {
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET_DISABLE_INI_MODE
|
||||
ct_req->req.rff_id.fc4_feature = BIT_0;
|
||||
#else
|
||||
ct_req->req.rff_id.fc4_feature = BIT_0 | BIT_1;
|
||||
#endif
|
||||
if (qla_ini_mode_enabled(ha))
|
||||
ct_req->req.rff_id.fc4_feature = BIT_0 | BIT_1;
|
||||
else
|
||||
ct_req->req.rff_id.fc4_feature = BIT_0;
|
||||
} else
|
||||
#endif
|
||||
ct_req->req.rff_id.fc4_feature = BIT_1;
|
||||
|
||||
@@ -1754,9 +1754,10 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
|
||||
|
||||
/* Enable target mode */
|
||||
nv->firmware_options[0] |= BIT_4;
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET_DISABLE_INI_MODE
|
||||
nv->firmware_options[0] |= BIT_5;
|
||||
#endif
|
||||
|
||||
/* Disable ini mode, if requested */
|
||||
if (!qla_ini_mode_enabled(ha))
|
||||
nv->firmware_options[0] |= BIT_5;
|
||||
|
||||
/* Disable Full Login after LIP */
|
||||
nv->firmware_options[1] &= ~BIT_5;
|
||||
@@ -3745,9 +3746,10 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
|
||||
|
||||
/* Enable target mode */
|
||||
nv->firmware_options_1 |= __constant_cpu_to_le32(BIT_4);
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET_DISABLE_INI_MODE
|
||||
nv->firmware_options_1 |= __constant_cpu_to_le32(BIT_5);
|
||||
#endif
|
||||
|
||||
/* Disable ini mode, if requested */
|
||||
if (!qla_ini_mode_enabled(ha))
|
||||
nv->firmware_options_1 |= __constant_cpu_to_le32(BIT_5);
|
||||
|
||||
/* Disable Full Login after LIP */
|
||||
nv->firmware_options_1 &= __constant_cpu_to_le32(~BIT_13);
|
||||
|
||||
@@ -36,6 +36,18 @@ struct qla_tgt_data qla_target;
|
||||
*/
|
||||
static LIST_HEAD(qla_ha_list);
|
||||
static DEFINE_MUTEX(qla_ha_list_mutex);
|
||||
|
||||
static char *qlini_mode = QLA2X_INI_MODE_STR_EXCLUSIVE;
|
||||
module_param(qlini_mode, charp, S_IRUGO);
|
||||
MODULE_PARM_DESC(qlini_mode,
|
||||
"Determines when initiator mode will be enabled. Possible values: "
|
||||
"\"exclusive\" (default) - initiator mode will be enabled on load, "
|
||||
"disabled on enabling target mode and then on disabling target mode "
|
||||
"enabled back; "
|
||||
"\"disabled\" - initiator mode will never be enabled; "
|
||||
"\"enabled\" - initiator mode will always stay enabled.");
|
||||
|
||||
static int ql2x_ini_mode = QLA2X_INI_MODE_EXCLUSIVE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -3073,6 +3085,76 @@ static struct pci_driver qla2xxx_pci_driver = {
|
||||
.err_handler = &qla2xxx_err_handler,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
|
||||
|
||||
/* Must be called under HW lock */
|
||||
void qla_set_tgt_mode(scsi_qla_host_t *ha)
|
||||
{
|
||||
switch (ql2x_ini_mode) {
|
||||
case QLA2X_INI_MODE_DISABLED:
|
||||
case QLA2X_INI_MODE_EXCLUSIVE:
|
||||
ha->host->active_mode = MODE_TARGET;
|
||||
break;
|
||||
case QLA2X_INI_MODE_ENABLED:
|
||||
ha->host->active_mode |= MODE_TARGET;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ha->ini_mode_force_reverse)
|
||||
qla_reverse_ini_mode(ha);
|
||||
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(qla_set_tgt_mode);
|
||||
|
||||
/* Must be called under HW lock */
|
||||
void qla_clear_tgt_mode(scsi_qla_host_t *ha)
|
||||
{
|
||||
switch (ql2x_ini_mode) {
|
||||
case QLA2X_INI_MODE_DISABLED:
|
||||
ha->host->active_mode = MODE_UNKNOWN;
|
||||
break;
|
||||
case QLA2X_INI_MODE_EXCLUSIVE:
|
||||
ha->host->active_mode = MODE_INITIATOR;
|
||||
break;
|
||||
case QLA2X_INI_MODE_ENABLED:
|
||||
ha->host->active_mode &= ~MODE_TARGET;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ha->ini_mode_force_reverse)
|
||||
qla_reverse_ini_mode(ha);
|
||||
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(qla_clear_tgt_mode);
|
||||
|
||||
static bool __init qla2x00_parse_ini_mode(void)
|
||||
{
|
||||
if (strcasecmp(qlini_mode, QLA2X_INI_MODE_STR_EXCLUSIVE) == 0)
|
||||
ql2x_ini_mode = QLA2X_INI_MODE_EXCLUSIVE;
|
||||
else if (strcasecmp(qlini_mode, QLA2X_INI_MODE_STR_DISABLED) == 0)
|
||||
ql2x_ini_mode = QLA2X_INI_MODE_DISABLED;
|
||||
else if (strcasecmp(qlini_mode, QLA2X_INI_MODE_STR_ENABLED) == 0)
|
||||
ql2x_ini_mode = QLA2X_INI_MODE_ENABLED;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static inline bool qla2x00_parse_ini_mode(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* qla2x00_module_init - Module initialization.
|
||||
**/
|
||||
@@ -3100,6 +3182,11 @@ qla2x00_module_init(void)
|
||||
ql2xextended_error_logging = 1;
|
||||
#endif
|
||||
|
||||
if (!qla2x00_parse_ini_mode()) {
|
||||
printk("Wrong qlini_mode value %s\n", qlini_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Allocate cache for SRBs. */
|
||||
srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0,
|
||||
SLAB_HWCACHE_ALIGN, NULL);
|
||||
|
||||
Reference in New Issue
Block a user