Merge branch 'svn-trunk'

This commit is contained in:
Bart Van Assche
2019-05-03 20:13:48 -07:00
11 changed files with 193 additions and 279 deletions

View File

@@ -28,7 +28,7 @@ ABT_KERNELS=" \
3.19.8-nc \
3.18.139-nc \
3.17.8-nc \
3.16.65-nc \
3.16.66-nc \
3.15.10-nc \
3.14.79-nc \
3.13.11-nc \

View File

@@ -801,7 +801,7 @@ free_sess:
}
static struct fc_port *sqa_qla2xxx_find_sess_by_s_id(scsi_qla_host_t *vha,
const uint8_t *s_id)
be_id_t s_id)
{
struct fc_port *sess;
@@ -812,9 +812,9 @@ static struct fc_port *sqa_qla2xxx_find_sess_by_s_id(scsi_qla_host_t *vha,
s_id[1], s_id[2]);
#endif
list_for_each_entry(sess, &vha->vp_fcports, list) {
if ((sess->d_id.b.al_pa == s_id[2]) &&
(sess->d_id.b.area == s_id[1]) &&
(sess->d_id.b.domain == s_id[0]) &&
if (sess->d_id.b.al_pa == s_id.al_pa &&
sess->d_id.b.area == s_id.area &&
sess->d_id.b.domain == s_id.domain &&
!sess->deleted && sess->se_sess)
return sess;
}

View File

@@ -48,6 +48,20 @@
#define NEW_LIBFC_API
#endif
/* Big endian Fibre Channel S_ID (source ID) or D_ID (destination ID). */
typedef struct {
uint8_t domain;
uint8_t area;
uint8_t al_pa;
} be_id_t;
/* Little endian Fibre Channel S_ID (source ID) or D_ID (destination ID). */
typedef struct {
uint8_t al_pa;
uint8_t area;
uint8_t domain;
} le_id_t;
#include "qla_bsg.h"
#include "qla_dsd.h"
#include "qla_nx.h"
@@ -357,6 +371,51 @@ typedef union {
} port_id_t;
#define INVALID_PORT_ID 0xFFFFFF
static inline le_id_t be_id_to_le(be_id_t id)
{
le_id_t res;
res.domain = id.domain;
res.area = id.area;
res.al_pa = id.al_pa;
return res;
}
static inline be_id_t le_id_to_be(le_id_t id)
{
be_id_t res;
res.domain = id.domain;
res.area = id.area;
res.al_pa = id.al_pa;
return res;
}
static inline port_id_t be_to_port_id(be_id_t id)
{
port_id_t res;
res.b.domain = id.domain;
res.b.area = id.area;
res.b.al_pa = id.al_pa;
res.b.rsvd_1 = 0;
return res;
}
static inline be_id_t port_id_to_be_id(port_id_t port_id)
{
be_id_t res;
res.domain = port_id.b.domain;
res.area = port_id.b.area;
res.al_pa = port_id.b.al_pa;
return res;
}
struct els_logo_payload {
uint8_t opcode;
uint8_t rsvd[3];
@@ -4778,5 +4837,4 @@ struct sff_8247_a0 {
#include "qla_gbl.h"
#include "qla_dbg.h"
#include "qla_inline.h"
#endif

View File

@@ -57,10 +57,9 @@ qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused)
{
scsi_qla_host_t *vha = s->private;
struct qla_hw_data *ha = vha->hw;
struct gid_list_info *gid_list;
struct gid_list_info *gid_list, *gid;
dma_addr_t gid_list_dma;
fc_port_t fc_port;
char *id_iter;
int rc, i;
uint16_t entries, loop_id;
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
@@ -82,13 +81,11 @@ qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused)
if (rc != QLA_SUCCESS)
goto out_free_id_list;
id_iter = (char *)gid_list;
gid = gid_list;
seq_puts(s, "Port Name Port ID Loop ID\n");
for (i = 0; i < entries; i++) {
struct gid_list_info *gid =
(struct gid_list_info *)id_iter;
loop_id = le16_to_cpu(gid->loop_id);
memset(&fc_port, 0, sizeof(fc_port_t));
@@ -99,7 +96,7 @@ qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused)
wwn_to_str(fc_port.port_name), fc_port.d_id.b.domain,
fc_port.d_id.b.area, fc_port.d_id.b.al_pa,
fc_port.loop_id);
id_iter += ha->gid_list_info_size;
gid = (void *)gid + ha->gid_list_info_size;
}
out_free_id_list:
dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha),

View File

@@ -224,7 +224,6 @@ extern void qla24xx_sched_upd_fcport(fc_port_t *);
void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
int qla24xx_async_abort_cmd(srb_t *, bool);
int qla24xx_post_relogin_work(struct scsi_qla_host *vha);
void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *);

View File

@@ -115,7 +115,7 @@ static void qla24xx_abort_sp_done(void *ptr, int res)
sp->free(sp);
}
int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
{
scsi_qla_host_t *vha = cmd_sp->vha;
struct srb_iocb *abt_iocb;
@@ -4818,11 +4818,10 @@ void qla2x00_set_fcport_state(fc_port_t *fcport, int state)
/* Don't print state transitions during initial allocation of fcport */
if (old_state && old_state != state) {
ql_dbg(ql_dbg_disc, fcport->vha, 0x207d,
"FCPort %s state transitioned from %s to %s - "
"portid=%02x%02x%02x.\n", wwn_to_str(fcport->port_name),
port_state_str[old_state], port_state_str[state],
fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa);
"FCPort %8phC state transitioned from %s to %s - portid=%02x%02x%02x.\n",
fcport->port_name, port_state_str[old_state],
port_state_str[state], fcport->d_id.b.domain,
fcport->d_id.b.area, fcport->d_id.b.al_pa);
}
}
@@ -5054,7 +5053,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
uint16_t index;
uint16_t entries;
char *id_iter;
struct gid_list_info *gid;
uint16_t loop_id;
uint8_t domain, area, al_pa;
struct qla_hw_data *ha = vha->hw;
@@ -5129,18 +5128,16 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
new_fcport->flags &= ~FCF_FABRIC_DEVICE;
/* Add devices to port list. */
id_iter = (char *)ha->gid_list;
gid = ha->gid_list;
for (index = 0; index < entries; index++) {
domain = ((struct gid_list_info *)id_iter)->domain;
area = ((struct gid_list_info *)id_iter)->area;
al_pa = ((struct gid_list_info *)id_iter)->al_pa;
domain = gid->domain;
area = gid->area;
al_pa = gid->al_pa;
if (IS_QLA2100(ha) || IS_QLA2200(ha))
loop_id = (uint16_t)
((struct gid_list_info *)id_iter)->loop_id_2100;
loop_id = gid->loop_id_2100;
else
loop_id = le16_to_cpu(
((struct gid_list_info *)id_iter)->loop_id);
id_iter += ha->gid_list_info_size;
loop_id = le16_to_cpu(gid->loop_id);
gid = (void *)gid + ha->gid_list_info_size;
/* Bypass reserved domain fields. */
if ((domain & 0xf0) == 0xf0)

View File

@@ -595,34 +595,6 @@ static struct nvme_fc_port_template qla_nvme_fc_transport = {
.fcprqst_priv_sz = sizeof(struct nvme_private),
};
#define NVME_ABORT_POLLING_PERIOD 2
static int qla_nvme_wait_on_command(srb_t *sp)
{
int ret = QLA_SUCCESS;
wait_event_timeout(sp->nvme_ls_waitq, (atomic_read(&sp->ref_count) > 1),
NVME_ABORT_POLLING_PERIOD*HZ);
if (atomic_read(&sp->ref_count) > 1)
ret = QLA_FUNCTION_FAILED;
return ret;
}
void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp, int res)
{
int rval;
if (ha->flags.fw_started) {
rval = ha->isp_ops->abort_command(sp);
if (!rval && !qla_nvme_wait_on_command(sp))
ql_log(ql_log_warn, NULL, 0x2112,
"timed out waiting on sp=%p\n", sp);
} else {
sp->done(sp, res);
}
}
static void qla_nvme_unregister_remote_port(struct work_struct *work)
{
struct fc_port *fcport = container_of(work, struct fc_port,

View File

@@ -120,7 +120,7 @@ struct pt_ls4_rx_unsol {
uint32_t exchange_address;
uint8_t d_id[3];
uint8_t r_ctl;
uint8_t s_id[3];
be_id_t s_id;
uint8_t cs_ctl;
uint8_t f_ctl[3];
uint8_t type;
@@ -144,7 +144,6 @@ struct pt_ls4_rx_unsol {
int qla_nvme_register_hba(struct scsi_qla_host *);
int qla_nvme_register_remote(struct scsi_qla_host *, struct fc_port *);
void qla_nvme_delete(struct scsi_qla_host *);
void qla_nvme_abort(struct qla_hw_data *, struct srb *sp, int res);
#else
static inline int qla_nvme_register_hba(struct scsi_qla_host *vha)
{
@@ -160,11 +159,6 @@ static inline int qla_nvme_register_remote(struct scsi_qla_host *vha,
static inline void qla_nvme_delete(struct scsi_qla_host *vha)
{
}
static inline void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp,
int res)
{
}
#endif
void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *, struct pt_ls4_request *,

View File

@@ -702,7 +702,7 @@ qla2x00_sp_free_dma(void *ptr)
}
if (!ctx)
goto end;
return;
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
/* List assured to be having elements */
@@ -727,12 +727,6 @@ qla2x00_sp_free_dma(void *ptr)
ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
mempool_free(ctx1, ha->ctx_mempool);
}
end:
if (sp->type != SRB_NVME_CMD && sp->type != SRB_NVME_LS) {
CMD_SP(cmd) = NULL;
qla2x00_rel_sp(sp);
}
}
void
@@ -742,16 +736,18 @@ qla2x00_sp_compl(void *ptr, int res)
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
struct completion *comp = sp->comp;
if (WARN_ON(atomic_read(&sp->ref_count) == 0))
if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0))
return;
atomic_dec(&sp->ref_count);
sp->free(sp);
cmd->result = res;
CMD_SP(cmd) = NULL;
cmd->scsi_done(cmd);
if (comp)
complete(comp);
qla2x00_rel_sp(sp);
}
void
@@ -774,7 +770,7 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
}
if (!ctx)
goto end;
return;
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
/* List assured to be having elements */
@@ -836,10 +832,6 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma);
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
}
end:
CMD_SP(cmd) = NULL;
qla2xxx_rel_qpair_sp(sp->qpair, sp);
}
void
@@ -849,15 +841,18 @@ qla2xxx_qpair_sp_compl(void *ptr, int res)
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
struct completion *comp = sp->comp;
if (WARN_ON(atomic_read(&sp->ref_count) == 0))
if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0))
return;
atomic_dec(&sp->ref_count);
sp->free(sp);
cmd->result = res;
CMD_SP(cmd) = NULL;
cmd->scsi_done(cmd);
if (comp)
complete(comp);
qla2xxx_rel_qpair_sp(sp->qpair, sp);
}
#if defined(RHEL_MAJOR) && RHEL_MAJOR -0 == 6 && RHEL_MINOR -0 >= 2
@@ -1338,7 +1333,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
ret = fc_block_scsi_eh(cmd);
if (ret != 0)
return ret;
ret = SUCCESS;
sp = (srb_t *) CMD_SP(cmd);
if (!sp)
@@ -1350,10 +1344,13 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
if (sp->type != SRB_SCSI_CMD || GET_CMD_SP(sp) != cmd) {
/* there's a chance an interrupt could clear
the ptr as part of done & free */
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return SUCCESS;
}
/* Get a reference to the sp and drop the lock. */
if (sp_get(sp)){
/* ref_count is already 0 */
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
@@ -1368,8 +1365,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
"Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n",
vha->host_no, id, lun, sp, cmd, sp->handle);
/* Get a reference to the sp and drop the lock.*/
ret = SUCCESS;
rval = ha->isp_ops->abort_command(sp);
ql_dbg(ql_dbg_taskm, vha, 0x8003,
@@ -1377,7 +1372,10 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
switch (rval) {
case QLA_SUCCESS:
/* The command has been aborted. */
/*
* The command has been aborted. That means that the firmware
* won't report a completion.
*/
sp->done(sp, DID_ABORT << 16);
break;
case QLA_FUNCTION_PARAMETER_ERROR:
@@ -1778,42 +1776,34 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res,
__releases(qp->qp_lock_ptr)
__acquires(qp->qp_lock_ptr)
{
DECLARE_COMPLETION_ONSTACK(comp);
scsi_qla_host_t *vha = qp->vha;
struct qla_hw_data *ha = vha->hw;
int rval;
if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS) {
if (!sp_get(sp)) {
/* got sp */
spin_unlock_irqrestore(qp->qp_lock_ptr, *flags);
qla_nvme_abort(ha, sp, res);
spin_lock_irqsave(qp->qp_lock_ptr, *flags);
}
} else if (GET_CMD_SP(sp) && !ha->flags.eeh_busy &&
!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
!qla2x00_isp_reg_stat(ha) && sp->type == SRB_SCSI_CMD) {
/*
* Don't abort commands in adapter during EEH recovery as it's
* not accessible/responding.
*
* Get a reference to the sp and drop the lock. The reference
* ensures this sp->done() call and not the call in
* qla2xxx_eh_abort() ends the SCSI cmd (with result 'res').
*/
if (!sp_get(sp)) {
int status;
if (sp_get(sp))
return;
spin_unlock_irqrestore(qp->qp_lock_ptr, *flags);
status = qla2xxx_eh_abort(GET_CMD_SP(sp));
spin_lock_irqsave(qp->qp_lock_ptr, *flags);
/*
* Get rid of extra reference caused
* by early exit from qla2xxx_eh_abort
*/
if (status == FAST_IO_FAIL)
atomic_dec(&sp->ref_count);
if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS ||
(sp->type == SRB_SCSI_CMD && !ha->flags.eeh_busy &&
!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
!qla2x00_isp_reg_stat(ha))) {
sp->comp = &comp;
rval = ha->isp_ops->abort_command(sp);
spin_unlock_irqrestore(qp->qp_lock_ptr, *flags);
switch (rval) {
case QLA_SUCCESS:
sp->done(sp, res);
break;
case QLA_FUNCTION_PARAMETER_ERROR:
wait_for_completion(&comp);
break;
}
spin_lock_irqsave(qp->qp_lock_ptr, *flags);
sp->comp = NULL;
}
sp->done(sp, res);
}
static void
@@ -1849,15 +1839,10 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
continue;
}
cmd = (struct qla_tgt_cmd *)sp;
qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
cmd->aborted = 1;
break;
case TYPE_TGT_TMCMD:
/*
* Currently, only ABTS response gets on the
* outstanding_cmds[]
*/
ha->tgt.tgt_ops->free_mcmd(
(struct qla_tgt_mgmt_cmd *)sp);
/* Skip task management functions. */
break;
default:
break;

View File

@@ -210,18 +210,19 @@ static inline int qlt_issue_marker(struct scsi_qla_host *vha, int vha_locked)
static inline
struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha,
uint8_t *d_id)
be_id_t d_id)
{
struct scsi_qla_host *host;
uint32_t key = 0;
if ((vha->d_id.b.area == d_id[1]) && (vha->d_id.b.domain == d_id[0]) &&
(vha->d_id.b.al_pa == d_id[2]))
if (vha->d_id.b.area == d_id.area &&
vha->d_id.b.domain == d_id.domain &&
vha->d_id.b.al_pa == d_id.al_pa)
return vha;
key = (uint32_t)d_id[0] << 16;
key |= (uint32_t)d_id[1] << 8;
key |= (uint32_t)d_id[2];
key = d_id.domain << 16;
key |= d_id.area << 8;
key |= d_id.al_pa;
host = btree_lookup32(&vha->hw->tgt.host_map, key);
if (!host)
@@ -379,9 +380,9 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_tgt, vha, 0xe03e,
"qla_target(%d): Received ATIO_TYPE7 "
"with unknown d_id %x:%x:%x\n", vha->vp_idx,
atio->u.isp24.fcp_hdr.d_id[0],
atio->u.isp24.fcp_hdr.d_id[1],
atio->u.isp24.fcp_hdr.d_id[2]);
atio->u.isp24.fcp_hdr.d_id.domain,
atio->u.isp24.fcp_hdr.d_id.area,
atio->u.isp24.fcp_hdr.d_id.al_pa);
qlt_queue_unknown_atio(vha, atio, ha_locked);
@@ -1303,13 +1304,12 @@ static void qlt_clear_tgt_db(struct qla_tgt *tgt)
/* At this point tgt could be already dead */
}
static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id,
static int qla24xx_get_loop_id(struct scsi_qla_host *vha, be_id_t s_id,
uint16_t *loop_id)
{
struct qla_hw_data *ha = vha->hw;
dma_addr_t gid_list_dma;
struct gid_list_info *gid_list;
char *id_iter;
struct gid_list_info *gid_list, *gid;
int res, rc, i;
uint16_t entries;
@@ -1332,19 +1332,17 @@ static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id,
goto out_free_id_list;
}
id_iter = (char *)gid_list;
gid = gid_list;
res = -ENOENT;
for (i = 0; i < entries; i++) {
struct gid_list_info *gid = (struct gid_list_info *)id_iter;
if ((gid->al_pa == s_id[2]) &&
(gid->area == s_id[1]) &&
(gid->domain == s_id[0])) {
if (gid->al_pa == s_id.al_pa &&
gid->area == s_id.area &&
gid->domain == s_id.domain) {
*loop_id = le16_to_cpu(gid->loop_id);
res = 0;
break;
}
id_iter += ha->gid_list_info_size;
gid = (void *)gid + ha->gid_list_info_size;
}
out_free_id_list:
@@ -1790,12 +1788,8 @@ static int qlt_build_abts_resp_iocb(struct qla_tgt_mgmt_cmd *mcmd)
resp->fcp_hdr_le.f_ctl[1] = *p++;
resp->fcp_hdr_le.f_ctl[2] = *p;
resp->fcp_hdr_le.d_id[0] = abts->fcp_hdr_le.s_id[0];
resp->fcp_hdr_le.d_id[1] = abts->fcp_hdr_le.s_id[1];
resp->fcp_hdr_le.d_id[2] = abts->fcp_hdr_le.s_id[2];
resp->fcp_hdr_le.s_id[0] = abts->fcp_hdr_le.d_id[0];
resp->fcp_hdr_le.s_id[1] = abts->fcp_hdr_le.d_id[1];
resp->fcp_hdr_le.s_id[2] = abts->fcp_hdr_le.d_id[2];
resp->fcp_hdr_le.d_id = abts->fcp_hdr_le.s_id;
resp->fcp_hdr_le.s_id = abts->fcp_hdr_le.d_id;
resp->exchange_addr_to_abort = abts->exchange_addr_to_abort;
if (mcmd->fc_tm_rsp == FCP_TMF_CMPL) {
@@ -1866,19 +1860,11 @@ static void qlt_24xx_send_abts_resp(struct qla_qpair *qpair,
resp->fcp_hdr_le.f_ctl[1] = *p++;
resp->fcp_hdr_le.f_ctl[2] = *p;
if (ids_reversed) {
resp->fcp_hdr_le.d_id[0] = abts->fcp_hdr_le.d_id[0];
resp->fcp_hdr_le.d_id[1] = abts->fcp_hdr_le.d_id[1];
resp->fcp_hdr_le.d_id[2] = abts->fcp_hdr_le.d_id[2];
resp->fcp_hdr_le.s_id[0] = abts->fcp_hdr_le.s_id[0];
resp->fcp_hdr_le.s_id[1] = abts->fcp_hdr_le.s_id[1];
resp->fcp_hdr_le.s_id[2] = abts->fcp_hdr_le.s_id[2];
resp->fcp_hdr_le.d_id = abts->fcp_hdr_le.d_id;
resp->fcp_hdr_le.s_id = abts->fcp_hdr_le.s_id;
} else {
resp->fcp_hdr_le.d_id[0] = abts->fcp_hdr_le.s_id[0];
resp->fcp_hdr_le.d_id[1] = abts->fcp_hdr_le.s_id[1];
resp->fcp_hdr_le.d_id[2] = abts->fcp_hdr_le.s_id[2];
resp->fcp_hdr_le.s_id[0] = abts->fcp_hdr_le.d_id[0];
resp->fcp_hdr_le.s_id[1] = abts->fcp_hdr_le.d_id[1];
resp->fcp_hdr_le.s_id[2] = abts->fcp_hdr_le.d_id[2];
resp->fcp_hdr_le.d_id = abts->fcp_hdr_le.s_id;
resp->fcp_hdr_le.s_id = abts->fcp_hdr_le.d_id;
}
resp->exchange_addr_to_abort = abts->exchange_addr_to_abort;
if (status == FCP_TMF_CMPL) {
@@ -1945,18 +1931,14 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
tmp = (CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_TERMINATE);
if (mcmd) {
ctio->initiator_id[0] = entry->fcp_hdr_le.s_id[0];
ctio->initiator_id[1] = entry->fcp_hdr_le.s_id[1];
ctio->initiator_id[2] = entry->fcp_hdr_le.s_id[2];
ctio->initiator_id = entry->fcp_hdr_le.s_id;
if (mcmd->flags & QLA24XX_MGMT_ABORT_IO_ATTR_VALID)
tmp |= (mcmd->abort_io_attr << 9);
else if (qpair->retry_term_cnt & 1)
tmp |= (0x4 << 9);
} else {
ctio->initiator_id[0] = entry->fcp_hdr_le.d_id[0];
ctio->initiator_id[1] = entry->fcp_hdr_le.d_id[1];
ctio->initiator_id[2] = entry->fcp_hdr_le.d_id[2];
ctio->initiator_id = entry->fcp_hdr_le.d_id;
if (qpair->retry_term_cnt & 1)
tmp |= (0x4 << 9);
@@ -1990,8 +1972,7 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
* XXX does not go through the list of other port (which may have cmds
* for the same lun)
*/
static void abort_cmds_for_lun(struct scsi_qla_host *vha,
u64 lun, uint8_t *s_id)
static void abort_cmds_for_lun(struct scsi_qla_host *vha, u64 lun, be_id_t s_id)
{
struct qla_tgt_sess_op *op;
struct qla_tgt_cmd *cmd;
@@ -2175,7 +2156,7 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
struct qla_hw_data *ha = vha->hw;
struct fc_port *sess;
uint32_t tag = abts->exchange_addr_to_abort;
uint8_t s_id[3];
be_id_t s_id;
int rc;
unsigned long flags;
@@ -2199,13 +2180,11 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf011,
"qla_target(%d): task abort (s_id=%x:%x:%x, "
"tag=%d, param=%x)\n", vha->vp_idx, abts->fcp_hdr_le.s_id[2],
abts->fcp_hdr_le.s_id[1], abts->fcp_hdr_le.s_id[0], tag,
"tag=%d, param=%x)\n", vha->vp_idx, abts->fcp_hdr_le.s_id.domain,
abts->fcp_hdr_le.s_id.area, abts->fcp_hdr_le.s_id.al_pa, tag,
le32_to_cpu(abts->fcp_hdr_le.parameter));
s_id[0] = abts->fcp_hdr_le.s_id[2];
s_id[1] = abts->fcp_hdr_le.s_id[1];
s_id[2] = abts->fcp_hdr_le.s_id[0];
s_id = le_id_to_be(abts->fcp_hdr_le.s_id);
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id);
@@ -2269,9 +2248,7 @@ static void qlt_24xx_send_task_mgmt_ctio(struct qla_qpair *qpair,
ctio->nport_handle = mcmd->sess->loop_id;
ctio->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
ctio->vp_index = ha->vp_idx;
ctio->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
ctio->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id);
ctio->exchange_addr = atio->u.isp24.exchange_addr;
temp = (atio->u.isp24.attr << 9)|
CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS;
@@ -2328,9 +2305,7 @@ void qlt_send_resp_ctio(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd,
ctio->nport_handle = cmd->sess->loop_id;
ctio->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
ctio->vp_index = vha->vp_idx;
ctio->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
ctio->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id);
ctio->exchange_addr = atio->u.isp24.exchange_addr;
temp = (atio->u.isp24.attr << 9) |
CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS;
@@ -2638,9 +2613,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_qpair *qpair,
pkt->handle |= CTIO_COMPLETION_HANDLE_MARK;
pkt->nport_handle = cpu_to_le16(prm->cmd->loop_id);
pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
pkt->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id);
pkt->exchange_addr = atio->u.isp24.exchange_addr;
temp = atio->u.isp24.attr << 9;
pkt->u.status0.flags |= cpu_to_le16(temp);
@@ -3154,9 +3127,7 @@ qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm)
pkt->handle |= CTIO_COMPLETION_HANDLE_MARK;
pkt->nport_handle = cpu_to_le16(prm->cmd->loop_id);
pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
pkt->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id);
pkt->exchange_addr = atio->u.isp24.exchange_addr;
/* silence compile warning */
@@ -3274,7 +3245,6 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) ||
(cmd->sess && cmd->sess->deleted)) {
cmd->state = QLA_TGT_STATE_PROCESSED;
qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
return 0;
}
@@ -3303,7 +3273,6 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
* previous life, just abort the processing.
*/
cmd->state = QLA_TGT_STATE_PROCESSED;
qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
ql_dbg_qp(ql_dbg_async, qpair, 0xe101,
"RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n",
vha->flags.online, qla2x00_reset_active(vha),
@@ -3399,9 +3368,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
cmd->state = QLA_TGT_STATE_PROCESSED; /* Mid-level is done processing */
spin_lock(&cmd->cmd_lock);
cmd->cmd_sent_to_fw = 1;
spin_unlock(&cmd->cmd_lock);
cmd->ctio_flags = le16_to_cpu(pkt->u.status0.flags);
/* Memory Barrier */
@@ -3448,8 +3415,10 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
* Either the port is not online or this request was from
* previous life, just abort the processing.
*/
cmd->state = QLA_TGT_STATE_NEED_DATA;
qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
cmd->aborted = 1;
cmd->write_data_transferred = 0;
cmd->state = QLA_TGT_STATE_DATA_IN;
vha->hw->tgt.tgt_ops->handle_data(cmd);
ql_dbg_qp(ql_dbg_async, qpair, 0xe102,
"RESET-XFR online/active/old-count/new-count = %d/%d/%d/%d.\n",
vha->flags.online, qla2x00_reset_active(vha),
@@ -3484,9 +3453,7 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
qlt_load_data_segments(&prm);
cmd->state = QLA_TGT_STATE_NEED_DATA;
spin_lock(&cmd->cmd_lock);
cmd->cmd_sent_to_fw = 1;
spin_unlock(&cmd->cmd_lock);
cmd->ctio_flags = le16_to_cpu(pkt->u.status0.flags);
/* Memory Barrier */
@@ -3728,9 +3695,7 @@ static int __qlt_send_term_exchange(struct qla_qpair *qpair,
ctio24->nport_handle = CTIO7_NHANDLE_UNRECOGNIZED;
ctio24->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
ctio24->vp_index = vha->vp_idx;
ctio24->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
ctio24->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
ctio24->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
ctio24->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id);
ctio24->exchange_addr = atio->u.isp24.exchange_addr;
temp = (atio->u.isp24.attr << 9) | CTIO7_FLAGS_STATUS_MODE_1 |
CTIO7_FLAGS_TERMINATE;
@@ -3984,39 +3949,6 @@ static void *qlt_ctio_to_cmd(struct scsi_qla_host *vha,
return cmd;
}
/* hardware_lock should be held by caller. */
void
qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
{
struct qla_hw_data *ha = vha->hw;
if (cmd->sg_mapped)
qlt_unmap_sg(vha, cmd);
/* TODO: fix debug message type and ids. */
if (cmd->state == QLA_TGT_STATE_PROCESSED) {
ql_dbg(ql_dbg_io, vha, 0xff00,
"HOST-ABORT: state=PROCESSED.\n");
} else if (cmd->state == QLA_TGT_STATE_NEED_DATA) {
cmd->write_data_transferred = 0;
cmd->state = QLA_TGT_STATE_DATA_IN;
ql_dbg(ql_dbg_io, vha, 0xff01,
"HOST-ABORT: state=DATA_IN.\n");
ha->tgt.tgt_ops->handle_data(cmd);
return;
} else {
ql_dbg(ql_dbg_io, vha, 0xff03,
"HOST-ABORT: state=BAD(%d).\n",
cmd->state);
dump_stack();
}
cmd->trc_flags |= TRC_FLUSH;
ha->tgt.tgt_ops->free_cmd(cmd);
}
/*
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
*/
@@ -4198,8 +4130,7 @@ static inline int qlt_get_fcp_task_attr(struct scsi_qla_host *vha,
return fcp_task_attr;
}
static struct fc_port *qlt_make_local_sess(struct scsi_qla_host *,
uint8_t *);
static struct fc_port *qlt_make_local_sess(struct scsi_qla_host *, be_id_t);
/*
* Process context for I/O path into tcm_qla2xxx code
*/
@@ -4439,9 +4370,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
return -ENODEV;
}
id.b.al_pa = atio->u.isp24.fcp_hdr.s_id[2];
id.b.area = atio->u.isp24.fcp_hdr.s_id[1];
id.b.domain = atio->u.isp24.fcp_hdr.s_id[0];
id = be_to_port_id(atio->u.isp24.fcp_hdr.s_id);
if (IS_SW_RESV_ADDR(id))
return -EBUSY;
@@ -5413,10 +5342,7 @@ static int __qlt_send_busy(struct qla_qpair *qpair,
u16 temp;
port_id_t id;
id.b.al_pa = atio->u.isp24.fcp_hdr.s_id[2];
id.b.area = atio->u.isp24.fcp_hdr.s_id[1];
id.b.domain = atio->u.isp24.fcp_hdr.s_id[0];
id.b.rsvd_1 = 0;
id = be_to_port_id(atio->u.isp24.fcp_hdr.s_id);
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
sess = qla2x00_find_fcport_by_nportid(vha, &id, 1);
@@ -5444,9 +5370,7 @@ static int __qlt_send_busy(struct qla_qpair *qpair,
ctio24->nport_handle = sess->loop_id;
ctio24->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
ctio24->vp_index = vha->vp_idx;
ctio24->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
ctio24->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
ctio24->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
ctio24->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id);
ctio24->exchange_addr = atio->u.isp24.exchange_addr;
temp = (atio->u.isp24.attr << 9) |
CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS |
@@ -6226,21 +6150,21 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha,
/* Must be called under tgt_mutex */
static struct fc_port *qlt_make_local_sess(struct scsi_qla_host *vha,
uint8_t *s_id)
be_id_t s_id)
{
struct fc_port *sess = NULL;
fc_port_t *fcport = NULL;
int rc, global_resets;
uint16_t loop_id = 0;
if ((s_id[0] == 0xFF) && (s_id[1] == 0xFC)) {
if (s_id.domain == 0xFF && s_id.area == 0xFC) {
/*
* This is Domain Controller, so it should be
* OK to drop SCSI commands from it.
*/
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf042,
"Unable to find initiator with S_ID %x:%x:%x",
s_id[0], s_id[1], s_id[2]);
s_id.domain, s_id.area, s_id.al_pa);
return NULL;
}
@@ -6257,13 +6181,12 @@ retry:
ql_log(ql_log_info, vha, 0xf071,
"qla_target(%d): Unable to find "
"initiator with S_ID %x:%x:%x",
vha->vp_idx, s_id[0], s_id[1],
s_id[2]);
vha->vp_idx, s_id.domain, s_id.area, s_id.al_pa);
if (rc == -ENOENT) {
qlt_port_logo_t logo;
sid_to_portid(s_id, &logo.id);
logo.id = be_to_port_id(s_id);
logo.cmd_count = 1;
qlt_send_first_logo(vha, &logo);
}
@@ -6302,8 +6225,7 @@ static void qlt_abort_work(struct qla_tgt *tgt,
struct qla_hw_data *ha = vha->hw;
struct fc_port *sess = NULL;
unsigned long flags = 0, flags2 = 0;
uint32_t be_s_id;
uint8_t s_id[3];
be_id_t s_id;
int rc;
spin_lock_irqsave(&ha->tgt.sess_lock, flags2);
@@ -6311,12 +6233,9 @@ static void qlt_abort_work(struct qla_tgt *tgt,
if (tgt->tgt_stop)
goto out_term2;
s_id[0] = prm->abts.fcp_hdr_le.s_id[2];
s_id[1] = prm->abts.fcp_hdr_le.s_id[1];
s_id[2] = prm->abts.fcp_hdr_le.s_id[0];
s_id = le_id_to_be(prm->abts.fcp_hdr_le.s_id);
sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
(unsigned char *)&be_s_id);
sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id);
if (!sess) {
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
@@ -6371,7 +6290,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
struct qla_hw_data *ha = vha->hw;
struct fc_port *sess;
unsigned long flags;
uint8_t *s_id = NULL; /* to hide compiler warnings */
be_id_t s_id;
int rc;
u64 unpacked_lun;
int fn;
@@ -6920,7 +6839,7 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked)
*/
ql_log(ql_log_warn, vha, 0xd03c,
"corrupted fcp frame SID[%3phN] OXID[%04x] EXCG[%x] %64phN\n",
pkt->u.isp24.fcp_hdr.s_id,
&pkt->u.isp24.fcp_hdr.s_id.domain,
be16_to_cpu(pkt->u.isp24.fcp_hdr.ox_id),
le32_to_cpu(pkt->u.isp24.exchange_addr), pkt);

View File

@@ -283,9 +283,9 @@ struct ctio_to_2xxx {
struct fcp_hdr {
uint8_t r_ctl;
uint8_t d_id[3];
be_id_t d_id;
uint8_t cs_ctl;
uint8_t s_id[3];
be_id_t s_id;
uint8_t type;
uint8_t f_ctl[3];
uint8_t seq_id;
@@ -297,9 +297,9 @@ struct fcp_hdr {
} __packed;
struct fcp_hdr_le {
uint8_t d_id[3];
le_id_t d_id;
uint8_t r_ctl;
uint8_t s_id[3];
le_id_t s_id;
uint8_t cs_ctl;
uint8_t f_ctl[3];
uint8_t type;
@@ -438,7 +438,7 @@ struct ctio7_to_24xx {
uint16_t dseg_count; /* Data segment count. */
uint8_t vp_index;
uint8_t add_flags;
uint8_t initiator_id[3];
le_id_t initiator_id;
uint8_t reserved;
uint32_t exchange_addr;
union {
@@ -534,7 +534,7 @@ struct ctio_crc2_to_fw {
uint8_t add_flags; /* additional flags */
#define CTIO_CRC2_AF_DIF_DSD_ENA BIT_3
uint8_t initiator_id[3]; /* initiator ID */
le_id_t initiator_id; /* initiator ID */
uint8_t reserved1;
uint32_t exchange_addr; /* rcv exchange address */
uint16_t reserved2;
@@ -719,7 +719,7 @@ struct qla_tgt_func_tmpl {
struct fc_port *(*find_sess_by_loop_id)(struct scsi_qla_host *,
const uint16_t);
struct fc_port *(*find_sess_by_s_id)(struct scsi_qla_host *,
const uint8_t *);
const be_id_t);
void (*clear_nacl_from_fcport_map)(struct fc_port *);
void (*put_sess)(struct fc_port *);
void (*shutdown_sess)(struct fc_port *);
@@ -929,8 +929,14 @@ 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;
unsigned int released:1;
/*
* This variable may be set from outside the LIO and I/O completion
* callback functions. Do not declare this member variable as a
* bitfield to avoid a read-modify-write operation when this variable
* is set.
*/
unsigned int aborted;
struct scatterlist *sg; /* cmd data buffer SG vector */
int sg_cnt; /* SG segments count */
@@ -1085,22 +1091,11 @@ static inline bool qla_dual_mode_enabled(struct scsi_qla_host *ha)
return (ha->host->active_mode == MODE_DUAL);
}
static inline uint32_t sid_to_key(const uint8_t *s_id)
static inline uint32_t sid_to_key(const be_id_t s_id)
{
uint32_t key;
key = (((unsigned long)s_id[0] << 16) |
((unsigned long)s_id[1] << 8) |
(unsigned long)s_id[2]);
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];
return s_id.domain << 16 |
s_id.area << 8 |
s_id.al_pa;
}
/*
@@ -1146,7 +1141,5 @@ extern void qlt_do_generation_tick(struct scsi_qla_host *, int *);
void qlt_send_resp_ctio(struct qla_qpair *, struct qla_tgt_cmd *, uint8_t,
uint8_t, uint8_t, uint8_t);
extern void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *,
struct qla_tgt_cmd *);
#endif /* __QLA_TARGET_H */