mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger:
"The highlights this round include:
- Introduce configfs support for unlocked configfs_depend_item()
(krzysztof + andrezej)
- Conversion of usb-gadget target driver to new function registration
interface (andrzej + sebastian)
- Enable qla2xxx FC target mode support for Extended Logins (himansu +
giridhar)
- Enable qla2xxx FC target mode support for Exchange Offload (himansu +
giridhar)
- Add qla2xxx FC target mode irq affinity notification + selective
command queuing. (quinn + himanshu)
- Fix iscsi-target deadlock in se_node_acl configfs deletion (sagi +
nab)
- Convert se_node_acl configfs deletion + se_node_acl->queue_depth to
proper se_session->sess_kref + target_get_session() usage. (hch +
sagi + nab)
- Fix long-standing race between se_node_acl->acl_kref get and
get_initiator_node_acl() lookup. (hch + nab)
- Fix target/user block-size handling, and make sure netlink reaches
all network namespaces (sheng + andy)
Note there is an outstanding bug-fix series for remote I_T nexus port
TMR LUN_RESET has been posted and still being tested, and will likely
become post -rc1 material at this point"
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (56 commits)
scsi: qla2xxxx: avoid type mismatch in comparison
target/user: Make sure netlink would reach all network namespaces
target: Obtain se_node_acl->acl_kref during get_initiator_node_acl
target: Convert ACL change queue_depth se_session reference usage
iscsi-target: Fix potential dead-lock during node acl delete
ib_srpt: Convert acl lookup to modern get_initiator_node_acl usage
tcm_fc: Convert acl lookup to modern get_initiator_node_acl usage
tcm_fc: Wait for command completion before freeing a session
target: Fix a memory leak in target_dev_lba_map_store()
target: Support aborting tasks with a 64-bit tag
usb/gadget: Remove set-but-not-used variables
target: Remove an unused variable
target: Fix indentation in target_core_configfs.c
target/user: Allow user to set block size before enabling device
iser-target: Fix non negative ERR_PTR isert_device_get usage
target/fcoe: Add tag support to tcm_fc
qla2xxx: Check for online flag instead of active reset when transmitting responses
qla2xxx: Set all queues to 4k
qla2xxx: Disable ZIO at start time.
qla2xxx: Move atioq to a different lock to reduce lock contention
...
This commit is contained in:
commit
71e4634e00
53 changed files with 4507 additions and 2699 deletions
|
|
@ -823,6 +823,41 @@ static struct bin_attribute sysfs_reset_attr = {
|
|||
.write = qla2x00_sysfs_write_reset,
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
qla2x00_issue_logo(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
|
||||
struct device, kobj)));
|
||||
int type;
|
||||
int rval = 0;
|
||||
port_id_t did;
|
||||
|
||||
type = simple_strtol(buf, NULL, 10);
|
||||
|
||||
did.b.domain = (type & 0x00ff0000) >> 16;
|
||||
did.b.area = (type & 0x0000ff00) >> 8;
|
||||
did.b.al_pa = (type & 0x000000ff);
|
||||
|
||||
ql_log(ql_log_info, vha, 0x70e3, "portid=%02x%02x%02x done\n",
|
||||
did.b.domain, did.b.area, did.b.al_pa);
|
||||
|
||||
ql_log(ql_log_info, vha, 0x70e4, "%s: %d\n", __func__, type);
|
||||
|
||||
rval = qla24xx_els_dcmd_iocb(vha, ELS_DCMD_LOGO, did);
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct bin_attribute sysfs_issue_logo_attr = {
|
||||
.attr = {
|
||||
.name = "issue_logo",
|
||||
.mode = S_IWUSR,
|
||||
},
|
||||
.size = 0,
|
||||
.write = qla2x00_issue_logo,
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
qla2x00_sysfs_read_xgmac_stats(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
|
|
@ -937,6 +972,7 @@ static struct sysfs_entry {
|
|||
{ "vpd", &sysfs_vpd_attr, 1 },
|
||||
{ "sfp", &sysfs_sfp_attr, 1 },
|
||||
{ "reset", &sysfs_reset_attr, },
|
||||
{ "issue_logo", &sysfs_issue_logo_attr, },
|
||||
{ "xgmac_stats", &sysfs_xgmac_stats_attr, 3 },
|
||||
{ "dcbx_tlv", &sysfs_dcbx_tlv_attr, 3 },
|
||||
{ NULL },
|
||||
|
|
|
|||
|
|
@ -14,25 +14,24 @@
|
|||
* | Module Init and Probe | 0x017f | 0x0146 |
|
||||
* | | | 0x015b-0x0160 |
|
||||
* | | | 0x016e-0x0170 |
|
||||
* | Mailbox commands | 0x118d | 0x1115-0x1116 |
|
||||
* | | | 0x111a-0x111b |
|
||||
* | Mailbox commands | 0x1192 | |
|
||||
* | | | |
|
||||
* | Device Discovery | 0x2016 | 0x2020-0x2022, |
|
||||
* | | | 0x2011-0x2012, |
|
||||
* | | | 0x2099-0x20a4 |
|
||||
* | Queue Command and IO tracing | 0x3075 | 0x300b |
|
||||
* | Queue Command and IO tracing | 0x3074 | 0x300b |
|
||||
* | | | 0x3027-0x3028 |
|
||||
* | | | 0x303d-0x3041 |
|
||||
* | | | 0x302d,0x3033 |
|
||||
* | | | 0x3036,0x3038 |
|
||||
* | | | 0x303a |
|
||||
* | DPC Thread | 0x4023 | 0x4002,0x4013 |
|
||||
* | Async Events | 0x508a | 0x502b-0x502f |
|
||||
* | | | 0x5047 |
|
||||
* | Async Events | 0x5089 | 0x502b-0x502f |
|
||||
* | | | 0x5084,0x5075 |
|
||||
* | | | 0x503d,0x5044 |
|
||||
* | | | 0x507b,0x505f |
|
||||
* | Timer Routines | 0x6012 | |
|
||||
* | User Space Interactions | 0x70e2 | 0x7018,0x702e |
|
||||
* | User Space Interactions | 0x70e65 | 0x7018,0x702e |
|
||||
* | | | 0x7020,0x7024 |
|
||||
* | | | 0x7039,0x7045 |
|
||||
* | | | 0x7073-0x7075 |
|
||||
|
|
@ -60,15 +59,11 @@
|
|||
* | | | 0xb13c-0xb140 |
|
||||
* | | | 0xb149 |
|
||||
* | MultiQ | 0xc00c | |
|
||||
* | Misc | 0xd300 | 0xd016-0xd017 |
|
||||
* | | | 0xd021,0xd024 |
|
||||
* | | | 0xd025,0xd029 |
|
||||
* | | | 0xd02a,0xd02e |
|
||||
* | | | 0xd031-0xd0ff |
|
||||
* | Misc | 0xd301 | 0xd031-0xd0ff |
|
||||
* | | | 0xd101-0xd1fe |
|
||||
* | | | 0xd214-0xd2fe |
|
||||
* | Target Mode | 0xe080 | |
|
||||
* | Target Mode Management | 0xf096 | 0xf002 |
|
||||
* | Target Mode Management | 0xf09b | 0xf002 |
|
||||
* | | | 0xf046-0xf049 |
|
||||
* | Target Mode Task Management | 0x1000d | |
|
||||
* ----------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@
|
|||
#define LOOP_DOWN_TIME 255 /* 240 */
|
||||
#define LOOP_DOWN_RESET (LOOP_DOWN_TIME - 30)
|
||||
|
||||
#define DEFAULT_OUTSTANDING_COMMANDS 1024
|
||||
#define DEFAULT_OUTSTANDING_COMMANDS 4096
|
||||
#define MIN_OUTSTANDING_COMMANDS 128
|
||||
|
||||
/* ISP request and response entry counts (37-65535) */
|
||||
|
|
@ -267,11 +267,13 @@
|
|||
#define REQUEST_ENTRY_CNT_2200 2048 /* Number of request entries. */
|
||||
#define REQUEST_ENTRY_CNT_24XX 2048 /* Number of request entries. */
|
||||
#define REQUEST_ENTRY_CNT_83XX 8192 /* Number of request entries. */
|
||||
#define RESPONSE_ENTRY_CNT_83XX 4096 /* Number of response entries.*/
|
||||
#define RESPONSE_ENTRY_CNT_2100 64 /* Number of response entries.*/
|
||||
#define RESPONSE_ENTRY_CNT_2300 512 /* Number of response entries.*/
|
||||
#define RESPONSE_ENTRY_CNT_MQ 128 /* Number of response entries.*/
|
||||
#define ATIO_ENTRY_CNT_24XX 4096 /* Number of ATIO entries. */
|
||||
#define RESPONSE_ENTRY_CNT_FX00 256 /* Number of response entries.*/
|
||||
#define EXTENDED_EXCH_ENTRY_CNT 32768 /* Entries for offload case */
|
||||
|
||||
struct req_que;
|
||||
struct qla_tgt_sess;
|
||||
|
|
@ -309,6 +311,14 @@ struct srb_cmd {
|
|||
/* To identify if a srb is of T10-CRC type. @sp => srb_t pointer */
|
||||
#define IS_PROT_IO(sp) (sp->flags & SRB_CRC_CTX_DSD_VALID)
|
||||
|
||||
struct els_logo_payload {
|
||||
uint8_t opcode;
|
||||
uint8_t rsvd[3];
|
||||
uint8_t s_id[3];
|
||||
uint8_t rsvd1[1];
|
||||
uint8_t wwpn[WWN_SIZE];
|
||||
};
|
||||
|
||||
/*
|
||||
* SRB extensions.
|
||||
*/
|
||||
|
|
@ -322,6 +332,15 @@ struct srb_iocb {
|
|||
uint16_t data[2];
|
||||
} logio;
|
||||
struct {
|
||||
#define ELS_DCMD_TIMEOUT 20
|
||||
#define ELS_DCMD_LOGO 0x5
|
||||
uint32_t flags;
|
||||
uint32_t els_cmd;
|
||||
struct completion comp;
|
||||
struct els_logo_payload *els_logo_pyld;
|
||||
dma_addr_t els_logo_pyld_dma;
|
||||
} els_logo;
|
||||
struct {
|
||||
/*
|
||||
* Values for flags field below are as
|
||||
* defined in tsk_mgmt_entry struct
|
||||
|
|
@ -382,7 +401,7 @@ struct srb_iocb {
|
|||
#define SRB_FXIOCB_DCMD 10
|
||||
#define SRB_FXIOCB_BCMD 11
|
||||
#define SRB_ABT_CMD 12
|
||||
|
||||
#define SRB_ELS_DCMD 13
|
||||
|
||||
typedef struct srb {
|
||||
atomic_t ref_count;
|
||||
|
|
@ -891,6 +910,7 @@ struct mbx_cmd_32 {
|
|||
#define MBC_DISABLE_VI 0x24 /* Disable VI operation. */
|
||||
#define MBC_ENABLE_VI 0x25 /* Enable VI operation. */
|
||||
#define MBC_GET_FIRMWARE_OPTION 0x28 /* Get Firmware Options. */
|
||||
#define MBC_GET_MEM_OFFLOAD_CNTRL_STAT 0x34 /* Memory Offload ctrl/Stat*/
|
||||
#define MBC_SET_FIRMWARE_OPTION 0x38 /* Set Firmware Options. */
|
||||
#define MBC_LOOP_PORT_BYPASS 0x40 /* Loop Port Bypass. */
|
||||
#define MBC_LOOP_PORT_ENABLE 0x41 /* Loop Port Enable. */
|
||||
|
|
@ -2695,11 +2715,16 @@ struct isp_operations {
|
|||
|
||||
struct scsi_qla_host;
|
||||
|
||||
|
||||
#define QLA83XX_RSPQ_MSIX_ENTRY_NUMBER 1 /* refer to qla83xx_msix_entries */
|
||||
|
||||
struct qla_msix_entry {
|
||||
int have_irq;
|
||||
uint32_t vector;
|
||||
uint16_t entry;
|
||||
struct rsp_que *rsp;
|
||||
struct irq_affinity_notify irq_notify;
|
||||
int cpuid;
|
||||
};
|
||||
|
||||
#define WATCH_INTERVAL 1 /* number of seconds */
|
||||
|
|
@ -2910,12 +2935,15 @@ struct qlt_hw_data {
|
|||
uint32_t num_qfull_cmds_dropped;
|
||||
spinlock_t q_full_lock;
|
||||
uint32_t leak_exchg_thresh_hold;
|
||||
spinlock_t sess_lock;
|
||||
int rspq_vector_cpuid;
|
||||
spinlock_t atio_lock ____cacheline_aligned;
|
||||
};
|
||||
|
||||
#define MAX_QFULL_CMDS_ALLOC 8192
|
||||
#define Q_FULL_THRESH_HOLD_PERCENT 90
|
||||
#define Q_FULL_THRESH_HOLD(ha) \
|
||||
((ha->fw_xcb_count/100) * Q_FULL_THRESH_HOLD_PERCENT)
|
||||
((ha->cur_fw_xcb_count/100) * Q_FULL_THRESH_HOLD_PERCENT)
|
||||
|
||||
#define LEAK_EXCHG_THRESH_HOLD_PERCENT 75 /* 75 percent */
|
||||
|
||||
|
|
@ -2962,10 +2990,12 @@ struct qla_hw_data {
|
|||
uint32_t isp82xx_no_md_cap:1;
|
||||
uint32_t host_shutting_down:1;
|
||||
uint32_t idc_compl_status:1;
|
||||
|
||||
uint32_t mr_reset_hdlr_active:1;
|
||||
uint32_t mr_intr_valid:1;
|
||||
|
||||
uint32_t fawwpn_enabled:1;
|
||||
uint32_t exlogins_enabled:1;
|
||||
uint32_t exchoffld_enabled:1;
|
||||
/* 35 bits */
|
||||
} flags;
|
||||
|
||||
|
|
@ -3237,6 +3267,21 @@ struct qla_hw_data {
|
|||
void *async_pd;
|
||||
dma_addr_t async_pd_dma;
|
||||
|
||||
#define ENABLE_EXTENDED_LOGIN BIT_7
|
||||
|
||||
/* Extended Logins */
|
||||
void *exlogin_buf;
|
||||
dma_addr_t exlogin_buf_dma;
|
||||
int exlogin_size;
|
||||
|
||||
#define ENABLE_EXCHANGE_OFFLD BIT_2
|
||||
|
||||
/* Exchange Offload */
|
||||
void *exchoffld_buf;
|
||||
dma_addr_t exchoffld_buf_dma;
|
||||
int exchoffld_size;
|
||||
int exchoffld_count;
|
||||
|
||||
void *swl;
|
||||
|
||||
/* These are used by mailbox operations. */
|
||||
|
|
@ -3279,8 +3324,14 @@ struct qla_hw_data {
|
|||
#define RISC_START_ADDRESS_2100 0x1000
|
||||
#define RISC_START_ADDRESS_2300 0x800
|
||||
#define RISC_START_ADDRESS_2400 0x100000
|
||||
uint16_t fw_xcb_count;
|
||||
uint16_t fw_iocb_count;
|
||||
|
||||
uint16_t orig_fw_tgt_xcb_count;
|
||||
uint16_t cur_fw_tgt_xcb_count;
|
||||
uint16_t orig_fw_xcb_count;
|
||||
uint16_t cur_fw_xcb_count;
|
||||
uint16_t orig_fw_iocb_count;
|
||||
uint16_t cur_fw_iocb_count;
|
||||
uint16_t fw_max_fcf_count;
|
||||
|
||||
uint32_t fw_shared_ram_start;
|
||||
uint32_t fw_shared_ram_end;
|
||||
|
|
@ -3323,6 +3374,9 @@ struct qla_hw_data {
|
|||
uint32_t chain_offset;
|
||||
struct dentry *dfs_dir;
|
||||
struct dentry *dfs_fce;
|
||||
struct dentry *dfs_tgt_counters;
|
||||
struct dentry *dfs_fw_resource_cnt;
|
||||
|
||||
dma_addr_t fce_dma;
|
||||
void *fce;
|
||||
uint32_t fce_bufs;
|
||||
|
|
@ -3480,6 +3534,18 @@ struct qla_hw_data {
|
|||
int allow_cna_fw_dump;
|
||||
};
|
||||
|
||||
struct qla_tgt_counters {
|
||||
uint64_t qla_core_sbt_cmd;
|
||||
uint64_t core_qla_que_buf;
|
||||
uint64_t qla_core_ret_ctio;
|
||||
uint64_t core_qla_snd_status;
|
||||
uint64_t qla_core_ret_sta_ctio;
|
||||
uint64_t core_qla_free_cmd;
|
||||
uint64_t num_q_full_sent;
|
||||
uint64_t num_alloc_iocb_failed;
|
||||
uint64_t num_term_xchg_sent;
|
||||
};
|
||||
|
||||
/*
|
||||
* Qlogic scsi host structure
|
||||
*/
|
||||
|
|
@ -3595,6 +3661,10 @@ typedef struct scsi_qla_host {
|
|||
atomic_t generation_tick;
|
||||
/* Time when global fcport update has been scheduled */
|
||||
int total_fcport_update_gen;
|
||||
/* List of pending LOGOs, protected by tgt_mutex */
|
||||
struct list_head logo_list;
|
||||
/* List of pending PLOGI acks, protected by hw lock */
|
||||
struct list_head plogi_ack_list;
|
||||
|
||||
uint32_t vp_abort_cnt;
|
||||
|
||||
|
|
@ -3632,6 +3702,7 @@ typedef struct scsi_qla_host {
|
|||
|
||||
atomic_t vref_count;
|
||||
struct qla8044_reset_template reset_tmplt;
|
||||
struct qla_tgt_counters tgt_counters;
|
||||
} scsi_qla_host_t;
|
||||
|
||||
#define SET_VP_IDX 1
|
||||
|
|
|
|||
|
|
@ -12,6 +12,85 @@
|
|||
static struct dentry *qla2x00_dfs_root;
|
||||
static atomic_t qla2x00_dfs_root_count;
|
||||
|
||||
static int
|
||||
qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
struct scsi_qla_host *vha = s->private;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
seq_puts(s, "FW Resource count\n\n");
|
||||
seq_printf(s, "Original TGT exchg count[%d]\n",
|
||||
ha->orig_fw_tgt_xcb_count);
|
||||
seq_printf(s, "current TGT exchg count[%d]\n",
|
||||
ha->cur_fw_tgt_xcb_count);
|
||||
seq_printf(s, "original Initiator Exchange count[%d]\n",
|
||||
ha->orig_fw_xcb_count);
|
||||
seq_printf(s, "Current Initiator Exchange count[%d]\n",
|
||||
ha->cur_fw_xcb_count);
|
||||
seq_printf(s, "Original IOCB count[%d]\n", ha->orig_fw_iocb_count);
|
||||
seq_printf(s, "Current IOCB count[%d]\n", ha->cur_fw_iocb_count);
|
||||
seq_printf(s, "MAX VP count[%d]\n", ha->max_npiv_vports);
|
||||
seq_printf(s, "MAX FCF count[%d]\n", ha->fw_max_fcf_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
qla_dfs_fw_resource_cnt_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct scsi_qla_host *vha = inode->i_private;
|
||||
return single_open(file, qla_dfs_fw_resource_cnt_show, vha);
|
||||
}
|
||||
|
||||
static const struct file_operations dfs_fw_resource_cnt_ops = {
|
||||
.open = qla_dfs_fw_resource_cnt_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int
|
||||
qla_dfs_tgt_counters_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
struct scsi_qla_host *vha = s->private;
|
||||
|
||||
seq_puts(s, "Target Counters\n");
|
||||
seq_printf(s, "qla_core_sbt_cmd = %lld\n",
|
||||
vha->tgt_counters.qla_core_sbt_cmd);
|
||||
seq_printf(s, "qla_core_ret_sta_ctio = %lld\n",
|
||||
vha->tgt_counters.qla_core_ret_sta_ctio);
|
||||
seq_printf(s, "qla_core_ret_ctio = %lld\n",
|
||||
vha->tgt_counters.qla_core_ret_ctio);
|
||||
seq_printf(s, "core_qla_que_buf = %lld\n",
|
||||
vha->tgt_counters.core_qla_que_buf);
|
||||
seq_printf(s, "core_qla_snd_status = %lld\n",
|
||||
vha->tgt_counters.core_qla_snd_status);
|
||||
seq_printf(s, "core_qla_free_cmd = %lld\n",
|
||||
vha->tgt_counters.core_qla_free_cmd);
|
||||
seq_printf(s, "num alloc iocb failed = %lld\n",
|
||||
vha->tgt_counters.num_alloc_iocb_failed);
|
||||
seq_printf(s, "num term exchange sent = %lld\n",
|
||||
vha->tgt_counters.num_term_xchg_sent);
|
||||
seq_printf(s, "num Q full sent = %lld\n",
|
||||
vha->tgt_counters.num_q_full_sent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
qla_dfs_tgt_counters_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct scsi_qla_host *vha = inode->i_private;
|
||||
return single_open(file, qla_dfs_tgt_counters_show, vha);
|
||||
}
|
||||
|
||||
static const struct file_operations dfs_tgt_counters_ops = {
|
||||
.open = qla_dfs_tgt_counters_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int
|
||||
qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
|
|
@ -146,6 +225,22 @@ create_dir:
|
|||
atomic_inc(&qla2x00_dfs_root_count);
|
||||
|
||||
create_nodes:
|
||||
ha->dfs_fw_resource_cnt = debugfs_create_file("fw_resource_count",
|
||||
S_IRUSR, ha->dfs_dir, vha, &dfs_fw_resource_cnt_ops);
|
||||
if (!ha->dfs_fw_resource_cnt) {
|
||||
ql_log(ql_log_warn, vha, 0x00fd,
|
||||
"Unable to create debugFS fw_resource_count node.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ha->dfs_tgt_counters = debugfs_create_file("tgt_counters", S_IRUSR,
|
||||
ha->dfs_dir, vha, &dfs_tgt_counters_ops);
|
||||
if (!ha->dfs_tgt_counters) {
|
||||
ql_log(ql_log_warn, vha, 0xd301,
|
||||
"Unable to create debugFS tgt_counters node.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
|
||||
&dfs_fce_ops);
|
||||
if (!ha->dfs_fce) {
|
||||
|
|
@ -161,6 +256,17 @@ int
|
|||
qla2x00_dfs_remove(scsi_qla_host_t *vha)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
if (ha->dfs_fw_resource_cnt) {
|
||||
debugfs_remove(ha->dfs_fw_resource_cnt);
|
||||
ha->dfs_fw_resource_cnt = NULL;
|
||||
}
|
||||
|
||||
if (ha->dfs_tgt_counters) {
|
||||
debugfs_remove(ha->dfs_tgt_counters);
|
||||
ha->dfs_tgt_counters = NULL;
|
||||
}
|
||||
|
||||
if (ha->dfs_fce) {
|
||||
debugfs_remove(ha->dfs_fce);
|
||||
ha->dfs_fce = NULL;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *);
|
|||
extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
|
||||
extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
|
||||
|
||||
extern int qla24xx_els_dcmd_iocb(scsi_qla_host_t *, int, port_id_t);
|
||||
|
||||
extern void qla2x00_update_fcports(scsi_qla_host_t *);
|
||||
|
||||
extern int qla2x00_abort_isp(scsi_qla_host_t *);
|
||||
|
|
@ -117,6 +119,8 @@ extern int ql2xdontresethba;
|
|||
extern uint64_t ql2xmaxlun;
|
||||
extern int ql2xmdcapmask;
|
||||
extern int ql2xmdenable;
|
||||
extern int ql2xexlogins;
|
||||
extern int ql2xexchoffld;
|
||||
|
||||
extern int qla2x00_loop_reset(scsi_qla_host_t *);
|
||||
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
|
||||
|
|
@ -135,6 +139,10 @@ extern int qla2x00_post_async_adisc_work(struct scsi_qla_host *, fc_port_t *,
|
|||
uint16_t *);
|
||||
extern int qla2x00_post_async_adisc_done_work(struct scsi_qla_host *,
|
||||
fc_port_t *, uint16_t *);
|
||||
extern int qla2x00_set_exlogins_buffer(struct scsi_qla_host *);
|
||||
extern void qla2x00_free_exlogin_buffer(struct qla_hw_data *);
|
||||
extern int qla2x00_set_exchoffld_buffer(struct scsi_qla_host *);
|
||||
extern void qla2x00_free_exchoffld_buffer(struct qla_hw_data *);
|
||||
|
||||
extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
|
||||
|
||||
|
|
@ -323,8 +331,7 @@ extern int
|
|||
qla2x00_get_id_list(scsi_qla_host_t *, void *, dma_addr_t, uint16_t *);
|
||||
|
||||
extern int
|
||||
qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *,
|
||||
uint16_t *, uint16_t *, uint16_t *, uint16_t *);
|
||||
qla2x00_get_resource_cnts(scsi_qla_host_t *);
|
||||
|
||||
extern int
|
||||
qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map);
|
||||
|
|
@ -766,4 +773,11 @@ extern int qla8044_abort_isp(scsi_qla_host_t *);
|
|||
extern int qla8044_check_fw_alive(struct scsi_qla_host *);
|
||||
|
||||
extern void qlt_host_reset_handler(struct qla_hw_data *ha);
|
||||
extern int qla_get_exlogin_status(scsi_qla_host_t *, uint16_t *,
|
||||
uint16_t *);
|
||||
extern int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr);
|
||||
extern int qla_get_exchoffld_status(scsi_qla_host_t *, uint16_t *, uint16_t *);
|
||||
extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *, dma_addr_t);
|
||||
extern void qlt_handle_abts_recv(struct scsi_qla_host *, response_t *);
|
||||
|
||||
#endif /* _QLA_GBL_H */
|
||||
|
|
|
|||
|
|
@ -1766,10 +1766,10 @@ qla2x00_alloc_outstanding_cmds(struct qla_hw_data *ha, struct req_que *req)
|
|||
(ql2xmultique_tag || ql2xmaxqueues > 1)))
|
||||
req->num_outstanding_cmds = DEFAULT_OUTSTANDING_COMMANDS;
|
||||
else {
|
||||
if (ha->fw_xcb_count <= ha->fw_iocb_count)
|
||||
req->num_outstanding_cmds = ha->fw_xcb_count;
|
||||
if (ha->cur_fw_xcb_count <= ha->cur_fw_iocb_count)
|
||||
req->num_outstanding_cmds = ha->cur_fw_xcb_count;
|
||||
else
|
||||
req->num_outstanding_cmds = ha->fw_iocb_count;
|
||||
req->num_outstanding_cmds = ha->cur_fw_iocb_count;
|
||||
}
|
||||
|
||||
req->outstanding_cmds = kzalloc(sizeof(srb_t *) *
|
||||
|
|
@ -1843,9 +1843,23 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
|
|||
ql_dbg(ql_dbg_init, vha, 0x00ca,
|
||||
"Starting firmware.\n");
|
||||
|
||||
if (ql2xexlogins)
|
||||
ha->flags.exlogins_enabled = 1;
|
||||
|
||||
if (ql2xexchoffld)
|
||||
ha->flags.exchoffld_enabled = 1;
|
||||
|
||||
rval = qla2x00_execute_fw(vha, srisc_address);
|
||||
/* Retrieve firmware information. */
|
||||
if (rval == QLA_SUCCESS) {
|
||||
rval = qla2x00_set_exlogins_buffer(vha);
|
||||
if (rval != QLA_SUCCESS)
|
||||
goto failed;
|
||||
|
||||
rval = qla2x00_set_exchoffld_buffer(vha);
|
||||
if (rval != QLA_SUCCESS)
|
||||
goto failed;
|
||||
|
||||
enable_82xx_npiv:
|
||||
fw_major_version = ha->fw_major_version;
|
||||
if (IS_P3P_TYPE(ha))
|
||||
|
|
@ -1864,9 +1878,7 @@ enable_82xx_npiv:
|
|||
ha->max_npiv_vports =
|
||||
MIN_MULTI_ID_FABRIC - 1;
|
||||
}
|
||||
qla2x00_get_resource_cnts(vha, NULL,
|
||||
&ha->fw_xcb_count, NULL, &ha->fw_iocb_count,
|
||||
&ha->max_npiv_vports, NULL);
|
||||
qla2x00_get_resource_cnts(vha);
|
||||
|
||||
/*
|
||||
* Allocate the array of outstanding commands
|
||||
|
|
@ -2248,7 +2260,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
|
|||
if (IS_FWI2_CAPABLE(ha)) {
|
||||
mid_init_cb->options = cpu_to_le16(BIT_1);
|
||||
mid_init_cb->init_cb.execution_throttle =
|
||||
cpu_to_le16(ha->fw_xcb_count);
|
||||
cpu_to_le16(ha->cur_fw_xcb_count);
|
||||
/* D-Port Status */
|
||||
if (IS_DPORT_CAPABLE(ha))
|
||||
mid_init_cb->init_cb.firmware_options_1 |=
|
||||
|
|
@ -3053,6 +3065,26 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
|
|||
atomic_set(&vha->loop_state, LOOP_READY);
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2069,
|
||||
"LOOP READY.\n");
|
||||
|
||||
/*
|
||||
* Process any ATIO queue entries that came in
|
||||
* while we weren't online.
|
||||
*/
|
||||
if (qla_tgt_mode_enabled(vha)) {
|
||||
if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) {
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock,
|
||||
flags);
|
||||
qlt_24xx_process_atio_queue(vha, 0);
|
||||
spin_unlock_irqrestore(
|
||||
&ha->tgt.atio_lock, flags);
|
||||
} else {
|
||||
spin_lock_irqsave(&ha->hardware_lock,
|
||||
flags);
|
||||
qlt_24xx_process_atio_queue(vha, 1);
|
||||
spin_unlock_irqrestore(
|
||||
&ha->hardware_lock, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4907,7 +4939,6 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
|
|||
struct qla_hw_data *ha = vha->hw;
|
||||
struct req_que *req = ha->req_q_map[0];
|
||||
struct rsp_que *rsp = ha->rsp_q_map[0];
|
||||
unsigned long flags;
|
||||
|
||||
/* If firmware needs to be loaded */
|
||||
if (qla2x00_isp_firmware(vha)) {
|
||||
|
|
@ -4929,17 +4960,6 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
|
|||
/* Issue a marker after FW becomes ready. */
|
||||
qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
|
||||
|
||||
vha->flags.online = 1;
|
||||
|
||||
/*
|
||||
* Process any ATIO queue entries that came in
|
||||
* while we weren't online.
|
||||
*/
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
if (qla_tgt_mode_enabled(vha))
|
||||
qlt_24xx_process_atio_queue(vha);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -258,6 +258,8 @@ qla2x00_init_timer(srb_t *sp, unsigned long tmo)
|
|||
if ((IS_QLAFX00(sp->fcport->vha->hw)) &&
|
||||
(sp->type == SRB_FXIOCB_DCMD))
|
||||
init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
|
||||
if (sp->type == SRB_ELS_DCMD)
|
||||
init_completion(&sp->u.iocb_cmd.u.els_logo.comp);
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
|
|
|||
|
|
@ -1868,6 +1868,7 @@ skip_cmd_array:
|
|||
}
|
||||
|
||||
queuing_error:
|
||||
vha->tgt_counters.num_alloc_iocb_failed++;
|
||||
return pkt;
|
||||
}
|
||||
|
||||
|
|
@ -2009,6 +2010,190 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qla2x00_els_dcmd_sp_free(void *ptr, void *data)
|
||||
{
|
||||
struct scsi_qla_host *vha = (scsi_qla_host_t *)ptr;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
srb_t *sp = (srb_t *)data;
|
||||
struct srb_iocb *elsio = &sp->u.iocb_cmd;
|
||||
|
||||
kfree(sp->fcport);
|
||||
|
||||
if (elsio->u.els_logo.els_logo_pyld)
|
||||
dma_free_coherent(&ha->pdev->dev, DMA_POOL_SIZE,
|
||||
elsio->u.els_logo.els_logo_pyld,
|
||||
elsio->u.els_logo.els_logo_pyld_dma);
|
||||
|
||||
del_timer(&elsio->timer);
|
||||
qla2x00_rel_sp(vha, sp);
|
||||
}
|
||||
|
||||
static void
|
||||
qla2x00_els_dcmd_iocb_timeout(void *data)
|
||||
{
|
||||
srb_t *sp = (srb_t *)data;
|
||||
struct srb_iocb *lio = &sp->u.iocb_cmd;
|
||||
fc_port_t *fcport = sp->fcport;
|
||||
struct scsi_qla_host *vha = fcport->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
unsigned long flags = 0;
|
||||
|
||||
ql_dbg(ql_dbg_io, vha, 0x3069,
|
||||
"%s Timeout, hdl=%x, portid=%02x%02x%02x\n",
|
||||
sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area,
|
||||
fcport->d_id.b.al_pa);
|
||||
|
||||
/* Abort the exchange */
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
if (ha->isp_ops->abort_command(sp)) {
|
||||
ql_dbg(ql_dbg_io, vha, 0x3070,
|
||||
"mbx abort_command failed.\n");
|
||||
} else {
|
||||
ql_dbg(ql_dbg_io, vha, 0x3071,
|
||||
"mbx abort_command success.\n");
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
complete(&lio->u.els_logo.comp);
|
||||
}
|
||||
|
||||
static void
|
||||
qla2x00_els_dcmd_sp_done(void *data, void *ptr, int res)
|
||||
{
|
||||
srb_t *sp = (srb_t *)ptr;
|
||||
fc_port_t *fcport = sp->fcport;
|
||||
struct srb_iocb *lio = &sp->u.iocb_cmd;
|
||||
struct scsi_qla_host *vha = fcport->vha;
|
||||
|
||||
ql_dbg(ql_dbg_io, vha, 0x3072,
|
||||
"%s hdl=%x, portid=%02x%02x%02x done\n",
|
||||
sp->name, sp->handle, fcport->d_id.b.domain,
|
||||
fcport->d_id.b.area, fcport->d_id.b.al_pa);
|
||||
|
||||
complete(&lio->u.els_logo.comp);
|
||||
}
|
||||
|
||||
int
|
||||
qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
|
||||
port_id_t remote_did)
|
||||
{
|
||||
srb_t *sp;
|
||||
fc_port_t *fcport = NULL;
|
||||
struct srb_iocb *elsio = NULL;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct els_logo_payload logo_pyld;
|
||||
int rval = QLA_SUCCESS;
|
||||
|
||||
fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
|
||||
if (!fcport) {
|
||||
ql_log(ql_log_info, vha, 0x70e5, "fcport allocation failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Alloc SRB structure */
|
||||
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
|
||||
if (!sp) {
|
||||
kfree(fcport);
|
||||
ql_log(ql_log_info, vha, 0x70e6,
|
||||
"SRB allocation failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
elsio = &sp->u.iocb_cmd;
|
||||
fcport->loop_id = 0xFFFF;
|
||||
fcport->d_id.b.domain = remote_did.b.domain;
|
||||
fcport->d_id.b.area = remote_did.b.area;
|
||||
fcport->d_id.b.al_pa = remote_did.b.al_pa;
|
||||
|
||||
ql_dbg(ql_dbg_io, vha, 0x3073, "portid=%02x%02x%02x done\n",
|
||||
fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);
|
||||
|
||||
sp->type = SRB_ELS_DCMD;
|
||||
sp->name = "ELS_DCMD";
|
||||
sp->fcport = fcport;
|
||||
qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
|
||||
elsio->timeout = qla2x00_els_dcmd_iocb_timeout;
|
||||
sp->done = qla2x00_els_dcmd_sp_done;
|
||||
sp->free = qla2x00_els_dcmd_sp_free;
|
||||
|
||||
elsio->u.els_logo.els_logo_pyld = dma_alloc_coherent(&ha->pdev->dev,
|
||||
DMA_POOL_SIZE, &elsio->u.els_logo.els_logo_pyld_dma,
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!elsio->u.els_logo.els_logo_pyld) {
|
||||
sp->free(vha, sp);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
memset(&logo_pyld, 0, sizeof(struct els_logo_payload));
|
||||
|
||||
elsio->u.els_logo.els_cmd = els_opcode;
|
||||
logo_pyld.opcode = els_opcode;
|
||||
logo_pyld.s_id[0] = vha->d_id.b.al_pa;
|
||||
logo_pyld.s_id[1] = vha->d_id.b.area;
|
||||
logo_pyld.s_id[2] = vha->d_id.b.domain;
|
||||
host_to_fcp_swap(logo_pyld.s_id, sizeof(uint32_t));
|
||||
memcpy(&logo_pyld.wwpn, vha->port_name, WWN_SIZE);
|
||||
|
||||
memcpy(elsio->u.els_logo.els_logo_pyld, &logo_pyld,
|
||||
sizeof(struct els_logo_payload));
|
||||
|
||||
rval = qla2x00_start_sp(sp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
sp->free(vha, sp);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
ql_dbg(ql_dbg_io, vha, 0x3074,
|
||||
"%s LOGO sent, hdl=%x, loopid=%x, portid=%02x%02x%02x.\n",
|
||||
sp->name, sp->handle, fcport->loop_id, fcport->d_id.b.domain,
|
||||
fcport->d_id.b.area, fcport->d_id.b.al_pa);
|
||||
|
||||
wait_for_completion(&elsio->u.els_logo.comp);
|
||||
|
||||
sp->free(vha, sp);
|
||||
return rval;
|
||||
}
|
||||
|
||||
static void
|
||||
qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
|
||||
{
|
||||
scsi_qla_host_t *vha = sp->fcport->vha;
|
||||
struct srb_iocb *elsio = &sp->u.iocb_cmd;
|
||||
|
||||
els_iocb->entry_type = ELS_IOCB_TYPE;
|
||||
els_iocb->entry_count = 1;
|
||||
els_iocb->sys_define = 0;
|
||||
els_iocb->entry_status = 0;
|
||||
els_iocb->handle = sp->handle;
|
||||
els_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
|
||||
els_iocb->tx_dsd_count = 1;
|
||||
els_iocb->vp_index = vha->vp_idx;
|
||||
els_iocb->sof_type = EST_SOFI3;
|
||||
els_iocb->rx_dsd_count = 0;
|
||||
els_iocb->opcode = elsio->u.els_logo.els_cmd;
|
||||
|
||||
els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
|
||||
els_iocb->port_id[1] = sp->fcport->d_id.b.area;
|
||||
els_iocb->port_id[2] = sp->fcport->d_id.b.domain;
|
||||
els_iocb->control_flags = 0;
|
||||
|
||||
els_iocb->tx_byte_count = sizeof(struct els_logo_payload);
|
||||
els_iocb->tx_address[0] =
|
||||
cpu_to_le32(LSD(elsio->u.els_logo.els_logo_pyld_dma));
|
||||
els_iocb->tx_address[1] =
|
||||
cpu_to_le32(MSD(elsio->u.els_logo.els_logo_pyld_dma));
|
||||
els_iocb->tx_len = cpu_to_le32(sizeof(struct els_logo_payload));
|
||||
|
||||
els_iocb->rx_byte_count = 0;
|
||||
els_iocb->rx_address[0] = 0;
|
||||
els_iocb->rx_address[1] = 0;
|
||||
els_iocb->rx_len = 0;
|
||||
|
||||
sp->fcport->vha->qla_stats.control_requests++;
|
||||
}
|
||||
|
||||
static void
|
||||
qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
|
||||
{
|
||||
|
|
@ -2623,6 +2808,9 @@ qla2x00_start_sp(srb_t *sp)
|
|||
qlafx00_abort_iocb(sp, pkt) :
|
||||
qla24xx_abort_iocb(sp, pkt);
|
||||
break;
|
||||
case SRB_ELS_DCMD:
|
||||
qla24xx_els_logo_iocb(sp, pkt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
|
|||
static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *);
|
||||
static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
|
||||
sts_entry_t *);
|
||||
static void qla_irq_affinity_notify(struct irq_affinity_notify *,
|
||||
const cpumask_t *);
|
||||
static void qla_irq_affinity_release(struct kref *);
|
||||
|
||||
|
||||
/**
|
||||
* qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
|
||||
|
|
@ -1418,6 +1422,12 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|||
case SRB_CT_CMD:
|
||||
type = "ct pass-through";
|
||||
break;
|
||||
case SRB_ELS_DCMD:
|
||||
type = "Driver ELS logo";
|
||||
ql_dbg(ql_dbg_user, vha, 0x5047,
|
||||
"Completing %s: (%p) type=%d.\n", type, sp, sp->type);
|
||||
sp->done(vha, sp, 0);
|
||||
return;
|
||||
default:
|
||||
ql_dbg(ql_dbg_user, vha, 0x503e,
|
||||
"Unrecognized SRB: (%p) type=%d.\n", sp, sp->type);
|
||||
|
|
@ -2542,6 +2552,14 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
|
|||
if (!vha->flags.online)
|
||||
return;
|
||||
|
||||
if (rsp->msix->cpuid != smp_processor_id()) {
|
||||
/* if kernel does not notify qla of IRQ's CPU change,
|
||||
* then set it here.
|
||||
*/
|
||||
rsp->msix->cpuid = smp_processor_id();
|
||||
ha->tgt.rspq_vector_cpuid = rsp->msix->cpuid;
|
||||
}
|
||||
|
||||
while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
|
||||
pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
|
||||
|
||||
|
|
@ -2587,8 +2605,14 @@ process_err:
|
|||
qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
|
||||
break;
|
||||
case ABTS_RECV_24XX:
|
||||
/* ensure that the ATIO queue is empty */
|
||||
qlt_24xx_process_atio_queue(vha);
|
||||
if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
|
||||
/* ensure that the ATIO queue is empty */
|
||||
qlt_handle_abts_recv(vha, (response_t *)pkt);
|
||||
break;
|
||||
} else {
|
||||
/* drop through */
|
||||
qlt_24xx_process_atio_queue(vha, 1);
|
||||
}
|
||||
case ABTS_RESP_24XX:
|
||||
case CTIO_TYPE7:
|
||||
case NOTIFY_ACK_TYPE:
|
||||
|
|
@ -2755,13 +2779,22 @@ qla24xx_intr_handler(int irq, void *dev_id)
|
|||
case INTR_RSP_QUE_UPDATE_83XX:
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
break;
|
||||
case INTR_ATIO_QUE_UPDATE:
|
||||
qlt_24xx_process_atio_queue(vha);
|
||||
case INTR_ATIO_QUE_UPDATE:{
|
||||
unsigned long flags2;
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
|
||||
qlt_24xx_process_atio_queue(vha, 1);
|
||||
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
|
||||
break;
|
||||
case INTR_ATIO_RSP_QUE_UPDATE:
|
||||
qlt_24xx_process_atio_queue(vha);
|
||||
}
|
||||
case INTR_ATIO_RSP_QUE_UPDATE: {
|
||||
unsigned long flags2;
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
|
||||
qlt_24xx_process_atio_queue(vha, 1);
|
||||
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
|
||||
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ql_dbg(ql_dbg_async, vha, 0x504f,
|
||||
"Unrecognized interrupt type (%d).\n", stat * 0xff);
|
||||
|
|
@ -2920,13 +2953,22 @@ qla24xx_msix_default(int irq, void *dev_id)
|
|||
case INTR_RSP_QUE_UPDATE_83XX:
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
break;
|
||||
case INTR_ATIO_QUE_UPDATE:
|
||||
qlt_24xx_process_atio_queue(vha);
|
||||
case INTR_ATIO_QUE_UPDATE:{
|
||||
unsigned long flags2;
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
|
||||
qlt_24xx_process_atio_queue(vha, 1);
|
||||
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
|
||||
break;
|
||||
case INTR_ATIO_RSP_QUE_UPDATE:
|
||||
qlt_24xx_process_atio_queue(vha);
|
||||
}
|
||||
case INTR_ATIO_RSP_QUE_UPDATE: {
|
||||
unsigned long flags2;
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
|
||||
qlt_24xx_process_atio_queue(vha, 1);
|
||||
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
|
||||
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ql_dbg(ql_dbg_async, vha, 0x5051,
|
||||
"Unrecognized interrupt type (%d).\n", stat & 0xff);
|
||||
|
|
@ -2973,8 +3015,11 @@ qla24xx_disable_msix(struct qla_hw_data *ha)
|
|||
|
||||
for (i = 0; i < ha->msix_count; i++) {
|
||||
qentry = &ha->msix_entries[i];
|
||||
if (qentry->have_irq)
|
||||
if (qentry->have_irq) {
|
||||
/* un-register irq cpu affinity notification */
|
||||
irq_set_affinity_notifier(qentry->vector, NULL);
|
||||
free_irq(qentry->vector, qentry->rsp);
|
||||
}
|
||||
}
|
||||
pci_disable_msix(ha->pdev);
|
||||
kfree(ha->msix_entries);
|
||||
|
|
@ -3037,6 +3082,9 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
|
|||
qentry->entry = entries[i].entry;
|
||||
qentry->have_irq = 0;
|
||||
qentry->rsp = NULL;
|
||||
qentry->irq_notify.notify = qla_irq_affinity_notify;
|
||||
qentry->irq_notify.release = qla_irq_affinity_release;
|
||||
qentry->cpuid = -1;
|
||||
}
|
||||
|
||||
/* Enable MSI-X vectors for the base queue */
|
||||
|
|
@ -3055,6 +3103,18 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
|
|||
qentry->have_irq = 1;
|
||||
qentry->rsp = rsp;
|
||||
rsp->msix = qentry;
|
||||
|
||||
/* Register for CPU affinity notification. */
|
||||
irq_set_affinity_notifier(qentry->vector, &qentry->irq_notify);
|
||||
|
||||
/* Schedule work (ie. trigger a notification) to read cpu
|
||||
* mask for this specific irq.
|
||||
* kref_get is required because
|
||||
* irq_affinity_notify() will do
|
||||
* kref_put().
|
||||
*/
|
||||
kref_get(&qentry->irq_notify.kref);
|
||||
schedule_work(&qentry->irq_notify.work);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3234,3 +3294,47 @@ int qla25xx_request_irq(struct rsp_que *rsp)
|
|||
msix->rsp = rsp;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* irq_set_affinity/irqbalance will trigger notification of cpu mask update */
|
||||
static void qla_irq_affinity_notify(struct irq_affinity_notify *notify,
|
||||
const cpumask_t *mask)
|
||||
{
|
||||
struct qla_msix_entry *e =
|
||||
container_of(notify, struct qla_msix_entry, irq_notify);
|
||||
struct qla_hw_data *ha;
|
||||
struct scsi_qla_host *base_vha;
|
||||
|
||||
/* user is recommended to set mask to just 1 cpu */
|
||||
e->cpuid = cpumask_first(mask);
|
||||
|
||||
ha = e->rsp->hw;
|
||||
base_vha = pci_get_drvdata(ha->pdev);
|
||||
|
||||
ql_dbg(ql_dbg_init, base_vha, 0xffff,
|
||||
"%s: host %ld : vector %d cpu %d \n", __func__,
|
||||
base_vha->host_no, e->vector, e->cpuid);
|
||||
|
||||
if (e->have_irq) {
|
||||
if ((IS_QLA83XX(ha) || IS_QLA27XX(ha)) &&
|
||||
(e->entry == QLA83XX_RSPQ_MSIX_ENTRY_NUMBER)) {
|
||||
ha->tgt.rspq_vector_cpuid = e->cpuid;
|
||||
ql_dbg(ql_dbg_init, base_vha, 0xffff,
|
||||
"%s: host%ld: rspq vector %d cpu %d runtime change\n",
|
||||
__func__, base_vha->host_no, e->vector, e->cpuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void qla_irq_affinity_release(struct kref *ref)
|
||||
{
|
||||
struct irq_affinity_notify *notify =
|
||||
container_of(ref, struct irq_affinity_notify, kref);
|
||||
struct qla_msix_entry *e =
|
||||
container_of(notify, struct qla_msix_entry, irq_notify);
|
||||
struct scsi_qla_host *base_vha = pci_get_drvdata(e->rsp->hw->pdev);
|
||||
|
||||
ql_dbg(ql_dbg_init, base_vha, 0xffff,
|
||||
"%s: host%ld: vector %d cpu %d \n", __func__,
|
||||
base_vha->host_no, e->vector, e->cpuid);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -489,6 +489,13 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
|
|||
EXTENDED_BB_CREDITS);
|
||||
} else
|
||||
mcp->mb[4] = 0;
|
||||
|
||||
if (ha->flags.exlogins_enabled)
|
||||
mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;
|
||||
|
||||
if (ha->flags.exchoffld_enabled)
|
||||
mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;
|
||||
|
||||
mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
|
||||
mcp->in_mb |= MBX_1;
|
||||
} else {
|
||||
|
|
@ -520,6 +527,226 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
|
|||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* qla_get_exlogin_status
|
||||
* Get extended login status
|
||||
* uses the memory offload control/status Mailbox
|
||||
*
|
||||
* Input:
|
||||
* ha: adapter state pointer.
|
||||
* fwopt: firmware options
|
||||
*
|
||||
* Returns:
|
||||
* qla2x00 local function status
|
||||
*
|
||||
* Context:
|
||||
* Kernel context.
|
||||
*/
|
||||
#define FETCH_XLOGINS_STAT 0x8
|
||||
int
|
||||
qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
|
||||
uint16_t *ex_logins_cnt)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118f,
|
||||
"Entered %s\n", __func__);
|
||||
|
||||
memset(mcp->mb, 0 , sizeof(mcp->mb));
|
||||
mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
|
||||
mcp->mb[1] = FETCH_XLOGINS_STAT;
|
||||
mcp->out_mb = MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_10|MBX_4|MBX_0;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x1115, "Failed=%x.\n", rval);
|
||||
} else {
|
||||
*buf_sz = mcp->mb[4];
|
||||
*ex_logins_cnt = mcp->mb[10];
|
||||
|
||||
ql_log(ql_log_info, vha, 0x1190,
|
||||
"buffer size 0x%x, exchange login count=%d\n",
|
||||
mcp->mb[4], mcp->mb[10]);
|
||||
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1116,
|
||||
"Done %s.\n", __func__);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* qla_set_exlogin_mem_cfg
|
||||
* set extended login memory configuration
|
||||
* Mbx needs to be issues before init_cb is set
|
||||
*
|
||||
* Input:
|
||||
* ha: adapter state pointer.
|
||||
* buffer: buffer pointer
|
||||
* phys_addr: physical address of buffer
|
||||
* size: size of buffer
|
||||
* TARGET_QUEUE_LOCK must be released
|
||||
* ADAPTER_STATE_LOCK must be release
|
||||
*
|
||||
* Returns:
|
||||
* qla2x00 local funxtion status code.
|
||||
*
|
||||
* Context:
|
||||
* Kernel context.
|
||||
*/
|
||||
#define CONFIG_XLOGINS_MEM 0x3
|
||||
int
|
||||
qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
int configured_count;
|
||||
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111a,
|
||||
"Entered %s.\n", __func__);
|
||||
|
||||
memset(mcp->mb, 0 , sizeof(mcp->mb));
|
||||
mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
|
||||
mcp->mb[1] = CONFIG_XLOGINS_MEM;
|
||||
mcp->mb[2] = MSW(phys_addr);
|
||||
mcp->mb[3] = LSW(phys_addr);
|
||||
mcp->mb[6] = MSW(MSD(phys_addr));
|
||||
mcp->mb[7] = LSW(MSD(phys_addr));
|
||||
mcp->mb[8] = MSW(ha->exlogin_size);
|
||||
mcp->mb[9] = LSW(ha->exlogin_size);
|
||||
mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_11|MBX_0;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x111b, "Failed=%x.\n", rval);
|
||||
} else {
|
||||
configured_count = mcp->mb[11];
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,
|
||||
"Done %s.\n", __func__);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* qla_get_exchoffld_status
|
||||
* Get exchange offload status
|
||||
* uses the memory offload control/status Mailbox
|
||||
*
|
||||
* Input:
|
||||
* ha: adapter state pointer.
|
||||
* fwopt: firmware options
|
||||
*
|
||||
* Returns:
|
||||
* qla2x00 local function status
|
||||
*
|
||||
* Context:
|
||||
* Kernel context.
|
||||
*/
|
||||
#define FETCH_XCHOFFLD_STAT 0x2
|
||||
int
|
||||
qla_get_exchoffld_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
|
||||
uint16_t *ex_logins_cnt)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1019,
|
||||
"Entered %s\n", __func__);
|
||||
|
||||
memset(mcp->mb, 0 , sizeof(mcp->mb));
|
||||
mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
|
||||
mcp->mb[1] = FETCH_XCHOFFLD_STAT;
|
||||
mcp->out_mb = MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_10|MBX_4|MBX_0;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x1155, "Failed=%x.\n", rval);
|
||||
} else {
|
||||
*buf_sz = mcp->mb[4];
|
||||
*ex_logins_cnt = mcp->mb[10];
|
||||
|
||||
ql_log(ql_log_info, vha, 0x118e,
|
||||
"buffer size 0x%x, exchange offload count=%d\n",
|
||||
mcp->mb[4], mcp->mb[10]);
|
||||
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1156,
|
||||
"Done %s.\n", __func__);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* qla_set_exchoffld_mem_cfg
|
||||
* Set exchange offload memory configuration
|
||||
* Mbx needs to be issues before init_cb is set
|
||||
*
|
||||
* Input:
|
||||
* ha: adapter state pointer.
|
||||
* buffer: buffer pointer
|
||||
* phys_addr: physical address of buffer
|
||||
* size: size of buffer
|
||||
* TARGET_QUEUE_LOCK must be released
|
||||
* ADAPTER_STATE_LOCK must be release
|
||||
*
|
||||
* Returns:
|
||||
* qla2x00 local funxtion status code.
|
||||
*
|
||||
* Context:
|
||||
* Kernel context.
|
||||
*/
|
||||
#define CONFIG_XCHOFFLD_MEM 0x3
|
||||
int
|
||||
qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1157,
|
||||
"Entered %s.\n", __func__);
|
||||
|
||||
memset(mcp->mb, 0 , sizeof(mcp->mb));
|
||||
mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
|
||||
mcp->mb[1] = CONFIG_XCHOFFLD_MEM;
|
||||
mcp->mb[2] = MSW(phys_addr);
|
||||
mcp->mb[3] = LSW(phys_addr);
|
||||
mcp->mb[6] = MSW(MSD(phys_addr));
|
||||
mcp->mb[7] = LSW(MSD(phys_addr));
|
||||
mcp->mb[8] = MSW(ha->exlogin_size);
|
||||
mcp->mb[9] = LSW(ha->exlogin_size);
|
||||
mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_11|MBX_0;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x1158, "Failed=%x.\n", rval);
|
||||
} else {
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192,
|
||||
"Done %s.\n", __func__);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* qla2x00_get_fw_version
|
||||
* Get firmware version.
|
||||
|
|
@ -594,6 +821,16 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
|
|||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
|
||||
"%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
|
||||
__func__, mcp->mb[17], mcp->mb[16]);
|
||||
|
||||
if (ha->fw_attributes_h & 0x4)
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118d,
|
||||
"%s: Firmware supports Extended Login 0x%x\n",
|
||||
__func__, ha->fw_attributes_h);
|
||||
|
||||
if (ha->fw_attributes_h & 0x8)
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1191,
|
||||
"%s: Firmware supports Exchange Offload 0x%x\n",
|
||||
__func__, ha->fw_attributes_h);
|
||||
}
|
||||
|
||||
if (IS_QLA27XX(ha)) {
|
||||
|
|
@ -2383,10 +2620,9 @@ qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
|
|||
* Kernel context.
|
||||
*/
|
||||
int
|
||||
qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
|
||||
uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
|
||||
uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
|
||||
qla2x00_get_resource_cnts(scsi_qla_host_t *vha)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
|
@ -2414,19 +2650,16 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
|
|||
mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
|
||||
mcp->mb[11], mcp->mb[12]);
|
||||
|
||||
if (cur_xchg_cnt)
|
||||
*cur_xchg_cnt = mcp->mb[3];
|
||||
if (orig_xchg_cnt)
|
||||
*orig_xchg_cnt = mcp->mb[6];
|
||||
if (cur_iocb_cnt)
|
||||
*cur_iocb_cnt = mcp->mb[7];
|
||||
if (orig_iocb_cnt)
|
||||
*orig_iocb_cnt = mcp->mb[10];
|
||||
if (vha->hw->flags.npiv_supported && max_npiv_vports)
|
||||
*max_npiv_vports = mcp->mb[11];
|
||||
if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) ||
|
||||
IS_QLA27XX(vha->hw)) && max_fcfs)
|
||||
*max_fcfs = mcp->mb[12];
|
||||
ha->orig_fw_tgt_xcb_count = mcp->mb[1];
|
||||
ha->cur_fw_tgt_xcb_count = mcp->mb[2];
|
||||
ha->cur_fw_xcb_count = mcp->mb[3];
|
||||
ha->orig_fw_xcb_count = mcp->mb[6];
|
||||
ha->cur_fw_iocb_count = mcp->mb[7];
|
||||
ha->orig_fw_iocb_count = mcp->mb[10];
|
||||
if (ha->flags.npiv_supported)
|
||||
ha->max_npiv_vports = mcp->mb[11];
|
||||
if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
|
||||
ha->fw_max_fcf_count = mcp->mb[12];
|
||||
}
|
||||
|
||||
return (rval);
|
||||
|
|
|
|||
|
|
@ -221,6 +221,18 @@ MODULE_PARM_DESC(ql2xmdenable,
|
|||
"0 - MiniDump disabled. "
|
||||
"1 (Default) - MiniDump enabled.");
|
||||
|
||||
int ql2xexlogins = 0;
|
||||
module_param(ql2xexlogins, uint, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(ql2xexlogins,
|
||||
"Number of extended Logins. "
|
||||
"0 (Default)- Disabled.");
|
||||
|
||||
int ql2xexchoffld = 0;
|
||||
module_param(ql2xexchoffld, uint, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(ql2xexchoffld,
|
||||
"Number of exchanges to offload. "
|
||||
"0 (Default)- Disabled.");
|
||||
|
||||
/*
|
||||
* SCSI host template entry points
|
||||
*/
|
||||
|
|
@ -2324,6 +2336,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
ha->tgt.enable_class_2 = ql2xenableclass2;
|
||||
INIT_LIST_HEAD(&ha->tgt.q_full_list);
|
||||
spin_lock_init(&ha->tgt.q_full_lock);
|
||||
spin_lock_init(&ha->tgt.sess_lock);
|
||||
spin_lock_init(&ha->tgt.atio_lock);
|
||||
|
||||
|
||||
/* Clear our data area */
|
||||
ha->bars = bars;
|
||||
|
|
@ -2468,7 +2483,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
|
||||
ha->mbx_count = MAILBOX_REGISTER_COUNT;
|
||||
req_length = REQUEST_ENTRY_CNT_83XX;
|
||||
rsp_length = RESPONSE_ENTRY_CNT_2300;
|
||||
rsp_length = RESPONSE_ENTRY_CNT_83XX;
|
||||
ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
|
||||
ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
|
||||
ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
|
||||
|
|
@ -2498,8 +2513,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
ha->portnum = PCI_FUNC(ha->pdev->devfn);
|
||||
ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
|
||||
ha->mbx_count = MAILBOX_REGISTER_COUNT;
|
||||
req_length = REQUEST_ENTRY_CNT_24XX;
|
||||
rsp_length = RESPONSE_ENTRY_CNT_2300;
|
||||
req_length = REQUEST_ENTRY_CNT_83XX;
|
||||
rsp_length = RESPONSE_ENTRY_CNT_83XX;
|
||||
ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
|
||||
ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
|
||||
ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
|
||||
|
|
@ -3128,6 +3143,14 @@ qla2x00_remove_one(struct pci_dev *pdev)
|
|||
|
||||
base_vha->flags.online = 0;
|
||||
|
||||
/* free DMA memory */
|
||||
if (ha->exlogin_buf)
|
||||
qla2x00_free_exlogin_buffer(ha);
|
||||
|
||||
/* free DMA memory */
|
||||
if (ha->exchoffld_buf)
|
||||
qla2x00_free_exchoffld_buffer(ha);
|
||||
|
||||
qla2x00_destroy_deferred_work(ha);
|
||||
|
||||
qlt_remove_target(ha, base_vha);
|
||||
|
|
@ -3587,6 +3610,140 @@ fail:
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_set_exlogins_buffer(scsi_qla_host_t *vha)
|
||||
{
|
||||
int rval;
|
||||
uint16_t size, max_cnt, temp;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
/* Return if we don't need to alloacate any extended logins */
|
||||
if (!ql2xexlogins)
|
||||
return QLA_SUCCESS;
|
||||
|
||||
ql_log(ql_log_info, vha, 0xd021, "EXLOGIN count: %d.\n", ql2xexlogins);
|
||||
max_cnt = 0;
|
||||
rval = qla_get_exlogin_status(vha, &size, &max_cnt);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
ql_log_pci(ql_log_fatal, ha->pdev, 0xd029,
|
||||
"Failed to get exlogin status.\n");
|
||||
return rval;
|
||||
}
|
||||
|
||||
temp = (ql2xexlogins > max_cnt) ? max_cnt : ql2xexlogins;
|
||||
ha->exlogin_size = (size * temp);
|
||||
ql_log(ql_log_info, vha, 0xd024,
|
||||
"EXLOGIN: max_logins=%d, portdb=0x%x, total=%d.\n",
|
||||
max_cnt, size, temp);
|
||||
|
||||
ql_log(ql_log_info, vha, 0xd025, "EXLOGIN: requested size=0x%x\n",
|
||||
ha->exlogin_size);
|
||||
|
||||
/* Get consistent memory for extended logins */
|
||||
ha->exlogin_buf = dma_alloc_coherent(&ha->pdev->dev,
|
||||
ha->exlogin_size, &ha->exlogin_buf_dma, GFP_KERNEL);
|
||||
if (!ha->exlogin_buf) {
|
||||
ql_log_pci(ql_log_fatal, ha->pdev, 0xd02a,
|
||||
"Failed to allocate memory for exlogin_buf_dma.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Now configure the dma buffer */
|
||||
rval = qla_set_exlogin_mem_cfg(vha, ha->exlogin_buf_dma);
|
||||
if (rval) {
|
||||
ql_log(ql_log_fatal, vha, 0x00cf,
|
||||
"Setup extended login buffer ****FAILED****.\n");
|
||||
qla2x00_free_exlogin_buffer(ha);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* qla2x00_free_exlogin_buffer
|
||||
*
|
||||
* Input:
|
||||
* ha = adapter block pointer
|
||||
*/
|
||||
void
|
||||
qla2x00_free_exlogin_buffer(struct qla_hw_data *ha)
|
||||
{
|
||||
if (ha->exlogin_buf) {
|
||||
dma_free_coherent(&ha->pdev->dev, ha->exlogin_size,
|
||||
ha->exlogin_buf, ha->exlogin_buf_dma);
|
||||
ha->exlogin_buf = NULL;
|
||||
ha->exlogin_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_set_exchoffld_buffer(scsi_qla_host_t *vha)
|
||||
{
|
||||
int rval;
|
||||
uint16_t size, max_cnt, temp;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
/* Return if we don't need to alloacate any extended logins */
|
||||
if (!ql2xexchoffld)
|
||||
return QLA_SUCCESS;
|
||||
|
||||
ql_log(ql_log_info, vha, 0xd014,
|
||||
"Exchange offload count: %d.\n", ql2xexlogins);
|
||||
|
||||
max_cnt = 0;
|
||||
rval = qla_get_exchoffld_status(vha, &size, &max_cnt);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
ql_log_pci(ql_log_fatal, ha->pdev, 0xd012,
|
||||
"Failed to get exlogin status.\n");
|
||||
return rval;
|
||||
}
|
||||
|
||||
temp = (ql2xexchoffld > max_cnt) ? max_cnt : ql2xexchoffld;
|
||||
ha->exchoffld_size = (size * temp);
|
||||
ql_log(ql_log_info, vha, 0xd016,
|
||||
"Exchange offload: max_count=%d, buffers=0x%x, total=%d.\n",
|
||||
max_cnt, size, temp);
|
||||
|
||||
ql_log(ql_log_info, vha, 0xd017,
|
||||
"Exchange Buffers requested size = 0x%x\n", ha->exchoffld_size);
|
||||
|
||||
/* Get consistent memory for extended logins */
|
||||
ha->exchoffld_buf = dma_alloc_coherent(&ha->pdev->dev,
|
||||
ha->exchoffld_size, &ha->exchoffld_buf_dma, GFP_KERNEL);
|
||||
if (!ha->exchoffld_buf) {
|
||||
ql_log_pci(ql_log_fatal, ha->pdev, 0xd013,
|
||||
"Failed to allocate memory for exchoffld_buf_dma.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Now configure the dma buffer */
|
||||
rval = qla_set_exchoffld_mem_cfg(vha, ha->exchoffld_buf_dma);
|
||||
if (rval) {
|
||||
ql_log(ql_log_fatal, vha, 0xd02e,
|
||||
"Setup exchange offload buffer ****FAILED****.\n");
|
||||
qla2x00_free_exchoffld_buffer(ha);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* qla2x00_free_exchoffld_buffer
|
||||
*
|
||||
* Input:
|
||||
* ha = adapter block pointer
|
||||
*/
|
||||
void
|
||||
qla2x00_free_exchoffld_buffer(struct qla_hw_data *ha)
|
||||
{
|
||||
if (ha->exchoffld_buf) {
|
||||
dma_free_coherent(&ha->pdev->dev, ha->exchoffld_size,
|
||||
ha->exchoffld_buf, ha->exchoffld_buf_dma);
|
||||
ha->exchoffld_buf = NULL;
|
||||
ha->exchoffld_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* qla2x00_free_fw_dump
|
||||
* Frees fw dump stuff.
|
||||
|
|
@ -3766,6 +3923,8 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
|
|||
INIT_LIST_HEAD(&vha->list);
|
||||
INIT_LIST_HEAD(&vha->qla_cmd_list);
|
||||
INIT_LIST_HEAD(&vha->qla_sess_op_cmd_list);
|
||||
INIT_LIST_HEAD(&vha->logo_list);
|
||||
INIT_LIST_HEAD(&vha->plogi_ack_list);
|
||||
|
||||
spin_lock_init(&vha->work_lock);
|
||||
spin_lock_init(&vha->cmd_list_lock);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -787,7 +787,7 @@ int qla2x00_wait_for_hba_online(struct scsi_qla_host *);
|
|||
#define QLA_TGT_STATE_NEED_DATA 1 /* target needs data to continue */
|
||||
#define QLA_TGT_STATE_DATA_IN 2 /* Data arrived + target processing */
|
||||
#define QLA_TGT_STATE_PROCESSED 3 /* target done processing */
|
||||
#define QLA_TGT_STATE_ABORTED 4 /* Command aborted */
|
||||
|
||||
|
||||
/* Special handles */
|
||||
#define QLA_TGT_NULL_HANDLE 0
|
||||
|
|
@ -835,6 +835,7 @@ struct qla_tgt {
|
|||
* HW lock.
|
||||
*/
|
||||
int irq_cmd_count;
|
||||
int atio_irq_cmd_count;
|
||||
|
||||
int datasegs_per_cmd, datasegs_per_cont, sg_tablesize;
|
||||
|
||||
|
|
@ -883,6 +884,7 @@ struct qla_tgt {
|
|||
|
||||
struct qla_tgt_sess_op {
|
||||
struct scsi_qla_host *vha;
|
||||
uint32_t chip_reset;
|
||||
struct atio_from_isp atio;
|
||||
struct work_struct work;
|
||||
struct list_head cmd_list;
|
||||
|
|
@ -896,6 +898,19 @@ enum qla_sess_deletion {
|
|||
QLA_SESS_DELETION_IN_PROGRESS = 2,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
QLT_PLOGI_LINK_SAME_WWN,
|
||||
QLT_PLOGI_LINK_CONFLICT,
|
||||
QLT_PLOGI_LINK_MAX
|
||||
} qlt_plogi_link_t;
|
||||
|
||||
typedef struct {
|
||||
struct list_head list;
|
||||
struct imm_ntfy_from_isp iocb;
|
||||
port_id_t id;
|
||||
int ref_count;
|
||||
} qlt_plogi_ack_t;
|
||||
|
||||
/*
|
||||
* Equivilant to IT Nexus (Initiator-Target)
|
||||
*/
|
||||
|
|
@ -907,8 +922,8 @@ struct qla_tgt_sess {
|
|||
unsigned int deleted:2;
|
||||
unsigned int local:1;
|
||||
unsigned int logout_on_delete:1;
|
||||
unsigned int plogi_ack_needed:1;
|
||||
unsigned int keep_nport_handle:1;
|
||||
unsigned int send_els_logo:1;
|
||||
|
||||
unsigned char logout_completed;
|
||||
|
||||
|
|
@ -925,9 +940,7 @@ struct qla_tgt_sess {
|
|||
uint8_t port_name[WWN_SIZE];
|
||||
struct work_struct free_work;
|
||||
|
||||
union {
|
||||
struct imm_ntfy_from_isp tm_iocb;
|
||||
};
|
||||
qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX];
|
||||
};
|
||||
|
||||
struct qla_tgt_cmd {
|
||||
|
|
@ -949,6 +962,7 @@ struct qla_tgt_cmd {
|
|||
unsigned int term_exchg:1;
|
||||
unsigned int cmd_sent_to_fw:1;
|
||||
unsigned int cmd_in_wq:1;
|
||||
unsigned int aborted:1;
|
||||
|
||||
struct scatterlist *sg; /* cmd data buffer SG vector */
|
||||
int sg_cnt; /* SG segments count */
|
||||
|
|
@ -1120,6 +1134,14 @@ static inline uint32_t sid_to_key(const uint8_t *s_id)
|
|||
return key;
|
||||
}
|
||||
|
||||
static inline void sid_to_portid(const uint8_t *s_id, port_id_t *p)
|
||||
{
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->b.domain = s_id[0];
|
||||
p->b.area = s_id[1];
|
||||
p->b.al_pa = s_id[2];
|
||||
}
|
||||
|
||||
/*
|
||||
* Exported symbols from qla_target.c LLD logic used by qla2xxx code..
|
||||
*/
|
||||
|
|
@ -1135,7 +1157,7 @@ extern void qlt_enable_vha(struct scsi_qla_host *);
|
|||
extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *);
|
||||
extern void qlt_rff_id(struct scsi_qla_host *, struct ct_sns_req *);
|
||||
extern void qlt_init_atio_q_entries(struct scsi_qla_host *);
|
||||
extern void qlt_24xx_process_atio_queue(struct scsi_qla_host *);
|
||||
extern void qlt_24xx_process_atio_queue(struct scsi_qla_host *, uint8_t);
|
||||
extern void qlt_24xx_config_rings(struct scsi_qla_host *);
|
||||
extern void qlt_24xx_config_nvram_stage1(struct scsi_qla_host *,
|
||||
struct nvram_24xx *);
|
||||
|
|
|
|||
|
|
@ -284,6 +284,7 @@ static void tcm_qla2xxx_complete_free(struct work_struct *work)
|
|||
|
||||
WARN_ON(cmd->cmd_flags & BIT_16);
|
||||
|
||||
cmd->vha->tgt_counters.qla_core_ret_sta_ctio++;
|
||||
cmd->cmd_flags |= BIT_16;
|
||||
transport_generic_free_cmd(&cmd->se_cmd, 0);
|
||||
}
|
||||
|
|
@ -295,9 +296,10 @@ static void tcm_qla2xxx_complete_free(struct work_struct *work)
|
|||
*/
|
||||
static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
|
||||
{
|
||||
cmd->vha->tgt_counters.core_qla_free_cmd++;
|
||||
cmd->cmd_in_wq = 1;
|
||||
INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free);
|
||||
queue_work(tcm_qla2xxx_free_wq, &cmd->work);
|
||||
queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -342,9 +344,9 @@ static int tcm_qla2xxx_shutdown_session(struct se_session *se_sess)
|
|||
BUG_ON(!sess);
|
||||
vha = sess->vha;
|
||||
|
||||
spin_lock_irqsave(&vha->hw->hardware_lock, flags);
|
||||
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
|
||||
target_sess_cmd_list_set_waiting(se_sess);
|
||||
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
|
||||
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -358,9 +360,9 @@ static void tcm_qla2xxx_close_session(struct se_session *se_sess)
|
|||
BUG_ON(!sess);
|
||||
vha = sess->vha;
|
||||
|
||||
spin_lock_irqsave(&vha->hw->hardware_lock, flags);
|
||||
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
|
||||
qlt_unreg_sess(sess);
|
||||
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
|
||||
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
|
||||
}
|
||||
|
||||
static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess)
|
||||
|
|
@ -454,6 +456,7 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
cmd->vha->tgt_counters.qla_core_sbt_cmd++;
|
||||
return target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0],
|
||||
cmd->unpacked_lun, data_length, fcp_task_attr,
|
||||
data_dir, flags);
|
||||
|
|
@ -469,6 +472,7 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
|
|||
*/
|
||||
cmd->cmd_in_wq = 0;
|
||||
cmd->cmd_flags |= BIT_11;
|
||||
cmd->vha->tgt_counters.qla_core_ret_ctio++;
|
||||
if (!cmd->write_data_transferred) {
|
||||
/*
|
||||
* Check if se_cmd has already been aborted via LUN_RESET, and
|
||||
|
|
@ -500,7 +504,7 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
|
|||
cmd->cmd_flags |= BIT_10;
|
||||
cmd->cmd_in_wq = 1;
|
||||
INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work);
|
||||
queue_work(tcm_qla2xxx_free_wq, &cmd->work);
|
||||
queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
|
||||
}
|
||||
|
||||
static void tcm_qla2xxx_handle_dif_work(struct work_struct *work)
|
||||
|
|
@ -643,7 +647,7 @@ static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
|
|||
static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
|
||||
struct tcm_qla2xxx_nacl *, struct qla_tgt_sess *);
|
||||
/*
|
||||
* Expected to be called with struct qla_hw_data->hardware_lock held
|
||||
* Expected to be called with struct qla_hw_data->tgt.sess_lock held
|
||||
*/
|
||||
static void tcm_qla2xxx_clear_nacl_from_fcport_map(struct qla_tgt_sess *sess)
|
||||
{
|
||||
|
|
@ -697,13 +701,13 @@ static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess)
|
|||
if (!sess)
|
||||
return;
|
||||
|
||||
assert_spin_locked(&sess->vha->hw->hardware_lock);
|
||||
assert_spin_locked(&sess->vha->hw->tgt.sess_lock);
|
||||
kref_put(&sess->se_sess->sess_kref, tcm_qla2xxx_release_session);
|
||||
}
|
||||
|
||||
static void tcm_qla2xxx_shutdown_sess(struct qla_tgt_sess *sess)
|
||||
{
|
||||
assert_spin_locked(&sess->vha->hw->hardware_lock);
|
||||
assert_spin_locked(&sess->vha->hw->tgt.sess_lock);
|
||||
target_sess_cmd_list_set_waiting(sess->se_sess);
|
||||
}
|
||||
|
||||
|
|
@ -1077,7 +1081,7 @@ static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg(
|
|||
}
|
||||
|
||||
/*
|
||||
* Expected to be called with struct qla_hw_data->hardware_lock held
|
||||
* Expected to be called with struct qla_hw_data->tgt.sess_lock held
|
||||
*/
|
||||
static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_s_id(
|
||||
scsi_qla_host_t *vha,
|
||||
|
|
@ -1116,7 +1120,7 @@ static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_s_id(
|
|||
}
|
||||
|
||||
/*
|
||||
* Expected to be called with struct qla_hw_data->hardware_lock held
|
||||
* Expected to be called with struct qla_hw_data->tgt.sess_lock held
|
||||
*/
|
||||
static void tcm_qla2xxx_set_sess_by_s_id(
|
||||
struct tcm_qla2xxx_lport *lport,
|
||||
|
|
@ -1182,7 +1186,7 @@ static void tcm_qla2xxx_set_sess_by_s_id(
|
|||
}
|
||||
|
||||
/*
|
||||
* Expected to be called with struct qla_hw_data->hardware_lock held
|
||||
* Expected to be called with struct qla_hw_data->tgt.sess_lock held
|
||||
*/
|
||||
static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_loop_id(
|
||||
scsi_qla_host_t *vha,
|
||||
|
|
@ -1221,7 +1225,7 @@ static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_loop_id(
|
|||
}
|
||||
|
||||
/*
|
||||
* Expected to be called with struct qla_hw_data->hardware_lock held
|
||||
* Expected to be called with struct qla_hw_data->tgt.sess_lock held
|
||||
*/
|
||||
static void tcm_qla2xxx_set_sess_by_loop_id(
|
||||
struct tcm_qla2xxx_lport *lport,
|
||||
|
|
@ -1285,7 +1289,7 @@ static void tcm_qla2xxx_set_sess_by_loop_id(
|
|||
}
|
||||
|
||||
/*
|
||||
* Should always be called with qla_hw_data->hardware_lock held.
|
||||
* Should always be called with qla_hw_data->tgt.sess_lock held.
|
||||
*/
|
||||
static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *lport,
|
||||
struct tcm_qla2xxx_nacl *nacl, struct qla_tgt_sess *sess)
|
||||
|
|
@ -1353,7 +1357,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
|
|||
struct qla_tgt_sess *sess = qla_tgt_sess;
|
||||
unsigned char port_name[36];
|
||||
unsigned long flags;
|
||||
int num_tags = (ha->fw_xcb_count) ? ha->fw_xcb_count :
|
||||
int num_tags = (ha->cur_fw_xcb_count) ? ha->cur_fw_xcb_count :
|
||||
TCM_QLA2XXX_DEFAULT_TAGS;
|
||||
|
||||
lport = vha->vha_tgt.target_lport_ptr;
|
||||
|
|
@ -1401,12 +1405,12 @@ static int tcm_qla2xxx_check_initiator_node_acl(
|
|||
* And now setup the new se_nacl and session pointers into our HW lport
|
||||
* mappings for fabric S_ID and LOOP_ID.
|
||||
*/
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
|
||||
tcm_qla2xxx_set_sess_by_s_id(lport, se_nacl, nacl, se_sess,
|
||||
qla_tgt_sess, s_id);
|
||||
tcm_qla2xxx_set_sess_by_loop_id(lport, se_nacl, nacl, se_sess,
|
||||
qla_tgt_sess, loop_id);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
/*
|
||||
* Finally register the new FC Nexus with TCM
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue