Commit 82de802a authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen

scsi: qla2xxx: Preparation for Target MQ.

In Current code, Req Q 0, RespQ 0 & hardware_lock are the main resources
for sending and process completion of Target IO. These resources are now
referenced behind a new qpair/"struct qla_qpair base_qpair".  Main path
IO handle will access those resources via the qpair pointer in
preparation for Target MQ.
Signed-off-by: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent c5419e26
...@@ -2096,7 +2096,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) ...@@ -2096,7 +2096,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
} }
if (qos) { if (qos) {
qpair = qla2xxx_create_qpair(vha, qos, vha->vp_idx); qpair = qla2xxx_create_qpair(vha, qos, vha->vp_idx, true);
if (!qpair) if (!qpair)
ql_log(ql_log_warn, vha, 0x7084, ql_log(ql_log_warn, vha, 0x7084,
"Can't create qpair for VP[%d]\n", "Can't create qpair for VP[%d]\n",
......
...@@ -3182,6 +3182,9 @@ struct qla_tc_param { ...@@ -3182,6 +3182,9 @@ struct qla_tc_param {
#define QLA_PRECONFIG_VPORTS 32 #define QLA_PRECONFIG_VPORTS 32
#define QLA_MAX_VPORTS_QLA24XX 128 #define QLA_MAX_VPORTS_QLA24XX 128
#define QLA_MAX_VPORTS_QLA25XX 256 #define QLA_MAX_VPORTS_QLA25XX 256
struct qla_qpair;
/* Response queue data structure */ /* Response queue data structure */
struct rsp_que { struct rsp_que {
dma_addr_t dma; dma_addr_t dma;
...@@ -3201,6 +3204,7 @@ struct rsp_que { ...@@ -3201,6 +3204,7 @@ struct rsp_que {
struct qla_msix_entry *msix; struct qla_msix_entry *msix;
struct req_que *req; struct req_que *req;
srb_t *status_srb; /* status continuation entry */ srb_t *status_srb; /* status continuation entry */
struct qla_qpair *qpair;
dma_addr_t dma_fx00; dma_addr_t dma_fx00;
response_t *ring_fx00; response_t *ring_fx00;
...@@ -3241,6 +3245,14 @@ struct req_que { ...@@ -3241,6 +3245,14 @@ struct req_que {
struct qla_qpair { struct qla_qpair {
spinlock_t qp_lock; spinlock_t qp_lock;
atomic_t ref_count; atomic_t ref_count;
/*
* For qpair 0, qp_lock_ptr will point at hardware_lock due to
* legacy code. For other Qpair(s), it will point at qp_lock.
*/
spinlock_t *qp_lock_ptr;
struct scsi_qla_host *vha;
/* distill these fields down to 'online=0/1' /* distill these fields down to 'online=0/1'
* ha->flags.eeh_busy * ha->flags.eeh_busy
* ha->flags.pci_channel_io_perm_failure * ha->flags.pci_channel_io_perm_failure
...@@ -3252,10 +3264,7 @@ struct qla_qpair { ...@@ -3252,10 +3264,7 @@ struct qla_qpair {
uint32_t delete_in_progress:1; uint32_t delete_in_progress:1;
uint16_t id; /* qp number used with FW */ uint16_t id; /* qp number used with FW */
uint16_t num_active_cmd; /* cmds down at firmware */
cpumask_t cpu_mask; /* CPU mask for cpu affinity operation */
uint16_t vp_idx; /* vport ID */ uint16_t vp_idx; /* vport ID */
mempool_t *srb_mempool; mempool_t *srb_mempool;
/* to do: New driver: move queues to here instead of pointers */ /* to do: New driver: move queues to here instead of pointers */
...@@ -3266,7 +3275,7 @@ struct qla_qpair { ...@@ -3266,7 +3275,7 @@ struct qla_qpair {
struct qla_hw_data *hw; struct qla_hw_data *hw;
struct work_struct q_work; struct work_struct q_work;
struct list_head qp_list_elem; /* vha->qp_list */ struct list_head qp_list_elem; /* vha->qp_list */
struct scsi_qla_host *vha; uint16_t cpuid;
}; };
/* Place holder for FW buffer parameters */ /* Place holder for FW buffer parameters */
......
...@@ -77,8 +77,7 @@ struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host *, ...@@ -77,8 +77,7 @@ struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host *,
enum qla_work_type); enum qla_work_type);
extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *); extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *);
int qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e); int qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e);
extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *); extern void *qla2x00_alloc_iocbs_ready(struct qla_qpair *, srb_t *);
extern void *qla2x00_alloc_iocbs_ready(struct scsi_qla_host *, srb_t *);
extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *); extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);
extern fc_port_t * extern fc_port_t *
...@@ -96,7 +95,7 @@ qla2x00_alloc_outstanding_cmds(struct qla_hw_data *, struct req_que *); ...@@ -96,7 +95,7 @@ qla2x00_alloc_outstanding_cmds(struct qla_hw_data *, struct req_que *);
extern int qla2x00_init_rings(scsi_qla_host_t *); extern int qla2x00_init_rings(scsi_qla_host_t *);
extern uint8_t qla27xx_find_valid_image(struct scsi_qla_host *); extern uint8_t qla27xx_find_valid_image(struct scsi_qla_host *);
extern struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *, extern struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *,
int, int); int, int, bool);
extern int qla2xxx_delete_qpair(struct scsi_qla_host *, struct qla_qpair *); extern int qla2xxx_delete_qpair(struct scsi_qla_host *, struct qla_qpair *);
void qla2x00_fcport_event_handler(scsi_qla_host_t *, struct event_arg *); void qla2x00_fcport_event_handler(scsi_qla_host_t *, struct event_arg *);
int qla24xx_async_gpdb(struct scsi_qla_host *, fc_port_t *, u8); int qla24xx_async_gpdb(struct scsi_qla_host *, fc_port_t *, u8);
...@@ -255,7 +254,8 @@ extern int qla2x00_start_bidir(srb_t *, struct scsi_qla_host *, uint32_t); ...@@ -255,7 +254,8 @@ extern int qla2x00_start_bidir(srb_t *, struct scsi_qla_host *, uint32_t);
extern int qla2xxx_dif_start_scsi_mq(srb_t *); extern int qla2xxx_dif_start_scsi_mq(srb_t *);
extern unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *); extern unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *);
extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *); extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *);
extern void *__qla2x00_alloc_iocbs(struct qla_qpair *, srb_t *);
extern int qla2x00_issue_marker(scsi_qla_host_t *, int); extern int qla2x00_issue_marker(scsi_qla_host_t *, int);
extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *, extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *,
uint32_t *, uint16_t, struct qla_tc_param *); uint32_t *, uint16_t, struct qla_tc_param *);
...@@ -663,9 +663,9 @@ extern int qla25xx_request_irq(struct qla_hw_data *, struct qla_qpair *, ...@@ -663,9 +663,9 @@ extern int qla25xx_request_irq(struct qla_hw_data *, struct qla_qpair *,
extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *); extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *);
extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *); extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *);
extern int qla25xx_create_req_que(struct qla_hw_data *, uint16_t, uint8_t, extern int qla25xx_create_req_que(struct qla_hw_data *, uint16_t, uint8_t,
uint16_t, int, uint8_t); uint16_t, int, uint8_t, bool);
extern int qla25xx_create_rsp_que(struct qla_hw_data *, uint16_t, uint8_t, extern int qla25xx_create_rsp_que(struct qla_hw_data *, uint16_t, uint8_t,
uint16_t, struct qla_qpair *); uint16_t, struct qla_qpair *, bool);
extern void qla2x00_init_response_q_entries(struct rsp_que *); extern void qla2x00_init_response_q_entries(struct rsp_que *);
extern int qla25xx_delete_req_que(struct scsi_qla_host *, struct req_que *); extern int qla25xx_delete_req_que(struct scsi_qla_host *, struct req_que *);
...@@ -839,7 +839,8 @@ extern int qla_get_exlogin_status(scsi_qla_host_t *, uint16_t *, ...@@ -839,7 +839,8 @@ extern int qla_get_exlogin_status(scsi_qla_host_t *, uint16_t *,
extern int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr); 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_get_exchoffld_status(scsi_qla_host_t *, uint16_t *, uint16_t *);
extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *); extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *);
extern void qlt_handle_abts_recv(struct scsi_qla_host *, response_t *); extern void qlt_handle_abts_recv(struct scsi_qla_host *, struct rsp_que *,
response_t *);
int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *, int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *,
struct imm_ntfy_from_isp *, int); struct imm_ntfy_from_isp *, int);
......
...@@ -7578,7 +7578,8 @@ qla24xx_update_all_fcp_prio(scsi_qla_host_t *vha) ...@@ -7578,7 +7578,8 @@ qla24xx_update_all_fcp_prio(scsi_qla_host_t *vha)
return ret; return ret;
} }
struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int vp_idx) struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos,
int vp_idx, bool startqp)
{ {
int rsp_id = 0; int rsp_id = 0;
int req_id = 0; int req_id = 0;
...@@ -7605,6 +7606,8 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v ...@@ -7605,6 +7606,8 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
qpair->hw = vha->hw; qpair->hw = vha->hw;
qpair->vha = vha; qpair->vha = vha;
qpair->qp_lock_ptr = &qpair->qp_lock;
spin_lock_init(&qpair->qp_lock);
/* Assign available que pair id */ /* Assign available que pair id */
mutex_lock(&ha->mq_lock); mutex_lock(&ha->mq_lock);
...@@ -7642,7 +7645,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v ...@@ -7642,7 +7645,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
mutex_unlock(&ha->mq_lock); mutex_unlock(&ha->mq_lock);
/* Create response queue first */ /* Create response queue first */
rsp_id = qla25xx_create_rsp_que(ha, 0, 0, 0, qpair); rsp_id = qla25xx_create_rsp_que(ha, 0, 0, 0, qpair, startqp);
if (!rsp_id) { if (!rsp_id) {
ql_log(ql_log_warn, vha, 0x0185, ql_log(ql_log_warn, vha, 0x0185,
"Failed to create response queue.\n"); "Failed to create response queue.\n");
...@@ -7652,7 +7655,8 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v ...@@ -7652,7 +7655,8 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
qpair->rsp = ha->rsp_q_map[rsp_id]; qpair->rsp = ha->rsp_q_map[rsp_id];
/* Create request queue */ /* Create request queue */
req_id = qla25xx_create_req_que(ha, 0, vp_idx, 0, rsp_id, qos); req_id = qla25xx_create_req_que(ha, 0, vp_idx, 0, rsp_id, qos,
startqp);
if (!req_id) { if (!req_id) {
ql_log(ql_log_warn, vha, 0x0186, ql_log(ql_log_warn, vha, 0x0186,
"Failed to create request queue.\n"); "Failed to create request queue.\n");
...@@ -7661,6 +7665,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v ...@@ -7661,6 +7665,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
qpair->req = ha->req_q_map[req_id]; qpair->req = ha->req_q_map[req_id];
qpair->rsp->req = qpair->req; qpair->rsp->req = qpair->req;
qpair->rsp->qpair = qpair;
if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
if (ha->fw_attributes & BIT_4) if (ha->fw_attributes & BIT_4)
......
...@@ -2109,20 +2109,13 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp) ...@@ -2109,20 +2109,13 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp)
/* Generic Control-SRB manipulation functions. */ /* Generic Control-SRB manipulation functions. */
/* hardware_lock assumed to be held. */ /* hardware_lock assumed to be held. */
void *
qla2x00_alloc_iocbs_ready(scsi_qla_host_t *vha, srb_t *sp)
{
if (qla2x00_reset_active(vha))
return NULL;
return qla2x00_alloc_iocbs(vha, sp);
}
void * void *
qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp) __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp)
{ {
scsi_qla_host_t *vha = qpair->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_q_map[0]; struct req_que *req = qpair->req;
device_reg_t *reg = ISP_QUE_REG(ha, req->id); device_reg_t *reg = ISP_QUE_REG(ha, req->id);
uint32_t index, handle; uint32_t index, handle;
request_t *pkt; request_t *pkt;
...@@ -2200,6 +2193,23 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp) ...@@ -2200,6 +2193,23 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp)
return pkt; return pkt;
} }
void *
qla2x00_alloc_iocbs_ready(struct qla_qpair *qpair, srb_t *sp)
{
scsi_qla_host_t *vha = qpair->vha;
if (qla2x00_reset_active(vha))
return NULL;
return __qla2x00_alloc_iocbs(qpair, sp);
}
void *
qla2x00_alloc_iocbs(struct scsi_qla_host *vha, srb_t *sp)
{
return __qla2x00_alloc_iocbs(vha->hw->base_qpair, sp);
}
static void static void
qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio) qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio)
{ {
......
...@@ -2653,7 +2653,8 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt) ...@@ -2653,7 +2653,8 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
int res = DID_ERROR << 16; int res = DID_ERROR << 16;
ql_dbg(ql_dbg_async, vha, 0x502a, ql_dbg(ql_dbg_async, vha, 0x502a,
"type of error status in response: 0x%x\n", pkt->entry_status); "iocb type %xh with error status %xh, handle %xh, rspq id %d\n",
pkt->entry_type, pkt->entry_status, pkt->handle, rsp->id);
if (que >= ha->max_req_queues || !ha->req_q_map[que]) if (que >= ha->max_req_queues || !ha->req_q_map[que])
goto fatal; goto fatal;
...@@ -2805,7 +2806,8 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, ...@@ -2805,7 +2806,8 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
case ABTS_RECV_24XX: case ABTS_RECV_24XX:
if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
/* ensure that the ATIO queue is empty */ /* ensure that the ATIO queue is empty */
qlt_handle_abts_recv(vha, (response_t *)pkt); qlt_handle_abts_recv(vha, rsp,
(response_t *)pkt);
break; break;
} else { } else {
/* drop through */ /* drop through */
...@@ -2814,11 +2816,12 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, ...@@ -2814,11 +2816,12 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
case ABTS_RESP_24XX: case ABTS_RESP_24XX:
case CTIO_TYPE7: case CTIO_TYPE7:
case CTIO_CRC2: case CTIO_CRC2:
qlt_response_pkt_all_vps(vha, (response_t *)pkt); qlt_response_pkt_all_vps(vha, rsp, (response_t *)pkt);
break; break;
case NOTIFY_ACK_TYPE: case NOTIFY_ACK_TYPE:
if (pkt->handle == QLA_TGT_SKIP_HANDLE) if (pkt->handle == QLA_TGT_SKIP_HANDLE)
qlt_response_pkt_all_vps(vha, (response_t *)pkt); qlt_response_pkt_all_vps(vha, rsp,
(response_t *)pkt);
else else
qla24xxx_nack_iocb_entry(vha, rsp->req, qla24xxx_nack_iocb_entry(vha, rsp->req,
(struct nack_to_isp *)pkt); (struct nack_to_isp *)pkt);
......
...@@ -640,7 +640,7 @@ qla25xx_delete_queues(struct scsi_qla_host *vha) ...@@ -640,7 +640,7 @@ qla25xx_delete_queues(struct scsi_qla_host *vha)
int int
qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options, qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
uint8_t vp_idx, uint16_t rid, int rsp_que, uint8_t qos) uint8_t vp_idx, uint16_t rid, int rsp_que, uint8_t qos, bool startqp)
{ {
int ret = 0; int ret = 0;
struct req_que *req = NULL; struct req_que *req = NULL;
...@@ -731,14 +731,16 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options, ...@@ -731,14 +731,16 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
req->ring_ptr, req->ring_index, req->cnt, req->ring_ptr, req->ring_index, req->cnt,
req->id, req->max_q_depth); req->id, req->max_q_depth);
ret = qla25xx_init_req_que(base_vha, req); if (startqp) {
if (ret != QLA_SUCCESS) { ret = qla25xx_init_req_que(base_vha, req);
ql_log(ql_log_fatal, base_vha, 0x00df, if (ret != QLA_SUCCESS) {
"%s failed.\n", __func__); ql_log(ql_log_fatal, base_vha, 0x00df,
mutex_lock(&ha->mq_lock); "%s failed.\n", __func__);
clear_bit(que_id, ha->req_qid_map); mutex_lock(&ha->mq_lock);
mutex_unlock(&ha->mq_lock); clear_bit(que_id, ha->req_qid_map);
goto que_failed; mutex_unlock(&ha->mq_lock);
goto que_failed;
}
} }
return req->id; return req->id;
...@@ -765,7 +767,7 @@ static void qla_do_work(struct work_struct *work) ...@@ -765,7 +767,7 @@ static void qla_do_work(struct work_struct *work)
/* create response queue */ /* create response queue */
int int
qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
uint8_t vp_idx, uint16_t rid, struct qla_qpair *qpair) uint8_t vp_idx, uint16_t rid, struct qla_qpair *qpair, bool startqp)
{ {
int ret = 0; int ret = 0;
struct rsp_que *rsp = NULL; struct rsp_que *rsp = NULL;
...@@ -843,14 +845,16 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, ...@@ -843,14 +845,16 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
if (ret) if (ret)
goto que_failed; goto que_failed;
ret = qla25xx_init_rsp_que(base_vha, rsp); if (startqp) {
if (ret != QLA_SUCCESS) { ret = qla25xx_init_rsp_que(base_vha, rsp);
ql_log(ql_log_fatal, base_vha, 0x00e7, if (ret != QLA_SUCCESS) {
"%s failed.\n", __func__); ql_log(ql_log_fatal, base_vha, 0x00e7,
mutex_lock(&ha->mq_lock); "%s failed.\n", __func__);
clear_bit(que_id, ha->rsp_qid_map); mutex_lock(&ha->mq_lock);
mutex_unlock(&ha->mq_lock); clear_bit(que_id, ha->rsp_qid_map);
goto que_failed; mutex_unlock(&ha->mq_lock);
goto que_failed;
}
} }
rsp->req = NULL; rsp->req = NULL;
......
...@@ -389,6 +389,13 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, ...@@ -389,6 +389,13 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req,
ha->base_qpair->rsp = rsp; ha->base_qpair->rsp = rsp;
} }
rsp->qpair = ha->base_qpair;
rsp->req = req;
ha->base_qpair->vha = vha;
ha->base_qpair->qp_lock_ptr = &ha->hardware_lock;
ha->queue_pair_map[0] = ha->base_qpair;
set_bit(0, ha->qpair_qid_map);
/* /*
* Make sure we record at least the request and response queue zero in * Make sure we record at least the request and response queue zero in
* case we need to free them if part of the probe fails. * case we need to free them if part of the probe fails.
...@@ -399,9 +406,10 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, ...@@ -399,9 +406,10 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req,
set_bit(0, ha->req_qid_map); set_bit(0, ha->req_qid_map);
return 1; return 1;
fail_base_qpair:
kfree(ha->queue_pair_map);
fail_qpair_map: fail_qpair_map:
kfree(ha->base_qpair);
ha->base_qpair = NULL;
fail_base_qpair:
kfree(ha->rsp_q_map); kfree(ha->rsp_q_map);
ha->rsp_q_map = NULL; ha->rsp_q_map = NULL;
fail_rsp_map: fail_rsp_map:
...@@ -451,6 +459,15 @@ static void qla2x00_free_queues(struct qla_hw_data *ha) ...@@ -451,6 +459,15 @@ static void qla2x00_free_queues(struct qla_hw_data *ha)
int cnt; int cnt;
unsigned long flags; unsigned long flags;
if (ha->queue_pair_map) {
kfree(ha->queue_pair_map);
ha->queue_pair_map = NULL;
}
if (ha->base_qpair) {
kfree(ha->base_qpair);
ha->base_qpair = NULL;
}
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
for (cnt = 0; cnt < ha->max_req_queues; cnt++) { for (cnt = 0; cnt < ha->max_req_queues; cnt++) {
if (!test_bit(cnt, ha->req_qid_map)) if (!test_bit(cnt, ha->req_qid_map))
...@@ -3113,7 +3130,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -3113,7 +3130,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Create start of day qpairs for Block MQ */ /* Create start of day qpairs for Block MQ */
if (shost_use_blk_mq(host)) { if (shost_use_blk_mq(host)) {
for (i = 0; i < ha->max_qpairs; i++) for (i = 0; i < ha->max_qpairs; i++)
qla2xxx_create_qpair(base_vha, 5, 0); qla2xxx_create_qpair(base_vha, 5, 0, true);
} }
} }
......
...@@ -110,16 +110,17 @@ enum fcp_resp_rsp_codes { ...@@ -110,16 +110,17 @@ enum fcp_resp_rsp_codes {
/* Predefs for callbacks handed to qla2xxx LLD */ /* Predefs for callbacks handed to qla2xxx LLD */
static void qlt_24xx_atio_pkt(struct scsi_qla_host *ha, static void qlt_24xx_atio_pkt(struct scsi_qla_host *ha,
struct atio_from_isp *pkt, uint8_t); struct atio_from_isp *pkt, uint8_t);
static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt); static void qlt_response_pkt(struct scsi_qla_host *ha, struct rsp_que *rsp,
response_t *pkt);
static int qlt_issue_task_mgmt(struct fc_port *sess, u64 lun, static int qlt_issue_task_mgmt(struct fc_port *sess, u64 lun,
int fn, void *iocb, int flags); int fn, void *iocb, int flags);
static void qlt_send_term_exchange(struct scsi_qla_host *ha, struct qla_tgt_cmd static void qlt_send_term_exchange(struct qla_qpair *, struct qla_tgt_cmd
*cmd, struct atio_from_isp *atio, int ha_locked, int ul_abort); *cmd, struct atio_from_isp *atio, int ha_locked, int ul_abort);
static void qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, static void qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
struct atio_from_isp *atio, uint16_t status, int qfull); struct atio_from_isp *atio, uint16_t status, int qfull);
static void qlt_disable_vha(struct scsi_qla_host *vha); static void qlt_disable_vha(struct scsi_qla_host *vha);
static void qlt_clear_tgt_db(struct qla_tgt *tgt); static void qlt_clear_tgt_db(struct qla_tgt *tgt);
static void qlt_send_notify_ack(struct scsi_qla_host *vha, static void qlt_send_notify_ack(struct qla_qpair *qpair,
struct imm_ntfy_from_isp *ntfy, struct imm_ntfy_from_isp *ntfy,
uint32_t add_flags, uint16_t resp_code, int resp_code_valid, uint32_t add_flags, uint16_t resp_code, int resp_code_valid,
uint16_t srr_flags, uint16_t srr_reject_code, uint8_t srr_explan); uint16_t srr_flags, uint16_t srr_reject_code, uint8_t srr_explan);
...@@ -130,6 +131,8 @@ static struct fc_port *qlt_create_sess(struct scsi_qla_host *vha, ...@@ -130,6 +131,8 @@ static struct fc_port *qlt_create_sess(struct scsi_qla_host *vha,
void qlt_unreg_sess(struct fc_port *sess); void qlt_unreg_sess(struct fc_port *sess);
static void qlt_24xx_handle_abts(struct scsi_qla_host *, static void qlt_24xx_handle_abts(struct scsi_qla_host *,
struct abts_recv_from_24xx *); struct abts_recv_from_24xx *);
static void qlt_send_busy(struct qla_qpair *, struct atio_from_isp *,
uint16_t);
/* /*
* Global Variables * Global Variables
...@@ -243,7 +246,7 @@ static inline void qlt_decr_num_pend_cmds(struct scsi_qla_host *vha) ...@@ -243,7 +246,7 @@ static inline void qlt_decr_num_pend_cmds(struct scsi_qla_host *vha)
static void qlt_queue_unknown_atio(scsi_qla_host_t *vha, static void qlt_queue_unknown_atio(scsi_qla_host_t *vha,
struct atio_from_isp *atio, uint8_t ha_locked) struct atio_from_isp *atio, uint8_t ha_locked)
{ {
struct qla_tgt_sess_op *u; struct qla_tgt_sess_op *u;
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
...@@ -274,7 +277,7 @@ static void qlt_queue_unknown_atio(scsi_qla_host_t *vha, ...@@ -274,7 +277,7 @@ static void qlt_queue_unknown_atio(scsi_qla_host_t *vha,
return; return;
out_term: out_term:
qlt_send_term_exchange(vha, NULL, atio, ha_locked, 0); qlt_send_term_exchange(vha->hw->base_qpair, NULL, atio, ha_locked, 0);
goto out; goto out;
} }
...@@ -292,8 +295,8 @@ static void qlt_try_to_dequeue_unknown_atios(struct scsi_qla_host *vha, ...@@ -292,8 +295,8 @@ static void qlt_try_to_dequeue_unknown_atios(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_async, vha, 0x502e, ql_dbg(ql_dbg_async, vha, 0x502e,
"Freeing unknown %s %p, because of Abort\n", "Freeing unknown %s %p, because of Abort\n",
"ATIO_TYPE7", u); "ATIO_TYPE7", u);
qlt_send_term_exchange(vha, NULL, &u->atio, qlt_send_term_exchange(vha->hw->base_qpair, NULL,
ha_locked, 0); &u->atio, ha_locked, 0);
goto abort; goto abort;
} }
...@@ -306,8 +309,8 @@ static void qlt_try_to_dequeue_unknown_atios(struct scsi_qla_host *vha, ...@@ -306,8 +309,8 @@ static void qlt_try_to_dequeue_unknown_atios(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_async, vha, 0x503a, ql_dbg(ql_dbg_async, vha, 0x503a,
"Freeing unknown %s %p, because tgt is being stopped\n", "Freeing unknown %s %p, because tgt is being stopped\n",
"ATIO_TYPE7", u); "ATIO_TYPE7", u);
qlt_send_term_exchange(vha, NULL, &u->atio, qlt_send_term_exchange(vha->hw->base_qpair, NULL,
ha_locked, 0); &u->atio, ha_locked, 0);
} else { } else {
ql_dbg(ql_dbg_async, vha, 0x503d, ql_dbg(ql_dbg_async, vha, 0x503d,
"Reschedule u %p, vha %p, host %p\n", u, vha, host); "Reschedule u %p, vha %p, host %p\n", u, vha, host);
...@@ -373,6 +376,8 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, ...@@ -373,6 +376,8 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
struct imm_ntfy_from_isp *entry = struct imm_ntfy_from_isp *entry =
(struct imm_ntfy_from_isp *)atio; (struct imm_ntfy_from_isp *)atio;
qlt_issue_marker(vha, ha_locked);
if ((entry->u.isp24.vp_index != 0xFF) && if ((entry->u.isp24.vp_index != 0xFF) &&
(entry->u.isp24.nport_handle != 0xFFFF)) { (entry->u.isp24.nport_handle != 0xFFFF)) {
host = qlt_find_host_by_vp_idx(vha, host = qlt_find_host_by_vp_idx(vha,
...@@ -430,7 +435,8 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, ...@@ -430,7 +435,8 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
return false; return false;
} }
void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt) void qlt_response_pkt_all_vps(struct scsi_qla_host *vha,
struct rsp_que *rsp, response_t *pkt)
{ {
switch (pkt->entry_type) { switch (pkt->entry_type) {
case CTIO_CRC2: case CTIO_CRC2:
...@@ -449,7 +455,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt) ...@@ -449,7 +455,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
vha->vp_idx, entry->vp_index); vha->vp_idx, entry->vp_index);
break; break;
} }
qlt_response_pkt(host, pkt); qlt_response_pkt(host, rsp, pkt);
break; break;
} }
...@@ -467,7 +473,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt) ...@@ -467,7 +473,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
vha->vp_idx, entry->u.isp24.vp_index); vha->vp_idx, entry->u.isp24.vp_index);
break; break;
} }
qlt_response_pkt(host, pkt); qlt_response_pkt(host, rsp, pkt);
break; break;
} }
...@@ -489,7 +495,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt) ...@@ -489,7 +495,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
break; break;
} }
} }
qlt_response_pkt(host, pkt); qlt_response_pkt(host, rsp, pkt);
break; break;
} }
...@@ -506,7 +512,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt) ...@@ -506,7 +512,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
"vp_index %d\n", vha->vp_idx, entry->vp_index); "vp_index %d\n", vha->vp_idx, entry->vp_index);
break; break;
} }
qlt_response_pkt(host, pkt); qlt_response_pkt(host, rsp, pkt);
break; break;
} }
...@@ -523,12 +529,12 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt) ...@@ -523,12 +529,12 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
"vp_index %d\n", vha->vp_idx, entry->vp_index); "vp_index %d\n", vha->vp_idx, entry->vp_index);
break; break;
} }
qlt_response_pkt(host, pkt); qlt_response_pkt(host, rsp, pkt);
break; break;
} }
default: default:
qlt_response_pkt(vha, pkt); qlt_response_pkt(vha, rsp, pkt);
break; break;
} }
...@@ -1560,11 +1566,12 @@ static int qlt_sched_sess_work(struct qla_tgt *tgt, int type, ...@@ -1560,11 +1566,12 @@ static int qlt_sched_sess_work(struct qla_tgt *tgt, int type,
/* /*
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
*/ */
static void qlt_send_notify_ack(struct scsi_qla_host *vha, static void qlt_send_notify_ack(struct qla_qpair *qpair,
struct imm_ntfy_from_isp *ntfy, struct imm_ntfy_from_isp *ntfy,
uint32_t add_flags, uint16_t resp_code, int resp_code_valid, uint32_t add_flags, uint16_t resp_code, int resp_code_valid,
uint16_t srr_flags, uint16_t srr_reject_code, uint8_t srr_explan) uint16_t srr_flags, uint16_t srr_reject_code, uint8_t srr_explan)
{ {
struct scsi_qla_host *vha = qpair->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
request_t *pkt; request_t *pkt;
struct nack_to_isp *nack; struct nack_to_isp *nack;
...@@ -1574,11 +1581,7 @@ static void qlt_send_notify_ack(struct scsi_qla_host *vha, ...@@ -1574,11 +1581,7 @@ static void qlt_send_notify_ack(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_tgt, vha, 0xe004, "Sending NOTIFY_ACK (ha=%p)\n", ha); ql_dbg(ql_dbg_tgt, vha, 0xe004, "Sending NOTIFY_ACK (ha=%p)\n", ha);
/* Send marker if required */ pkt = (request_t *)__qla2x00_alloc_iocbs(qpair, NULL);
if (qlt_issue_marker(vha, 1) != QLA_SUCCESS)
return;
pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL);
if (!pkt) { if (!pkt) {
ql_dbg(ql_dbg_tgt, vha, 0xe049, ql_dbg(ql_dbg_tgt, vha, 0xe049,
"qla_target(%d): %s failed: unable to allocate " "qla_target(%d): %s failed: unable to allocate "
...@@ -1619,16 +1622,17 @@ static void qlt_send_notify_ack(struct scsi_qla_host *vha, ...@@ -1619,16 +1622,17 @@ static void qlt_send_notify_ack(struct scsi_qla_host *vha,
/* Memory Barrier */ /* Memory Barrier */
wmb(); wmb();
qla2x00_start_iocbs(vha, vha->req); qla2x00_start_iocbs(vha, qpair->req);
} }
/* /*
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
*/ */
static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha, static void qlt_24xx_send_abts_resp(struct qla_qpair *qpair,
struct abts_recv_from_24xx *abts, uint32_t status, struct abts_recv_from_24xx *abts, uint32_t status,
bool ids_reversed) bool ids_reversed)
{ {
struct scsi_qla_host *vha = qpair->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct abts_resp_to_24xx *resp; struct abts_resp_to_24xx *resp;
uint32_t f_ctl; uint32_t f_ctl;
...@@ -1638,11 +1642,8 @@ static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha, ...@@ -1638,11 +1642,8 @@ static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha,
"Sending task mgmt ABTS response (ha=%p, atio=%p, status=%x\n", "Sending task mgmt ABTS response (ha=%p, atio=%p, status=%x\n",
ha, abts, status); ha, abts, status);
/* Send marker if required */ resp = (struct abts_resp_to_24xx *)qla2x00_alloc_iocbs_ready(qpair,
if (qlt_issue_marker(vha, 1) != QLA_SUCCESS) NULL);
return;
resp = (struct abts_resp_to_24xx *)qla2x00_alloc_iocbs_ready(vha, NULL);
if (!resp) { if (!resp) {
ql_dbg(ql_dbg_tgt, vha, 0xe04a, ql_dbg(ql_dbg_tgt, vha, 0xe04a,
"qla_target(%d): %s failed: unable to allocate " "qla_target(%d): %s failed: unable to allocate "
...@@ -1698,7 +1699,7 @@ static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha, ...@@ -1698,7 +1699,7 @@ static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha,
/* Memory Barrier */ /* Memory Barrier */
wmb(); wmb();
qla2x00_start_iocbs(vha, vha->req); qla2x00_start_iocbs(vha, qpair->req);
} }
/* /*
...@@ -1711,11 +1712,9 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha, ...@@ -1711,11 +1712,9 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_tgt, vha, 0xe007, ql_dbg(ql_dbg_tgt, vha, 0xe007,
"Sending retry TERM EXCH CTIO7 (ha=%p)\n", vha->hw); "Sending retry TERM EXCH CTIO7 (ha=%p)\n", vha->hw);
/* Send marker if required */
if (qlt_issue_marker(vha, 1) != QLA_SUCCESS)
return;
ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs_ready(vha, NULL); ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs_ready(
vha->hw->base_qpair, NULL);
if (ctio == NULL) { if (ctio == NULL) {
ql_dbg(ql_dbg_tgt, vha, 0xe04b, ql_dbg(ql_dbg_tgt, vha, 0xe04b,
"qla_target(%d): %s failed: unable to allocate " "qla_target(%d): %s failed: unable to allocate "
...@@ -1746,7 +1745,8 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha, ...@@ -1746,7 +1745,8 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
wmb(); wmb();
qla2x00_start_iocbs(vha, vha->req); qla2x00_start_iocbs(vha, vha->req);
qlt_24xx_send_abts_resp(vha, (struct abts_recv_from_24xx *)entry, qlt_24xx_send_abts_resp(vha->hw->base_qpair,
(struct abts_recv_from_24xx *)entry,
FCP_TMF_CMPL, true); FCP_TMF_CMPL, true);
} }
...@@ -1861,7 +1861,8 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha, ...@@ -1861,7 +1861,8 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
if (!found_lun) { if (!found_lun) {
if (abort_cmd_for_tag(vha, abts->exchange_addr_to_abort)) { if (abort_cmd_for_tag(vha, abts->exchange_addr_to_abort)) {
/* send TASK_ABORT response immediately */ /* send TASK_ABORT response immediately */
qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_CMPL, false); qlt_24xx_send_abts_resp(ha->base_qpair, abts,
FCP_TMF_CMPL, false);
return 0; return 0;
} else { } else {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf081, ql_dbg(ql_dbg_tgt_mgt, vha, 0xf081,
...@@ -1889,6 +1890,7 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha, ...@@ -1889,6 +1890,7 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
memcpy(&mcmd->orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts)); memcpy(&mcmd->orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts));
mcmd->reset_count = vha->hw->chip_reset; mcmd->reset_count = vha->hw->chip_reset;
mcmd->tmr_func = QLA_TGT_ABTS; mcmd->tmr_func = QLA_TGT_ABTS;
mcmd->qpair = ha->base_qpair;
rc = ha->tgt.tgt_ops->handle_tmr(mcmd, cmd->unpacked_lun, mcmd->tmr_func, rc = ha->tgt.tgt_ops->handle_tmr(mcmd, cmd->unpacked_lun, mcmd->tmr_func,
abts->exchange_addr_to_abort); abts->exchange_addr_to_abort);
...@@ -1920,7 +1922,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, ...@@ -1920,7 +1922,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf053, ql_dbg(ql_dbg_tgt_mgt, vha, 0xf053,
"qla_target(%d): ABTS: Abort Sequence not " "qla_target(%d): ABTS: Abort Sequence not "
"supported\n", vha->vp_idx); "supported\n", vha->vp_idx);
qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false); qlt_24xx_send_abts_resp(ha->base_qpair, abts, FCP_TMF_REJECTED,
false);
return; return;
} }
...@@ -1928,7 +1931,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, ...@@ -1928,7 +1931,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf010, ql_dbg(ql_dbg_tgt_mgt, vha, 0xf010,
"qla_target(%d): ABTS: Unknown Exchange " "qla_target(%d): ABTS: Unknown Exchange "
"Address received\n", vha->vp_idx); "Address received\n", vha->vp_idx);
qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false); qlt_24xx_send_abts_resp(ha->base_qpair, abts, FCP_TMF_REJECTED,
false);
return; return;
} }
...@@ -1954,8 +1958,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, ...@@ -1954,8 +1958,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
if (rc != 0) { if (rc != 0) {
qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, qlt_24xx_send_abts_resp(ha->base_qpair, abts,
false); FCP_TMF_REJECTED, false);
} }
return; return;
} }
...@@ -1963,7 +1967,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, ...@@ -1963,7 +1967,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
if (sess->deleted) { if (sess->deleted) {
qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false); qlt_24xx_send_abts_resp(ha->base_qpair, abts, FCP_TMF_REJECTED,
false);
return; return;
} }
...@@ -1972,7 +1977,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, ...@@ -1972,7 +1977,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf054, ql_dbg(ql_dbg_tgt_mgt, vha, 0xf054,
"qla_target(%d): __qlt_24xx_handle_abts() failed: %d\n", "qla_target(%d): __qlt_24xx_handle_abts() failed: %d\n",
vha->vp_idx, rc); vha->vp_idx, rc);
qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false); qlt_24xx_send_abts_resp(ha->base_qpair, abts, FCP_TMF_REJECTED,
false);
return; return;
} }
} }
...@@ -1980,9 +1986,10 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, ...@@ -1980,9 +1986,10 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
/* /*
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
*/ */
static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha, static void qlt_24xx_send_task_mgmt_ctio(struct qla_qpair *qpair,
struct qla_tgt_mgmt_cmd *mcmd, uint32_t resp_code) struct qla_tgt_mgmt_cmd *mcmd, uint32_t resp_code)
{ {
struct scsi_qla_host *ha = qpair->vha;
struct atio_from_isp *atio = &mcmd->orig_iocb.atio; struct atio_from_isp *atio = &mcmd->orig_iocb.atio;
struct ctio7_to_24xx *ctio; struct ctio7_to_24xx *ctio;
uint16_t temp; uint16_t temp;
...@@ -1991,11 +1998,8 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha, ...@@ -1991,11 +1998,8 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha,
"Sending task mgmt CTIO7 (ha=%p, atio=%p, resp_code=%x\n", "Sending task mgmt CTIO7 (ha=%p, atio=%p, resp_code=%x\n",
ha, atio, resp_code); ha, atio, resp_code);
/* Send marker if required */
if (qlt_issue_marker(ha, 1) != QLA_SUCCESS)
return;
ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs(ha, NULL); ctio = (struct ctio7_to_24xx *)__qla2x00_alloc_iocbs(qpair, NULL);
if (ctio == NULL) { if (ctio == NULL) {
ql_dbg(ql_dbg_tgt, ha, 0xe04c, ql_dbg(ql_dbg_tgt, ha, 0xe04c,
"qla_target(%d): %s failed: unable to allocate " "qla_target(%d): %s failed: unable to allocate "
...@@ -2025,7 +2029,7 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha, ...@@ -2025,7 +2029,7 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha,
/* Memory Barrier */ /* Memory Barrier */
wmb(); wmb();
qla2x00_start_iocbs(ha, ha->req); qla2x00_start_iocbs(ha, qpair->req);
} }
void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd) void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd)
...@@ -2105,12 +2109,13 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd) ...@@ -2105,12 +2109,13 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
struct scsi_qla_host *vha = mcmd->sess->vha; struct scsi_qla_host *vha = mcmd->sess->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
unsigned long flags; unsigned long flags;
struct qla_qpair *qpair = mcmd->qpair;
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf013, ql_dbg(ql_dbg_tgt_mgt, vha, 0xf013,
"TM response mcmd (%p) status %#x state %#x", "TM response mcmd (%p) status %#x state %#x",
mcmd, mcmd->fc_tm_rsp, mcmd->flags); mcmd, mcmd->fc_tm_rsp, mcmd->flags);
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(qpair->qp_lock_ptr, flags);
if (!vha->flags.online || mcmd->reset_count != ha->chip_reset) { if (!vha->flags.online || mcmd->reset_count != ha->chip_reset) {
/* /*
...@@ -2122,7 +2127,7 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd) ...@@ -2122,7 +2127,7 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
vha->flags.online, qla2x00_reset_active(vha), vha->flags.online, qla2x00_reset_active(vha),
mcmd->reset_count, ha->chip_reset); mcmd->reset_count, ha->chip_reset);
ha->tgt.tgt_ops->free_mcmd(mcmd); ha->tgt.tgt_ops->free_mcmd(mcmd);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return; return;
} }
...@@ -2139,15 +2144,15 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd) ...@@ -2139,15 +2144,15 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
mcmd->flags); mcmd->flags);
qlt_schedule_sess_for_deletion_lock(mcmd->sess); qlt_schedule_sess_for_deletion_lock(mcmd->sess);
} else { } else {
qlt_send_notify_ack(vha, &mcmd->orig_iocb.imm_ntfy, qlt_send_notify_ack(vha->hw->base_qpair,
0, 0, 0, 0, 0, 0); &mcmd->orig_iocb.imm_ntfy, 0, 0, 0, 0, 0, 0);
} }
} else { } else {
if (mcmd->orig_iocb.atio.u.raw.entry_type == ABTS_RECV_24XX) if (mcmd->orig_iocb.atio.u.raw.entry_type == ABTS_RECV_24XX)
qlt_24xx_send_abts_resp(vha, &mcmd->orig_iocb.abts, qlt_24xx_send_abts_resp(qpair, &mcmd->orig_iocb.abts,
mcmd->fc_tm_rsp, false); mcmd->fc_tm_rsp, false);
else else
qlt_24xx_send_task_mgmt_ctio(vha, mcmd, qlt_24xx_send_task_mgmt_ctio(qpair, mcmd,
mcmd->fc_tm_rsp); mcmd->fc_tm_rsp);
} }
/* /*
...@@ -2159,7 +2164,7 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd) ...@@ -2159,7 +2164,7 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
* qlt_xmit_tm_rsp() returns here.. * qlt_xmit_tm_rsp() returns here..
*/ */
ha->tgt.tgt_ops->free_mcmd(mcmd); ha->tgt.tgt_ops->free_mcmd(mcmd);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
} }
EXPORT_SYMBOL(qlt_xmit_tm_rsp); EXPORT_SYMBOL(qlt_xmit_tm_rsp);
...@@ -2247,25 +2252,25 @@ static void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) ...@@ -2247,25 +2252,25 @@ static void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
dma_pool_free(ha->dl_dma_pool, cmd->ctx, cmd->ctx->crc_ctx_dma); dma_pool_free(ha->dl_dma_pool, cmd->ctx, cmd->ctx->crc_ctx_dma);
} }
static int qlt_check_reserve_free_req(struct scsi_qla_host *vha, static int qlt_check_reserve_free_req(struct qla_qpair *qpair,
uint32_t req_cnt) uint32_t req_cnt)
{ {
uint32_t cnt; uint32_t cnt;
struct req_que *req = qpair->req;
if (vha->req->cnt < (req_cnt + 2)) { if (req->cnt < (req_cnt + 2)) {
cnt = (uint16_t)RD_REG_DWORD(vha->req->req_q_out); cnt = (uint16_t)RD_REG_DWORD(req->req_q_out);
if (vha->req->ring_index < cnt) if (req->ring_index < cnt)
vha->req->cnt = cnt - vha->req->ring_index; req->cnt = cnt - req->ring_index;
else else
vha->req->cnt = vha->req->length - req->cnt = req->length - (req->ring_index - cnt);
(vha->req->ring_index - cnt);
if (unlikely(vha->req->cnt < (req_cnt + 2))) if (unlikely(req->cnt < (req_cnt + 2)))
return -EAGAIN; return -EAGAIN;
} }
vha->req->cnt -= req_cnt; req->cnt -= req_cnt;
return 0; return 0;
} }
...@@ -2273,26 +2278,27 @@ static int qlt_check_reserve_free_req(struct scsi_qla_host *vha, ...@@ -2273,26 +2278,27 @@ static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,
/* /*
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
*/ */
static inline void *qlt_get_req_pkt(struct scsi_qla_host *vha) static inline void *qlt_get_req_pkt(struct req_que *req)
{ {
/* Adjust ring index. */ /* Adjust ring index. */
vha->req->ring_index++; req->ring_index++;
if (vha->req->ring_index == vha->req->length) { if (req->ring_index == req->length) {
vha->req->ring_index = 0; req->ring_index = 0;
vha->req->ring_ptr = vha->req->ring; req->ring_ptr = req->ring;
} else { } else {
vha->req->ring_ptr++; req->ring_ptr++;
} }
return (cont_entry_t *)vha->req->ring_ptr; return (cont_entry_t *)req->ring_ptr;
} }
/* ha->hardware_lock supposed to be held on entry */ /* ha->hardware_lock supposed to be held on entry */
static inline uint32_t qlt_make_handle(struct scsi_qla_host *vha) static inline uint32_t qlt_make_handle(struct qla_qpair *qpair)
{ {
struct scsi_qla_host *vha = qpair->vha;
uint32_t h; uint32_t h;
int index; int index;
uint8_t found = 0; uint8_t found = 0;
struct req_que *req = vha->req; struct req_que *req = qpair->req;
h = req->current_outstanding_cmd; h = req->current_outstanding_cmd;
...@@ -2323,15 +2329,16 @@ static inline uint32_t qlt_make_handle(struct scsi_qla_host *vha) ...@@ -2323,15 +2329,16 @@ static inline uint32_t qlt_make_handle(struct scsi_qla_host *vha)
} }
/* ha->hardware_lock supposed to be held on entry */ /* ha->hardware_lock supposed to be held on entry */
static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm, static int qlt_24xx_build_ctio_pkt(struct qla_qpair *qpair,
struct scsi_qla_host *vha) struct qla_tgt_prm *prm)
{ {
uint32_t h; uint32_t h;
struct ctio7_to_24xx *pkt; struct ctio7_to_24xx *pkt;
struct atio_from_isp *atio = &prm->cmd->atio; struct atio_from_isp *atio = &prm->cmd->atio;
uint16_t temp; uint16_t temp;
struct scsi_qla_host *vha = prm->cmd->vha;
pkt = (struct ctio7_to_24xx *)vha->req->ring_ptr; pkt = (struct ctio7_to_24xx *)qpair->req->ring_ptr;
prm->pkt = pkt; prm->pkt = pkt;
memset(pkt, 0, sizeof(*pkt)); memset(pkt, 0, sizeof(*pkt));
...@@ -2339,7 +2346,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm, ...@@ -2339,7 +2346,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm,
pkt->entry_count = (uint8_t)prm->req_cnt; pkt->entry_count = (uint8_t)prm->req_cnt;
pkt->vp_index = vha->vp_idx; pkt->vp_index = vha->vp_idx;
h = qlt_make_handle(vha); h = qlt_make_handle(qpair);
if (unlikely(h == QLA_TGT_NULL_HANDLE)) { if (unlikely(h == QLA_TGT_NULL_HANDLE)) {
/* /*
* CTIO type 7 from the firmware doesn't provide a way to * CTIO type 7 from the firmware doesn't provide a way to
...@@ -2351,8 +2358,9 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm, ...@@ -2351,8 +2358,9 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm,
vha->req->outstanding_cmds[h] = (srb_t *)prm->cmd; vha->req->outstanding_cmds[h] = (srb_t *)prm->cmd;
} }
pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK; pkt->handle = MAKE_HANDLE(qpair->req->id, h);
pkt->nport_handle = prm->cmd->loop_id; 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->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; 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[1] = atio->u.isp24.fcp_hdr.s_id[1];
...@@ -2381,7 +2389,8 @@ static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm, ...@@ -2381,7 +2389,8 @@ static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm,
/* Build continuation packets */ /* Build continuation packets */
while (prm->seg_cnt > 0) { while (prm->seg_cnt > 0) {
cont_a64_entry_t *cont_pkt64 = cont_a64_entry_t *cont_pkt64 =
(cont_a64_entry_t *)qlt_get_req_pkt(vha); (cont_a64_entry_t *)qlt_get_req_pkt(
prm->cmd->qpair->req);
/* /*
* Make sure that from cont_pkt64 none of * Make sure that from cont_pkt64 none of
...@@ -2546,10 +2555,6 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd, ...@@ -2546,10 +2555,6 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
prm->req_cnt = 1; prm->req_cnt = 1;
prm->add_status_pkt = 0; prm->add_status_pkt = 0;
/* Send marker if required */
if (qlt_issue_marker(vha, 0) != QLA_SUCCESS)
return -EFAULT;
if ((xmit_type & QLA_TGT_XMIT_DATA) && qlt_has_data(cmd)) { if ((xmit_type & QLA_TGT_XMIT_DATA) && qlt_has_data(cmd)) {
if (qlt_pci_map_calc_cnt(prm) != 0) if (qlt_pci_map_calc_cnt(prm) != 0)
return -EAGAIN; return -EAGAIN;
...@@ -2791,7 +2796,7 @@ qla_tgt_set_dif_tags(struct qla_tgt_cmd *cmd, struct crc_context *ctx, ...@@ -2791,7 +2796,7 @@ qla_tgt_set_dif_tags(struct qla_tgt_cmd *cmd, struct crc_context *ctx,
} }
static inline int static inline int
qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm)
{ {
uint32_t *cur_dsd; uint32_t *cur_dsd;
uint32_t transfer_length = 0; uint32_t transfer_length = 0;
...@@ -2810,10 +2815,11 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) ...@@ -2810,10 +2815,11 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha)
struct atio_from_isp *atio = &prm->cmd->atio; struct atio_from_isp *atio = &prm->cmd->atio;
struct qla_tc_param tc; struct qla_tc_param tc;
uint16_t t16; uint16_t t16;
scsi_qla_host_t *vha = cmd->vha;
ha = vha->hw; ha = vha->hw;
pkt = (struct ctio_crc2_to_fw *)vha->req->ring_ptr; pkt = (struct ctio_crc2_to_fw *)qpair->req->ring_ptr;
prm->pkt = pkt; prm->pkt = pkt;
memset(pkt, 0, sizeof(*pkt)); memset(pkt, 0, sizeof(*pkt));
...@@ -2884,7 +2890,7 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) ...@@ -2884,7 +2890,7 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha)
pkt->entry_count = 1; pkt->entry_count = 1;
pkt->vp_index = vha->vp_idx; pkt->vp_index = vha->vp_idx;
h = qlt_make_handle(vha); h = qlt_make_handle(qpair);
if (unlikely(h == QLA_TGT_NULL_HANDLE)) { if (unlikely(h == QLA_TGT_NULL_HANDLE)) {
/* /*
* CTIO type 7 from the firmware doesn't provide a way to * CTIO type 7 from the firmware doesn't provide a way to
...@@ -2893,9 +2899,10 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) ...@@ -2893,9 +2899,10 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha)
*/ */
return -EAGAIN; return -EAGAIN;
} else } else
vha->req->outstanding_cmds[h] = (srb_t *)prm->cmd; qpair->req->outstanding_cmds[h] = (srb_t *)prm->cmd;
pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK; pkt->handle = MAKE_HANDLE(qpair->req->id, h);
pkt->handle |= CTIO_COMPLETION_HANDLE_MARK;
pkt->nport_handle = cpu_to_le16(prm->cmd->loop_id); pkt->nport_handle = cpu_to_le16(prm->cmd->loop_id);
pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
...@@ -2999,7 +3006,7 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) ...@@ -2999,7 +3006,7 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha)
crc_queuing_error: crc_queuing_error:
/* Cleanup will be performed by the caller */ /* Cleanup will be performed by the caller */
vha->req->outstanding_cmds[h] = NULL; qpair->req->outstanding_cmds[h] = NULL;
return QLA_FUNCTION_FAILED; return QLA_FUNCTION_FAILED;
} }
...@@ -3013,32 +3020,30 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, ...@@ -3013,32 +3020,30 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
{ {
struct scsi_qla_host *vha = cmd->vha; struct scsi_qla_host *vha = cmd->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct qla_qpair *qpair = cmd->qpair;
struct ctio7_to_24xx *pkt; struct ctio7_to_24xx *pkt;
struct qla_tgt_prm prm; struct qla_tgt_prm prm;
uint32_t full_req_cnt = 0; uint32_t full_req_cnt = 0;
unsigned long flags = 0; unsigned long flags = 0;
int res; int res;
spin_lock_irqsave(&ha->hardware_lock, flags);
if (cmd->sess && cmd->sess->deleted) { if (cmd->sess && cmd->sess->deleted) {
cmd->state = QLA_TGT_STATE_PROCESSED; cmd->state = QLA_TGT_STATE_PROCESSED;
if (cmd->sess->logout_completed) if (cmd->sess->logout_completed)
/* no need to terminate. FW already freed exchange. */ /* no need to terminate. FW already freed exchange. */
qlt_abort_cmd_on_host_reset(cmd->vha, cmd); qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
else else
qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0); qlt_send_term_exchange(qpair, cmd, &cmd->atio, 0, 0);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return 0; return 0;
} }
spin_unlock_irqrestore(&ha->hardware_lock, flags);
memset(&prm, 0, sizeof(prm)); memset(&prm, 0, sizeof(prm));
ql_dbg(ql_dbg_tgt, cmd->vha, 0xe018, ql_dbg(ql_dbg_tgt, cmd->vha, 0xe018,
"is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, cmd->dma_data_direction=%d se_cmd[%p]\n", "is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, cmd->dma_data_direction=%d se_cmd[%p] qp %d\n",
(xmit_type & QLA_TGT_XMIT_STATUS) ? (xmit_type & QLA_TGT_XMIT_STATUS) ?
1 : 0, cmd->bufflen, cmd->sg_cnt, cmd->dma_data_direction, 1 : 0, cmd->bufflen, cmd->sg_cnt, cmd->dma_data_direction,
&cmd->se_cmd); &cmd->se_cmd, qpair->id);
res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status,
&full_req_cnt); &full_req_cnt);
...@@ -3046,7 +3051,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, ...@@ -3046,7 +3051,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
return res; return res;
} }
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(qpair->qp_lock_ptr, flags);
if (xmit_type == QLA_TGT_XMIT_STATUS) if (xmit_type == QLA_TGT_XMIT_STATUS)
vha->tgt_counters.core_qla_snd_status++; vha->tgt_counters.core_qla_snd_status++;
...@@ -3064,21 +3069,21 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, ...@@ -3064,21 +3069,21 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
"RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n", "RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n",
vha->flags.online, qla2x00_reset_active(vha), vha->flags.online, qla2x00_reset_active(vha),
cmd->reset_count, ha->chip_reset); cmd->reset_count, ha->chip_reset);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return 0; return 0;
} }
/* Does F/W have an IOCBs for this request */ /* Does F/W have an IOCBs for this request */
res = qlt_check_reserve_free_req(vha, full_req_cnt); res = qlt_check_reserve_free_req(qpair, full_req_cnt);
if (unlikely(res)) if (unlikely(res))
goto out_unmap_unlock; goto out_unmap_unlock;
if (cmd->se_cmd.prot_op && (xmit_type & QLA_TGT_XMIT_DATA)) if (cmd->se_cmd.prot_op && (xmit_type & QLA_TGT_XMIT_DATA))
res = qlt_build_ctio_crc2_pkt(&prm, vha); res = qlt_build_ctio_crc2_pkt(qpair, &prm);
else else
res = qlt_24xx_build_ctio_pkt(&prm, vha); res = qlt_24xx_build_ctio_pkt(qpair, &prm);
if (unlikely(res != 0)) { if (unlikely(res != 0)) {
vha->req->cnt += full_req_cnt; qpair->req->cnt += full_req_cnt;
goto out_unmap_unlock; goto out_unmap_unlock;
} }
...@@ -3115,9 +3120,10 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, ...@@ -3115,9 +3120,10 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
* req_pkt(). * req_pkt().
*/ */
struct ctio7_to_24xx *ctio = struct ctio7_to_24xx *ctio =
(struct ctio7_to_24xx *)qlt_get_req_pkt(vha); (struct ctio7_to_24xx *)qlt_get_req_pkt(
qpair->req);
ql_dbg(ql_dbg_io, vha, 0x305e, ql_dbg(ql_dbg_tgt, vha, 0x305e,
"Building additional status packet 0x%p.\n", "Building additional status packet 0x%p.\n",
ctio); ctio);
...@@ -3155,14 +3161,14 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, ...@@ -3155,14 +3161,14 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
/* Memory Barrier */ /* Memory Barrier */
wmb(); wmb();
qla2x00_start_iocbs(vha, vha->req); qla2x00_start_iocbs(vha, qpair->req);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return 0; return 0;
out_unmap_unlock: out_unmap_unlock:
qlt_unmap_sg(vha, cmd); qlt_unmap_sg(vha, cmd);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return res; return res;
} }
...@@ -3175,8 +3181,9 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) ...@@ -3175,8 +3181,9 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct qla_tgt *tgt = cmd->tgt; struct qla_tgt *tgt = cmd->tgt;
struct qla_tgt_prm prm; struct qla_tgt_prm prm;
unsigned long flags; unsigned long flags = 0;
int res = 0; int res = 0;
struct qla_qpair *qpair = cmd->qpair;
memset(&prm, 0, sizeof(prm)); memset(&prm, 0, sizeof(prm));
prm.cmd = cmd; prm.cmd = cmd;
...@@ -3184,16 +3191,10 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) ...@@ -3184,16 +3191,10 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
prm.sg = NULL; prm.sg = NULL;
prm.req_cnt = 1; prm.req_cnt = 1;
/* Send marker if required */
if (qlt_issue_marker(vha, 0) != QLA_SUCCESS)
return -EIO;
/* Calculate number of entries and segments required */ /* Calculate number of entries and segments required */
if (qlt_pci_map_calc_cnt(&prm) != 0) if (qlt_pci_map_calc_cnt(&prm) != 0)
return -EAGAIN; return -EAGAIN;
spin_lock_irqsave(&ha->hardware_lock, flags);
if (!ha->flags.fw_started || (cmd->reset_count != ha->chip_reset) || if (!ha->flags.fw_started || (cmd->reset_count != ha->chip_reset) ||
(cmd->sess && cmd->sess->deleted)) { (cmd->sess && cmd->sess->deleted)) {
/* /*
...@@ -3206,21 +3207,21 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) ...@@ -3206,21 +3207,21 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
"RESET-XFR online/active/old-count/new-count = %d/%d/%d/%d.\n", "RESET-XFR online/active/old-count/new-count = %d/%d/%d/%d.\n",
vha->flags.online, qla2x00_reset_active(vha), vha->flags.online, qla2x00_reset_active(vha),
cmd->reset_count, ha->chip_reset); cmd->reset_count, ha->chip_reset);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return 0; return 0;
} }
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
/* Does F/W have an IOCBs for this request */ /* Does F/W have an IOCBs for this request */
res = qlt_check_reserve_free_req(vha, prm.req_cnt); res = qlt_check_reserve_free_req(qpair, prm.req_cnt);
if (res != 0) if (res != 0)
goto out_unlock_free_unmap; goto out_unlock_free_unmap;
if (cmd->se_cmd.prot_op) if (cmd->se_cmd.prot_op)
res = qlt_build_ctio_crc2_pkt(&prm, vha); res = qlt_build_ctio_crc2_pkt(qpair, &prm);
else else
res = qlt_24xx_build_ctio_pkt(&prm, vha); res = qlt_24xx_build_ctio_pkt(qpair, &prm);
if (unlikely(res != 0)) { if (unlikely(res != 0)) {
vha->req->cnt += prm.req_cnt; qpair->req->cnt += prm.req_cnt;
goto out_unlock_free_unmap; goto out_unlock_free_unmap;
} }
...@@ -3236,14 +3237,14 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) ...@@ -3236,14 +3237,14 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
/* Memory Barrier */ /* Memory Barrier */
wmb(); wmb();
qla2x00_start_iocbs(vha, vha->req); qla2x00_start_iocbs(vha, qpair->req);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return res; return res;
out_unlock_free_unmap: out_unlock_free_unmap:
qlt_unmap_sg(vha, cmd); qlt_unmap_sg(vha, cmd);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return res; return res;
} }
...@@ -3408,9 +3409,6 @@ static void qlt_send_term_imm_notif(struct scsi_qla_host *vha, ...@@ -3408,9 +3409,6 @@ static void qlt_send_term_imm_notif(struct scsi_qla_host *vha,
unsigned long flags = 0; unsigned long flags = 0;
int rc; int rc;
if (qlt_issue_marker(vha, ha_locked) < 0)
return;
if (ha_locked) { if (ha_locked) {
rc = __qlt_send_term_imm_notif(vha, imm); rc = __qlt_send_term_imm_notif(vha, imm);
...@@ -3441,10 +3439,11 @@ static void qlt_send_term_imm_notif(struct scsi_qla_host *vha, ...@@ -3441,10 +3439,11 @@ static void qlt_send_term_imm_notif(struct scsi_qla_host *vha,
* If hardware_lock held on entry, might drop it, then reaquire * If hardware_lock held on entry, might drop it, then reaquire
* This function sends the appropriate CTIO to ISP 2xxx or 24xx * This function sends the appropriate CTIO to ISP 2xxx or 24xx
*/ */
static int __qlt_send_term_exchange(struct scsi_qla_host *vha, static int __qlt_send_term_exchange(struct qla_qpair *qpair,
struct qla_tgt_cmd *cmd, struct qla_tgt_cmd *cmd,
struct atio_from_isp *atio) struct atio_from_isp *atio)
{ {
struct scsi_qla_host *vha = qpair->vha;
struct ctio7_to_24xx *ctio24; struct ctio7_to_24xx *ctio24;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
request_t *pkt; request_t *pkt;
...@@ -3453,7 +3452,7 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha, ...@@ -3453,7 +3452,7 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_tgt, vha, 0xe009, "Sending TERM EXCH CTIO (ha=%p)\n", ha); ql_dbg(ql_dbg_tgt, vha, 0xe009, "Sending TERM EXCH CTIO (ha=%p)\n", ha);
pkt = (request_t *)qla2x00_alloc_iocbs_ready(vha, NULL); pkt = (request_t *)qla2x00_alloc_iocbs_ready(qpair, NULL);
if (pkt == NULL) { if (pkt == NULL) {
ql_dbg(ql_dbg_tgt, vha, 0xe050, ql_dbg(ql_dbg_tgt, vha, 0xe050,
"qla_target(%d): %s failed: unable to allocate " "qla_target(%d): %s failed: unable to allocate "
...@@ -3499,28 +3498,32 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha, ...@@ -3499,28 +3498,32 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
/* Memory Barrier */ /* Memory Barrier */
wmb(); wmb();
qla2x00_start_iocbs(vha, vha->req); qla2x00_start_iocbs(vha, qpair->req);
return ret; return ret;
} }
static void qlt_send_term_exchange(struct scsi_qla_host *vha, static void qlt_send_term_exchange(struct qla_qpair *qpair,
struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked, struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked,
int ul_abort) int ul_abort)
{ {
struct scsi_qla_host *vha;
unsigned long flags = 0; unsigned long flags = 0;
int rc; int rc;
if (qlt_issue_marker(vha, ha_locked) < 0) /* why use different vha? NPIV */
return; if (cmd)
vha = cmd->vha;
else
vha = qpair->vha;
if (ha_locked) { if (ha_locked) {
rc = __qlt_send_term_exchange(vha, cmd, atio); rc = __qlt_send_term_exchange(qpair, cmd, atio);
if (rc == -ENOMEM) if (rc == -ENOMEM)
qlt_alloc_qfull_cmd(vha, atio, 0, 0); qlt_alloc_qfull_cmd(vha, atio, 0, 0);
goto done; goto done;
} }
spin_lock_irqsave(&vha->hw->hardware_lock, flags); spin_lock_irqsave(qpair->qp_lock_ptr, flags);
rc = __qlt_send_term_exchange(vha, cmd, atio); rc = __qlt_send_term_exchange(qpair, cmd, atio);
if (rc == -ENOMEM) if (rc == -ENOMEM)
qlt_alloc_qfull_cmd(vha, atio, 0, 0); qlt_alloc_qfull_cmd(vha, atio, 0, 0);
...@@ -3532,7 +3535,7 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha, ...@@ -3532,7 +3535,7 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha,
} }
if (!ha_locked) if (!ha_locked)
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return; return;
} }
...@@ -3614,7 +3617,7 @@ int qlt_abort_cmd(struct qla_tgt_cmd *cmd) ...@@ -3614,7 +3617,7 @@ int qlt_abort_cmd(struct qla_tgt_cmd *cmd)
cmd->trc_flags |= TRC_ABORT; cmd->trc_flags |= TRC_ABORT;
spin_unlock_irqrestore(&cmd->cmd_lock, flags); spin_unlock_irqrestore(&cmd->cmd_lock, flags);
qlt_send_term_exchange(vha, cmd, &cmd->atio, 0, 1); qlt_send_term_exchange(cmd->qpair, cmd, &cmd->atio, 0, 1);
return 0; return 0;
} }
EXPORT_SYMBOL(qlt_abort_cmd); EXPORT_SYMBOL(qlt_abort_cmd);
...@@ -3653,10 +3656,11 @@ EXPORT_SYMBOL(qlt_free_cmd); ...@@ -3653,10 +3656,11 @@ EXPORT_SYMBOL(qlt_free_cmd);
/* /*
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
*/ */
static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio, static int qlt_term_ctio_exchange(struct qla_qpair *qpair, void *ctio,
struct qla_tgt_cmd *cmd, uint32_t status) struct qla_tgt_cmd *cmd, uint32_t status)
{ {
int term = 0; int term = 0;
struct scsi_qla_host *vha = qpair->vha;
if (cmd->se_cmd.prot_op) if (cmd->se_cmd.prot_op)
ql_dbg(ql_dbg_tgt_dif, vha, 0xe013, ql_dbg(ql_dbg_tgt_dif, vha, 0xe013,
...@@ -3676,7 +3680,7 @@ static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio, ...@@ -3676,7 +3680,7 @@ static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio,
term = 1; term = 1;
if (term) if (term)
qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0); qlt_term_ctio_exchange(qpair, ctio, cmd, status);
return term; return term;
} }
...@@ -3684,35 +3688,45 @@ static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio, ...@@ -3684,35 +3688,45 @@ static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio,
/* ha->hardware_lock supposed to be held on entry */ /* ha->hardware_lock supposed to be held on entry */
static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha, static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha,
uint32_t handle, void *ctio) struct rsp_que *rsp, uint32_t handle, void *ctio)
{ {
struct qla_tgt_cmd *cmd = NULL; struct qla_tgt_cmd *cmd = NULL;
struct req_que *req = vha->req; struct req_que *req;
int qid = GET_QID(handle);
uint32_t h = handle & ~QLA_TGT_HANDLE_MASK;
/* Clear out internal marks */ if (unlikely(h == QLA_TGT_SKIP_HANDLE))
handle &= ~QLA_TGT_HANDLE_MASK; return NULL;
if (handle != QLA_TGT_NULL_HANDLE) { if (qid == rsp->req->id) {
if (unlikely(handle == QLA_TGT_SKIP_HANDLE)) req = rsp->req;
return NULL; } else if (vha->hw->req_q_map[qid]) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0x1000a,
"qla_target(%d): CTIO completion with different QID %d handle %x\n",
vha->vp_idx, rsp->id, handle);
req = vha->hw->req_q_map[qid];
} else {
return NULL;
}
handle &= QLA_CMD_HANDLE_MASK; h &= QLA_CMD_HANDLE_MASK;
if (unlikely(handle > req->num_outstanding_cmds)) { if (h != QLA_TGT_NULL_HANDLE) {
if (unlikely(h > req->num_outstanding_cmds)) {
ql_dbg(ql_dbg_tgt, vha, 0xe052, ql_dbg(ql_dbg_tgt, vha, 0xe052,
"qla_target(%d): Wrong handle %x received\n", "qla_target(%d): Wrong handle %x received\n",
vha->vp_idx, handle); vha->vp_idx, handle);
return NULL; return NULL;
} }
cmd = (struct qla_tgt_cmd *)req->outstanding_cmds[handle];
if (unlikely((cmd == NULL) || cmd = (struct qla_tgt_cmd *)req->outstanding_cmds[h];
(cmd->cmd_type != TYPE_TGT_CMD))) { if (unlikely(cmd == NULL)) {
ql_dbg(ql_dbg_async, vha, 0xe053, ql_dbg(ql_dbg_async, vha, 0xe053,
"qla_target(%d): Suspicious: unable to find the command with handle %x cmd %p\n", "qla_target(%d): Suspicious: unable to find the command with handle %x req->id %d rsp->id %d\n",
vha->vp_idx, handle, cmd); vha->vp_idx, handle, req->id, rsp->id);
return NULL; return NULL;
} }
req->outstanding_cmds[handle] = NULL; req->outstanding_cmds[h] = NULL;
} else if (ctio != NULL) { } else if (ctio != NULL) {
/* We can't get loop ID from CTIO7 */ /* We can't get loop ID from CTIO7 */
ql_dbg(ql_dbg_tgt, vha, 0xe054, ql_dbg(ql_dbg_tgt, vha, 0xe054,
...@@ -3729,29 +3743,26 @@ void ...@@ -3729,29 +3743,26 @@ void
qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
{ {
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
uint32_t handle;
if (cmd->sg_mapped) if (cmd->sg_mapped)
qlt_unmap_sg(vha, cmd); qlt_unmap_sg(vha, cmd);
handle = qlt_make_handle(vha);
/* TODO: fix debug message type and ids. */ /* TODO: fix debug message type and ids. */
if (cmd->state == QLA_TGT_STATE_PROCESSED) { if (cmd->state == QLA_TGT_STATE_PROCESSED) {
ql_dbg(ql_dbg_io, vha, 0xff00, ql_dbg(ql_dbg_io, vha, 0xff00,
"HOST-ABORT: handle=%d, state=PROCESSED.\n", handle); "HOST-ABORT: state=PROCESSED.\n");
} else if (cmd->state == QLA_TGT_STATE_NEED_DATA) { } else if (cmd->state == QLA_TGT_STATE_NEED_DATA) {
cmd->write_data_transferred = 0; cmd->write_data_transferred = 0;
cmd->state = QLA_TGT_STATE_DATA_IN; cmd->state = QLA_TGT_STATE_DATA_IN;
ql_dbg(ql_dbg_io, vha, 0xff01, ql_dbg(ql_dbg_io, vha, 0xff01,
"HOST-ABORT: handle=%d, state=DATA_IN.\n", handle); "HOST-ABORT: state=DATA_IN.\n");
ha->tgt.tgt_ops->handle_data(cmd); ha->tgt.tgt_ops->handle_data(cmd);
return; return;
} else { } else {
ql_dbg(ql_dbg_io, vha, 0xff03, ql_dbg(ql_dbg_io, vha, 0xff03,
"HOST-ABORT: handle=%d, state=BAD(%d).\n", handle, "HOST-ABORT: state=BAD(%d).\n",
cmd->state); cmd->state);
dump_stack(); dump_stack();
} }
...@@ -3763,12 +3774,13 @@ qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) ...@@ -3763,12 +3774,13 @@ qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
/* /*
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
*/ */
static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, static void qlt_do_ctio_completion(struct scsi_qla_host *vha,
uint32_t status, void *ctio) struct rsp_que *rsp, uint32_t handle, uint32_t status, void *ctio)
{ {
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct se_cmd *se_cmd; struct se_cmd *se_cmd;
struct qla_tgt_cmd *cmd; struct qla_tgt_cmd *cmd;
struct qla_qpair *qpair = rsp->qpair;
if (handle & CTIO_INTERMEDIATE_HANDLE_MARK) { if (handle & CTIO_INTERMEDIATE_HANDLE_MARK) {
/* That could happen only in case of an error/reset/abort */ /* That could happen only in case of an error/reset/abort */
...@@ -3780,7 +3792,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, ...@@ -3780,7 +3792,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
return; return;
} }
cmd = qlt_ctio_to_cmd(vha, handle, ctio); cmd = qlt_ctio_to_cmd(vha, rsp, handle, ctio);
if (cmd == NULL) if (cmd == NULL)
return; return;
...@@ -3864,7 +3876,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, ...@@ -3864,7 +3876,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
if ((cmd->state != QLA_TGT_STATE_NEED_DATA) && if ((cmd->state != QLA_TGT_STATE_NEED_DATA) &&
(!cmd->aborted)) { (!cmd->aborted)) {
cmd->trc_flags |= TRC_CTIO_ERR; cmd->trc_flags |= TRC_CTIO_ERR;
if (qlt_term_ctio_exchange(vha, ctio, cmd, status)) if (qlt_term_ctio_exchange(qpair, ctio, cmd, status))
return; return;
} }
} }
...@@ -3947,6 +3959,7 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd) ...@@ -3947,6 +3959,7 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
unsigned long flags; unsigned long flags;
uint32_t data_length; uint32_t data_length;
int ret, fcp_task_attr, data_dir, bidi = 0; int ret, fcp_task_attr, data_dir, bidi = 0;
struct qla_qpair *qpair = cmd->qpair;
cmd->cmd_in_wq = 0; cmd->cmd_in_wq = 0;
cmd->trc_flags |= TRC_DO_WORK; cmd->trc_flags |= TRC_DO_WORK;
...@@ -4002,12 +4015,12 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd) ...@@ -4002,12 +4015,12 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
* argument to qlt_send_term_exchange() and free the memory here. * argument to qlt_send_term_exchange() and free the memory here.
*/ */
cmd->trc_flags |= TRC_DO_WORK_ERR; cmd->trc_flags |= TRC_DO_WORK_ERR;
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(qpair->qp_lock_ptr, flags);
qlt_send_term_exchange(vha, NULL, &cmd->atio, 1, 0); qlt_send_term_exchange(qpair, NULL, &cmd->atio, 1, 0);
qlt_decr_num_pend_cmds(vha); qlt_decr_num_pend_cmds(vha);
percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag); percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
spin_lock_irqsave(&ha->tgt.sess_lock, flags); spin_lock_irqsave(&ha->tgt.sess_lock, flags);
ha->tgt.tgt_ops->put_sess(sess); ha->tgt.tgt_ops->put_sess(sess);
...@@ -4056,13 +4069,12 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha, ...@@ -4056,13 +4069,12 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
cmd->jiffies_at_alloc = get_jiffies_64(); cmd->jiffies_at_alloc = get_jiffies_64();
cmd->reset_count = vha->hw->chip_reset; cmd->reset_count = vha->hw->chip_reset;
cmd->qpair = vha->hw->base_qpair;
cmd->se_cmd.cpuid = cmd->qpair->cpuid;
return cmd; return cmd;
} }
static void qlt_send_busy(struct scsi_qla_host *, struct atio_from_isp *,
uint16_t);
static void qlt_create_sess_from_atio(struct work_struct *work) static void qlt_create_sess_from_atio(struct work_struct *work)
{ {
struct qla_tgt_sess_op *op = container_of(work, struct qla_tgt_sess_op *op = container_of(work,
...@@ -4108,10 +4120,15 @@ static void qlt_create_sess_from_atio(struct work_struct *work) ...@@ -4108,10 +4120,15 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
*/ */
cmd = qlt_get_tag(vha, sess, &op->atio); cmd = qlt_get_tag(vha, sess, &op->atio);
if (!cmd) { if (!cmd) {
spin_lock_irqsave(&ha->hardware_lock, flags); struct qla_qpair *qpair = ha->base_qpair;
qlt_send_busy(vha, &op->atio, SAM_STAT_BUSY);
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
qlt_send_busy(qpair, &op->atio, SAM_STAT_BUSY);
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
ha->tgt.tgt_ops->put_sess(sess); ha->tgt.tgt_ops->put_sess(sess);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
kfree(op); kfree(op);
return; return;
} }
...@@ -4124,9 +4141,7 @@ static void qlt_create_sess_from_atio(struct work_struct *work) ...@@ -4124,9 +4141,7 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
kfree(op); kfree(op);
return; return;
out_term: out_term:
spin_lock_irqsave(&ha->hardware_lock, flags); qlt_send_term_exchange(vha->hw->base_qpair, NULL, &op->atio, 0, 0);
qlt_send_term_exchange(vha, NULL, &op->atio, 1, 0);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
kfree(op); kfree(op);
} }
...@@ -4197,8 +4212,6 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, ...@@ -4197,8 +4212,6 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
cmd->cmd_in_wq = 1; cmd->cmd_in_wq = 1;
cmd->trc_flags |= TRC_NEW_CMD; cmd->trc_flags |= TRC_NEW_CMD;
cmd->se_cmd.cpuid = ha->msix_count ?
ha->tgt.rspq_vector_cpuid : WORK_CPU_UNBOUND;
spin_lock_irqsave(&vha->cmd_list_lock, flags); spin_lock_irqsave(&vha->cmd_list_lock, flags);
list_add_tail(&cmd->cmd_list, &vha->qla_cmd_list); list_add_tail(&cmd->cmd_list, &vha->qla_cmd_list);
...@@ -4215,8 +4228,8 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, ...@@ -4215,8 +4228,8 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
} else { } else {
queue_work(qla_tgt_wq, &cmd->work); queue_work(qla_tgt_wq, &cmd->work);
} }
return 0;
return 0;
} }
/* ha->hardware_lock supposed to be held on entry */ /* ha->hardware_lock supposed to be held on entry */
...@@ -4247,6 +4260,7 @@ static int qlt_issue_task_mgmt(struct fc_port *sess, u64 lun, ...@@ -4247,6 +4260,7 @@ static int qlt_issue_task_mgmt(struct fc_port *sess, u64 lun,
mcmd->tmr_func = fn; mcmd->tmr_func = fn;
mcmd->flags = flags; mcmd->flags = flags;
mcmd->reset_count = vha->hw->chip_reset; mcmd->reset_count = vha->hw->chip_reset;
mcmd->qpair = ha->base_qpair;
switch (fn) { switch (fn) {
case QLA_TGT_LUN_RESET: case QLA_TGT_LUN_RESET:
...@@ -4330,6 +4344,7 @@ static int __qlt_abort_task(struct scsi_qla_host *vha, ...@@ -4330,6 +4344,7 @@ static int __qlt_abort_task(struct scsi_qla_host *vha,
scsilun_to_int((struct scsi_lun *)&a->u.isp24.fcp_cmnd.lun); scsilun_to_int((struct scsi_lun *)&a->u.isp24.fcp_cmnd.lun);
mcmd->reset_count = vha->hw->chip_reset; mcmd->reset_count = vha->hw->chip_reset;
mcmd->tmr_func = QLA_TGT_2G_ABORT_TASK; mcmd->tmr_func = QLA_TGT_2G_ABORT_TASK;
mcmd->qpair = ha->base_qpair;
rc = ha->tgt.tgt_ops->handle_tmr(mcmd, unpacked_lun, mcmd->tmr_func, rc = ha->tgt.tgt_ops->handle_tmr(mcmd, unpacked_lun, mcmd->tmr_func,
le16_to_cpu(iocb->u.isp2x.seq_id)); le16_to_cpu(iocb->u.isp2x.seq_id));
...@@ -4756,8 +4771,8 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, ...@@ -4756,8 +4771,8 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
{ {
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
if (tgt->link_reinit_iocb_pending) { if (tgt->link_reinit_iocb_pending) {
qlt_send_notify_ack(vha, &tgt->link_reinit_iocb, qlt_send_notify_ack(ha->base_qpair,
0, 0, 0, 0, 0, 0); &tgt->link_reinit_iocb, 0, 0, 0, 0, 0, 0);
tgt->link_reinit_iocb_pending = 0; tgt->link_reinit_iocb_pending = 0;
} }
...@@ -4820,8 +4835,8 @@ static void qlt_handle_imm_notify(struct scsi_qla_host *vha, ...@@ -4820,8 +4835,8 @@ static void qlt_handle_imm_notify(struct scsi_qla_host *vha,
le16_to_cpu(iocb->u.isp24.nport_handle), le16_to_cpu(iocb->u.isp24.nport_handle),
iocb->u.isp24.status_subcode); iocb->u.isp24.status_subcode);
if (tgt->link_reinit_iocb_pending) { if (tgt->link_reinit_iocb_pending) {
qlt_send_notify_ack(vha, &tgt->link_reinit_iocb, qlt_send_notify_ack(ha->base_qpair,
0, 0, 0, 0, 0, 0); &tgt->link_reinit_iocb, 0, 0, 0, 0, 0, 0);
} }
memcpy(&tgt->link_reinit_iocb, iocb, sizeof(*iocb)); memcpy(&tgt->link_reinit_iocb, iocb, sizeof(*iocb));
tgt->link_reinit_iocb_pending = 1; tgt->link_reinit_iocb_pending = 1;
...@@ -4915,16 +4930,18 @@ static void qlt_handle_imm_notify(struct scsi_qla_host *vha, ...@@ -4915,16 +4930,18 @@ static void qlt_handle_imm_notify(struct scsi_qla_host *vha,
} }
if (send_notify_ack) if (send_notify_ack)
qlt_send_notify_ack(vha, iocb, add_flags, 0, 0, 0, 0, 0); qlt_send_notify_ack(ha->base_qpair, iocb, add_flags, 0, 0, 0,
0, 0);
} }
/* /*
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
* This function sends busy to ISP 2xxx or 24xx. * This function sends busy to ISP 2xxx or 24xx.
*/ */
static int __qlt_send_busy(struct scsi_qla_host *vha, static int __qlt_send_busy(struct qla_qpair *qpair,
struct atio_from_isp *atio, uint16_t status) struct atio_from_isp *atio, uint16_t status)
{ {
struct scsi_qla_host *vha = qpair->vha;
struct ctio7_to_24xx *ctio24; struct ctio7_to_24xx *ctio24;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
request_t *pkt; request_t *pkt;
...@@ -4937,12 +4954,12 @@ static int __qlt_send_busy(struct scsi_qla_host *vha, ...@@ -4937,12 +4954,12 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
atio->u.isp24.fcp_hdr.s_id); atio->u.isp24.fcp_hdr.s_id);
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
if (!sess) { if (!sess) {
qlt_send_term_exchange(vha, NULL, atio, 1, 0); qlt_send_term_exchange(qpair, NULL, atio, 1, 0);
return 0; return 0;
} }
/* Sending marker isn't necessary, since we called from ISR */ /* Sending marker isn't necessary, since we called from ISR */
pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL); pkt = (request_t *)__qla2x00_alloc_iocbs(qpair, NULL);
if (!pkt) { if (!pkt) {
ql_dbg(ql_dbg_io, vha, 0x3063, ql_dbg(ql_dbg_io, vha, 0x3063,
"qla_target(%d): %s failed: unable to allocate " "qla_target(%d): %s failed: unable to allocate "
...@@ -4975,7 +4992,7 @@ static int __qlt_send_busy(struct scsi_qla_host *vha, ...@@ -4975,7 +4992,7 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
ctio24->u.status1.scsi_status = cpu_to_le16(status); ctio24->u.status1.scsi_status = cpu_to_le16(status);
/* Memory Barrier */ /* Memory Barrier */
wmb(); wmb();
qla2x00_start_iocbs(vha, vha->req); qla2x00_start_iocbs(vha, qpair->req);
return 0; return 0;
} }
...@@ -4994,6 +5011,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, ...@@ -4994,6 +5011,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
struct se_session *se_sess; struct se_session *se_sess;
struct qla_tgt_cmd *cmd; struct qla_tgt_cmd *cmd;
int tag; int tag;
unsigned long flags;
if (unlikely(tgt->tgt_stop)) { if (unlikely(tgt->tgt_stop)) {
ql_dbg(ql_dbg_io, vha, 0x300a, ql_dbg(ql_dbg_io, vha, 0x300a,
...@@ -5054,6 +5072,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, ...@@ -5054,6 +5072,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
cmd->vha = vha; cmd->vha = vha;
cmd->reset_count = vha->hw->chip_reset; cmd->reset_count = vha->hw->chip_reset;
cmd->q_full = 1; cmd->q_full = 1;
cmd->qpair = ha->base_qpair;
if (qfull) { if (qfull) {
cmd->q_full = 1; cmd->q_full = 1;
...@@ -5062,6 +5081,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, ...@@ -5062,6 +5081,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
} else } else
cmd->term_exchg = 1; cmd->term_exchg = 1;
spin_lock_irqsave(&vha->hw->tgt.q_full_lock, flags);
list_add_tail(&cmd->cmd_list, &vha->hw->tgt.q_full_list); list_add_tail(&cmd->cmd_list, &vha->hw->tgt.q_full_list);
vha->hw->tgt.num_qfull_cmds_alloc++; vha->hw->tgt.num_qfull_cmds_alloc++;
...@@ -5069,35 +5089,41 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, ...@@ -5069,35 +5089,41 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
vha->qla_stats.stat_max_qfull_cmds_alloc) vha->qla_stats.stat_max_qfull_cmds_alloc)
vha->qla_stats.stat_max_qfull_cmds_alloc = vha->qla_stats.stat_max_qfull_cmds_alloc =
vha->hw->tgt.num_qfull_cmds_alloc; vha->hw->tgt.num_qfull_cmds_alloc;
spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
} }
int int
qlt_free_qfull_cmds(struct scsi_qla_host *vha) qlt_free_qfull_cmds(struct qla_qpair *qpair)
{ {
struct scsi_qla_host *vha = qpair->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
unsigned long flags; unsigned long flags;
struct qla_tgt_cmd *cmd, *tcmd; struct qla_tgt_cmd *cmd, *tcmd;
struct list_head free_list; struct list_head free_list, q_full_list;
int rc = 0; int rc = 0;
if (list_empty(&ha->tgt.q_full_list)) if (list_empty(&ha->tgt.q_full_list))
return 0; return 0;
INIT_LIST_HEAD(&free_list); INIT_LIST_HEAD(&free_list);
INIT_LIST_HEAD(&q_full_list);
spin_lock_irqsave(&vha->hw->hardware_lock, flags); spin_lock_irqsave(&vha->hw->tgt.q_full_lock, flags);
if (list_empty(&ha->tgt.q_full_list)) { if (list_empty(&ha->tgt.q_full_list)) {
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
return 0; return 0;
} }
list_for_each_entry_safe(cmd, tcmd, &ha->tgt.q_full_list, cmd_list) { list_splice_init(&vha->hw->tgt.q_full_list, &q_full_list);
spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
list_for_each_entry_safe(cmd, tcmd, &q_full_list, cmd_list) {
if (cmd->q_full) if (cmd->q_full)
/* cmd->state is a borrowed field to hold status */ /* cmd->state is a borrowed field to hold status */
rc = __qlt_send_busy(vha, &cmd->atio, cmd->state); rc = __qlt_send_busy(qpair, &cmd->atio, cmd->state);
else if (cmd->term_exchg) else if (cmd->term_exchg)
rc = __qlt_send_term_exchange(vha, NULL, &cmd->atio); rc = __qlt_send_term_exchange(qpair, NULL, &cmd->atio);
if (rc == -ENOMEM) if (rc == -ENOMEM)
break; break;
...@@ -5121,7 +5147,7 @@ qlt_free_qfull_cmds(struct scsi_qla_host *vha) ...@@ -5121,7 +5147,7 @@ qlt_free_qfull_cmds(struct scsi_qla_host *vha)
/* piggy back on hardware_lock for protection */ /* piggy back on hardware_lock for protection */
vha->hw->tgt.num_qfull_cmds_alloc--; vha->hw->tgt.num_qfull_cmds_alloc--;
} }
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
cmd = NULL; cmd = NULL;
...@@ -5132,23 +5158,31 @@ qlt_free_qfull_cmds(struct scsi_qla_host *vha) ...@@ -5132,23 +5158,31 @@ qlt_free_qfull_cmds(struct scsi_qla_host *vha)
*/ */
qlt_free_cmd(cmd); qlt_free_cmd(cmd);
} }
if (!list_empty(&q_full_list)) {
spin_lock_irqsave(&vha->hw->tgt.q_full_lock, flags);
list_splice(&q_full_list, &vha->hw->tgt.q_full_list);
spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
}
return rc; return rc;
} }
static void static void
qlt_send_busy(struct scsi_qla_host *vha, qlt_send_busy(struct qla_qpair *qpair, struct atio_from_isp *atio,
struct atio_from_isp *atio, uint16_t status) uint16_t status)
{ {
int rc = 0; int rc = 0;
struct scsi_qla_host *vha = qpair->vha;
rc = __qlt_send_busy(vha, atio, status); rc = __qlt_send_busy(qpair, atio, status);
if (rc == -ENOMEM) if (rc == -ENOMEM)
qlt_alloc_qfull_cmd(vha, atio, status, 1); qlt_alloc_qfull_cmd(vha, atio, status, 1);
} }
static int static int
qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, struct qla_qpair *qpair,
struct atio_from_isp *atio, bool ha_locked) struct atio_from_isp *atio, uint8_t ha_locked)
{ {
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
uint16_t status; uint16_t status;
...@@ -5160,7 +5194,7 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, ...@@ -5160,7 +5194,7 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha,
if (!ha_locked) if (!ha_locked)
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
status = temp_sam_status; status = temp_sam_status;
qlt_send_busy(vha, atio, status); qlt_send_busy(qpair, atio, status);
if (!ha_locked) if (!ha_locked)
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
...@@ -5199,16 +5233,17 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, ...@@ -5199,16 +5233,17 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
"sending QUEUE_FULL\n", vha->vp_idx); "sending QUEUE_FULL\n", vha->vp_idx);
if (!ha_locked) if (!ha_locked)
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
qlt_send_busy(vha, atio, SAM_STAT_TASK_SET_FULL); qlt_send_busy(ha->base_qpair, atio,
SAM_STAT_TASK_SET_FULL);
if (!ha_locked) if (!ha_locked)
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock,
flags);
break; break;
} }
if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) { if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) {
rc = qlt_chk_qfull_thresh_hold(vha, atio, ha_locked); rc = qlt_chk_qfull_thresh_hold(vha, ha->base_qpair,
atio, ha_locked);
if (rc != 0) { if (rc != 0) {
tgt->atio_irq_cmd_count--; tgt->atio_irq_cmd_count--;
return; return;
...@@ -5220,19 +5255,19 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, ...@@ -5220,19 +5255,19 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
if (unlikely(rc != 0)) { if (unlikely(rc != 0)) {
if (rc == -ESRCH) { if (rc == -ESRCH) {
if (!ha_locked) if (!ha_locked)
spin_lock_irqsave spin_lock_irqsave(&ha->hardware_lock,
(&ha->hardware_lock, flags); flags);
#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
qlt_send_busy(vha, atio, SAM_STAT_BUSY); qlt_send_busy(ha->base_qpair, atio,
SAM_STAT_BUSY);
#else #else
qlt_send_term_exchange(vha, NULL, atio, 1, 0); qlt_send_term_exchange(ha->base_qpair, NULL,
atio, 1, 0);
#endif #endif
if (!ha_locked) if (!ha_locked)
spin_unlock_irqrestore spin_unlock_irqrestore(
(&ha->hardware_lock, flags); &ha->hardware_lock, flags);
} else { } else {
if (tgt->tgt_stop) { if (tgt->tgt_stop) {
ql_dbg(ql_dbg_tgt, vha, 0xe059, ql_dbg(ql_dbg_tgt, vha, 0xe059,
...@@ -5247,7 +5282,8 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, ...@@ -5247,7 +5282,8 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
if (!ha_locked) if (!ha_locked)
spin_lock_irqsave( spin_lock_irqsave(
&ha->hardware_lock, flags); &ha->hardware_lock, flags);
qlt_send_busy(vha, atio, SAM_STAT_BUSY); qlt_send_busy(ha->base_qpair,
atio, SAM_STAT_BUSY);
if (!ha_locked) if (!ha_locked)
spin_unlock_irqrestore( spin_unlock_irqrestore(
&ha->hardware_lock, flags); &ha->hardware_lock, flags);
...@@ -5288,7 +5324,8 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, ...@@ -5288,7 +5324,8 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
/* ha->hardware_lock supposed to be held on entry */ /* ha->hardware_lock supposed to be held on entry */
/* called via callback from qla2xxx */ /* called via callback from qla2xxx */
static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) static void qlt_response_pkt(struct scsi_qla_host *vha,
struct rsp_que *rsp, response_t *pkt)
{ {
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
...@@ -5310,7 +5347,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) ...@@ -5310,7 +5347,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
case CTIO_TYPE7: case CTIO_TYPE7:
{ {
struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt; struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt;
qlt_do_ctio_completion(vha, entry->handle, qlt_do_ctio_completion(vha, rsp, entry->handle,
le16_to_cpu(entry->status)|(pkt->entry_status << 16), le16_to_cpu(entry->status)|(pkt->entry_status << 16),
entry); entry);
break; break;
...@@ -5329,7 +5366,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) ...@@ -5329,7 +5366,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
break; break;
} }
rc = qlt_chk_qfull_thresh_hold(vha, atio, true); rc = qlt_chk_qfull_thresh_hold(vha, rsp->qpair, atio, 1);
if (rc != 0) if (rc != 0)
return; return;
...@@ -5337,9 +5374,9 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) ...@@ -5337,9 +5374,9 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
if (unlikely(rc != 0)) { if (unlikely(rc != 0)) {
if (rc == -ESRCH) { if (rc == -ESRCH) {
#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
qlt_send_busy(vha, atio, 0); qlt_send_busy(rsp->qpair, atio, 0);
#else #else
qlt_send_term_exchange(vha, NULL, atio, 1, 0); qlt_send_term_exchange(rsp->qpair, NULL, atio, 1, 0);
#endif #endif
} else { } else {
if (tgt->tgt_stop) { if (tgt->tgt_stop) {
...@@ -5347,14 +5384,14 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) ...@@ -5347,14 +5384,14 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
"qla_target: Unable to send " "qla_target: Unable to send "
"command to target, sending TERM " "command to target, sending TERM "
"EXCHANGE for rsp\n"); "EXCHANGE for rsp\n");
qlt_send_term_exchange(vha, NULL, qlt_send_term_exchange(rsp->qpair, NULL,
atio, 1, 0); atio, 1, 0);
} else { } else {
ql_dbg(ql_dbg_tgt, vha, 0xe060, ql_dbg(ql_dbg_tgt, vha, 0xe060,
"qla_target(%d): Unable to send " "qla_target(%d): Unable to send "
"command to target, sending BUSY " "command to target, sending BUSY "
"status\n", vha->vp_idx); "status\n", vha->vp_idx);
qlt_send_busy(vha, atio, 0); qlt_send_busy(rsp->qpair, atio, 0);
} }
} }
} }
...@@ -5364,7 +5401,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) ...@@ -5364,7 +5401,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
case CONTINUE_TGT_IO_TYPE: case CONTINUE_TGT_IO_TYPE:
{ {
struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt; struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt;
qlt_do_ctio_completion(vha, entry->handle, qlt_do_ctio_completion(vha, rsp, entry->handle,
le16_to_cpu(entry->status)|(pkt->entry_status << 16), le16_to_cpu(entry->status)|(pkt->entry_status << 16),
entry); entry);
break; break;
...@@ -5373,7 +5410,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) ...@@ -5373,7 +5410,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
case CTIO_A64_TYPE: case CTIO_A64_TYPE:
{ {
struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt; struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt;
qlt_do_ctio_completion(vha, entry->handle, qlt_do_ctio_completion(vha, rsp, entry->handle,
le16_to_cpu(entry->status)|(pkt->entry_status << 16), le16_to_cpu(entry->status)|(pkt->entry_status << 16),
entry); entry);
break; break;
...@@ -5508,7 +5545,8 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha, ...@@ -5508,7 +5545,8 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha,
le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]),
le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3])); le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3]));
if (tgt->link_reinit_iocb_pending) { if (tgt->link_reinit_iocb_pending) {
qlt_send_notify_ack(vha, (void *)&tgt->link_reinit_iocb, qlt_send_notify_ack(ha->base_qpair,
(void *)&tgt->link_reinit_iocb,
0, 0, 0, 0, 0, 0); 0, 0, 0, 0, 0, 0);
tgt->link_reinit_iocb_pending = 0; tgt->link_reinit_iocb_pending = 0;
} }
...@@ -5790,7 +5828,8 @@ static void qlt_abort_work(struct qla_tgt *tgt, ...@@ -5790,7 +5828,8 @@ static void qlt_abort_work(struct qla_tgt *tgt,
out_term: out_term:
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false); qlt_24xx_send_abts_resp(ha->base_qpair, &prm->abts,
FCP_TMF_REJECTED, false);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
} }
...@@ -5857,7 +5896,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt, ...@@ -5857,7 +5896,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
ha->tgt.tgt_ops->put_sess(sess); ha->tgt.tgt_ops->put_sess(sess);
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
out_term: out_term:
qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1, 0); qlt_send_term_exchange(ha->base_qpair, NULL, &prm->tm_iocb2, 1, 0);
} }
static void qlt_sess_work_fn(struct work_struct *work) static void qlt_sess_work_fn(struct work_struct *work)
...@@ -6160,7 +6199,6 @@ qlt_enable_vha(struct scsi_qla_host *vha) ...@@ -6160,7 +6199,6 @@ qlt_enable_vha(struct scsi_qla_host *vha)
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
unsigned long flags; unsigned long flags;
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
int rspq_ent = QLA83XX_RSPQ_MSIX_ENTRY_NUMBER;
if (!tgt) { if (!tgt) {
ql_dbg(ql_dbg_tgt, vha, 0xe069, ql_dbg(ql_dbg_tgt, vha, 0xe069,
...@@ -6179,17 +6217,6 @@ qlt_enable_vha(struct scsi_qla_host *vha) ...@@ -6179,17 +6217,6 @@ qlt_enable_vha(struct scsi_qla_host *vha)
qla24xx_disable_vp(vha); qla24xx_disable_vp(vha);
qla24xx_enable_vp(vha); qla24xx_enable_vp(vha);
} else { } else {
if (ha->msix_entries) {
ql_dbg(ql_dbg_tgt, vha, 0xe081,
"%s: host%ld : vector %d cpu %d\n",
__func__, vha->host_no,
ha->msix_entries[rspq_ent].vector,
ha->msix_entries[rspq_ent].cpuid);
ha->tgt.rspq_vector_cpuid =
ha->msix_entries[rspq_ent].cpuid;
}
set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
qla2xxx_wake_dpc(base_vha); qla2xxx_wake_dpc(base_vha);
qla2x00_wait_for_hba_online(base_vha); qla2x00_wait_for_hba_online(base_vha);
...@@ -6323,7 +6350,8 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked) ...@@ -6323,7 +6350,8 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked)
le32_to_cpu(pkt->u.isp24.exchange_addr), pkt); le32_to_cpu(pkt->u.isp24.exchange_addr), pkt);
adjust_corrupted_atio(pkt); adjust_corrupted_atio(pkt);
qlt_send_term_exchange(vha, NULL, pkt, ha_locked, 0); qlt_send_term_exchange(ha->base_qpair, NULL, pkt,
ha_locked, 0);
} else { } else {
qlt_24xx_atio_pkt_all_vps(vha, qlt_24xx_atio_pkt_all_vps(vha,
(struct atio_from_isp *)pkt, ha_locked); (struct atio_from_isp *)pkt, ha_locked);
...@@ -6674,14 +6702,15 @@ qlt_handle_abts_recv_work(struct work_struct *work) ...@@ -6674,14 +6702,15 @@ qlt_handle_abts_recv_work(struct work_struct *work)
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags); spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
qlt_response_pkt_all_vps(vha, (response_t *)&op->atio); qlt_response_pkt_all_vps(vha, op->rsp, (response_t *)&op->atio);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
kfree(op); kfree(op);
} }
void void
qlt_handle_abts_recv(struct scsi_qla_host *vha, response_t *pkt) qlt_handle_abts_recv(struct scsi_qla_host *vha, struct rsp_que *rsp,
response_t *pkt)
{ {
struct qla_tgt_sess_op *op; struct qla_tgt_sess_op *op;
...@@ -6691,13 +6720,14 @@ qlt_handle_abts_recv(struct scsi_qla_host *vha, response_t *pkt) ...@@ -6691,13 +6720,14 @@ qlt_handle_abts_recv(struct scsi_qla_host *vha, response_t *pkt)
/* do not reach for ATIO queue here. This is best effort err /* do not reach for ATIO queue here. This is best effort err
* recovery at this point. * recovery at this point.
*/ */
qlt_response_pkt_all_vps(vha, pkt); qlt_response_pkt_all_vps(vha, rsp, pkt);
return; return;
} }
memcpy(&op->atio, pkt, sizeof(*pkt)); memcpy(&op->atio, pkt, sizeof(*pkt));
op->vha = vha; op->vha = vha;
op->chip_reset = vha->hw->chip_reset; op->chip_reset = vha->hw->chip_reset;
op->rsp = rsp;
INIT_WORK(&op->work, qlt_handle_abts_recv_work); INIT_WORK(&op->work, qlt_handle_abts_recv_work);
queue_work(qla_tgt_wq, &op->work); queue_work(qla_tgt_wq, &op->work);
return; return;
......
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
#define QLA_TGT_NULL_HANDLE 0 #define QLA_TGT_NULL_HANDLE 0
#define QLA_TGT_HANDLE_MASK 0xF0000000 #define QLA_TGT_HANDLE_MASK 0xF0000000
#define QLA_QPID_HANDLE_MASK 0x000F0000 /* qpair id mask */ #define QLA_QPID_HANDLE_MASK 0x00FF0000 /* qpair id mask */
#define QLA_CMD_HANDLE_MASK 0x0000FFFF #define QLA_CMD_HANDLE_MASK 0x0000FFFF
#define QLA_TGT_SKIP_HANDLE (0xFFFFFFFF & ~QLA_TGT_HANDLE_MASK) #define QLA_TGT_SKIP_HANDLE (0xFFFFFFFF & ~QLA_TGT_HANDLE_MASK)
...@@ -837,6 +837,7 @@ struct qla_tgt_sess_op { ...@@ -837,6 +837,7 @@ struct qla_tgt_sess_op {
struct work_struct work; struct work_struct work;
struct list_head cmd_list; struct list_head cmd_list;
bool aborted; bool aborted;
struct rsp_que *rsp;
}; };
enum trace_flags { enum trace_flags {
...@@ -871,6 +872,7 @@ struct qla_tgt_cmd { ...@@ -871,6 +872,7 @@ struct qla_tgt_cmd {
uint8_t pad[7]; uint8_t pad[7];
struct se_cmd se_cmd; struct se_cmd se_cmd;
struct fc_port *sess; struct fc_port *sess;
struct qla_qpair *qpair;
int state; int state;
struct work_struct work; struct work_struct work;
/* Sense buffer that will be mapped into outgoing status */ /* Sense buffer that will be mapped into outgoing status */
...@@ -948,6 +950,7 @@ struct qla_tgt_mgmt_cmd { ...@@ -948,6 +950,7 @@ struct qla_tgt_mgmt_cmd {
uint16_t tmr_func; uint16_t tmr_func;
uint8_t fc_tm_rsp; uint8_t fc_tm_rsp;
struct fc_port *sess; struct fc_port *sess;
struct qla_qpair *qpair;
struct se_cmd se_cmd; struct se_cmd se_cmd;
struct work_struct free_work; struct work_struct free_work;
unsigned int flags; unsigned int flags;
...@@ -1049,7 +1052,8 @@ static inline void sid_to_portid(const uint8_t *s_id, port_id_t *p) ...@@ -1049,7 +1052,8 @@ static inline void sid_to_portid(const uint8_t *s_id, port_id_t *p)
/* /*
* Exported symbols from qla_target.c LLD logic used by qla2xxx code.. * Exported symbols from qla_target.c LLD logic used by qla2xxx code..
*/ */
extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *); extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, struct rsp_que *,
response_t *);
extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *); extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *);
extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t); extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t);
extern int qlt_abort_cmd(struct qla_tgt_cmd *); extern int qlt_abort_cmd(struct qla_tgt_cmd *);
...@@ -1082,7 +1086,7 @@ extern int qlt_stop_phase1(struct qla_tgt *); ...@@ -1082,7 +1086,7 @@ extern int qlt_stop_phase1(struct qla_tgt *);
extern void qlt_stop_phase2(struct qla_tgt *); extern void qlt_stop_phase2(struct qla_tgt *);
extern irqreturn_t qla83xx_msix_atio_q(int, void *); extern irqreturn_t qla83xx_msix_atio_q(int, void *);
extern void qlt_83xx_iospace_config(struct qla_hw_data *); extern void qlt_83xx_iospace_config(struct qla_hw_data *);
extern int qlt_free_qfull_cmds(struct scsi_qla_host *); extern int qlt_free_qfull_cmds(struct qla_qpair *);
extern void qlt_logo_completion_handler(fc_port_t *, int); extern void qlt_logo_completion_handler(fc_port_t *, int);
extern void qlt_do_generation_tick(struct scsi_qla_host *, int *); extern void qlt_do_generation_tick(struct scsi_qla_host *, int *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment