Commit 9ba56b95 authored by Giridhar Malavali's avatar Giridhar Malavali Committed by James Bottomley

[SCSI] qla2xxx: Consolidation of SRB processing.

Rework the structures related to SRB processing to minimize the memory
allocations per I/O and manage resources associated with and completions
from common routines.
Signed-off-by: default avatarGiridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: default avatarChad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 69e5f1ea
...@@ -11,29 +11,36 @@ ...@@ -11,29 +11,36 @@
#include <linux/delay.h> #include <linux/delay.h>
/* BSG support for ELS/CT pass through */ /* BSG support for ELS/CT pass through */
inline srb_t * void
qla2x00_get_ctx_bsg_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size) qla2x00_bsg_job_done(void *data, void *ptr, int res)
{ {
srb_t *sp; srb_t *sp = (srb_t *)ptr;
struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
struct fc_bsg_job *bsg_job = sp->u.bsg_job;
bsg_job->reply->result = res;
bsg_job->job_done(bsg_job);
sp->free(vha, sp);
}
void
qla2x00_bsg_sp_free(void *data, void *ptr)
{
srb_t *sp = (srb_t *)ptr;
struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
struct fc_bsg_job *bsg_job = sp->u.bsg_job;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct srb_ctx *ctx;
sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL); dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
if (!sp) bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
goto done;
ctx = kzalloc(size, GFP_KERNEL);
if (!ctx) {
mempool_free(sp, ha->srb_mempool);
sp = NULL;
goto done;
}
memset(sp, 0, sizeof(*sp)); dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
sp->fcport = fcport; bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
sp->ctx = ctx;
ctx->iocbs = 1; if (sp->type == SRB_CT_CMD ||
done: sp->type == SRB_ELS_CMD_HST)
return sp; kfree(sp->fcport);
mempool_free(sp, vha->hw->srb_mempool);
} }
int int
...@@ -217,6 +224,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job) ...@@ -217,6 +224,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
bsg_job->job_done(bsg_job); bsg_job->job_done(bsg_job);
return ret; return ret;
} }
static int static int
qla2x00_process_els(struct fc_bsg_job *bsg_job) qla2x00_process_els(struct fc_bsg_job *bsg_job)
{ {
...@@ -230,7 +238,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) ...@@ -230,7 +238,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
int req_sg_cnt, rsp_sg_cnt; int req_sg_cnt, rsp_sg_cnt;
int rval = (DRIVER_ERROR << 16); int rval = (DRIVER_ERROR << 16);
uint16_t nextlid = 0; uint16_t nextlid = 0;
struct srb_ctx *els;
if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) { if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
rport = bsg_job->rport; rport = bsg_job->rport;
...@@ -337,20 +344,21 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) ...@@ -337,20 +344,21 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
} }
/* Alloc SRB structure */ /* Alloc SRB structure */
sp = qla2x00_get_ctx_bsg_sp(vha, fcport, sizeof(struct srb_ctx)); sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp) { if (!sp) {
rval = -ENOMEM; rval = -ENOMEM;
goto done_unmap_sg; goto done_unmap_sg;
} }
els = sp->ctx; sp->type =
els->type =
(bsg_job->request->msgcode == FC_BSG_RPT_ELS ? (bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST); SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
els->name = sp->name =
(bsg_job->request->msgcode == FC_BSG_RPT_ELS ? (bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
"bsg_els_rpt" : "bsg_els_hst"); "bsg_els_rpt" : "bsg_els_hst");
els->u.bsg_job = bsg_job; sp->u.bsg_job = bsg_job;
sp->free = qla2x00_bsg_sp_free;
sp->done = qla2x00_bsg_job_done;
ql_dbg(ql_dbg_user, vha, 0x700a, ql_dbg(ql_dbg_user, vha, 0x700a,
"bsg rqst type: %s els type: %x - loop-id=%x " "bsg rqst type: %s els type: %x - loop-id=%x "
...@@ -362,7 +370,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) ...@@ -362,7 +370,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0x700e, ql_log(ql_log_warn, vha, 0x700e,
"qla2x00_start_sp failed = %d\n", rval); "qla2x00_start_sp failed = %d\n", rval);
kfree(sp->ctx);
mempool_free(sp, ha->srb_mempool); mempool_free(sp, ha->srb_mempool);
rval = -EIO; rval = -EIO;
goto done_unmap_sg; goto done_unmap_sg;
...@@ -409,7 +416,6 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) ...@@ -409,7 +416,6 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
uint16_t loop_id; uint16_t loop_id;
struct fc_port *fcport; struct fc_port *fcport;
char *type = "FC_BSG_HST_CT"; char *type = "FC_BSG_HST_CT";
struct srb_ctx *ct;
req_sg_cnt = req_sg_cnt =
dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
...@@ -486,19 +492,20 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) ...@@ -486,19 +492,20 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
fcport->loop_id = loop_id; fcport->loop_id = loop_id;
/* Alloc SRB structure */ /* Alloc SRB structure */
sp = qla2x00_get_ctx_bsg_sp(vha, fcport, sizeof(struct srb_ctx)); sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp) { if (!sp) {
ql_log(ql_log_warn, vha, 0x7015, ql_log(ql_log_warn, vha, 0x7015,
"qla2x00_get_ctx_bsg_sp failed.\n"); "qla2x00_get_sp failed.\n");
rval = -ENOMEM; rval = -ENOMEM;
goto done_free_fcport; goto done_free_fcport;
} }
ct = sp->ctx; sp->type = SRB_CT_CMD;
ct->type = SRB_CT_CMD; sp->name = "bsg_ct";
ct->name = "bsg_ct"; sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
ct->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt); sp->u.bsg_job = bsg_job;
ct->u.bsg_job = bsg_job; sp->free = qla2x00_bsg_sp_free;
sp->done = qla2x00_bsg_job_done;
ql_dbg(ql_dbg_user, vha, 0x7016, ql_dbg(ql_dbg_user, vha, 0x7016,
"bsg rqst type: %s else type: %x - " "bsg rqst type: %s else type: %x - "
...@@ -511,7 +518,6 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) ...@@ -511,7 +518,6 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0x7017, ql_log(ql_log_warn, vha, 0x7017,
"qla2x00_start_sp failed=%d.\n", rval); "qla2x00_start_sp failed=%d.\n", rval);
kfree(sp->ctx);
mempool_free(sp, ha->srb_mempool); mempool_free(sp, ha->srb_mempool);
rval = -EIO; rval = -EIO;
goto done_free_fcport; goto done_free_fcport;
...@@ -1669,7 +1675,6 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job) ...@@ -1669,7 +1675,6 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
int cnt, que; int cnt, que;
unsigned long flags; unsigned long flags;
struct req_que *req; struct req_que *req;
struct srb_ctx *sp_bsg;
/* find the bsg job from the active list of commands */ /* find the bsg job from the active list of commands */
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
...@@ -1681,11 +1686,9 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job) ...@@ -1681,11 +1686,9 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
sp = req->outstanding_cmds[cnt]; sp = req->outstanding_cmds[cnt];
if (sp) { if (sp) {
sp_bsg = sp->ctx; if (((sp->type == SRB_CT_CMD) ||
(sp->type == SRB_ELS_CMD_HST))
if (((sp_bsg->type == SRB_CT_CMD) || && (sp->u.bsg_job == bsg_job)) {
(sp_bsg->type == SRB_ELS_CMD_HST))
&& (sp_bsg->u.bsg_job == bsg_job)) {
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (ha->isp_ops->abort_command(sp)) { if (ha->isp_ops->abort_command(sp)) {
ql_log(ql_log_warn, vha, 0x7089, ql_log(ql_log_warn, vha, 0x7089,
...@@ -1715,7 +1718,6 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job) ...@@ -1715,7 +1718,6 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (bsg_job->request->msgcode == FC_BSG_HST_CT) if (bsg_job->request->msgcode == FC_BSG_HST_CT)
kfree(sp->fcport); kfree(sp->fcport);
kfree(sp->ctx);
mempool_free(sp, ha->srb_mempool); mempool_free(sp, ha->srb_mempool);
return 0; return 0;
} }
...@@ -14,10 +14,11 @@ ...@@ -14,10 +14,11 @@
* | Module Init and Probe | 0x011f | 0x4b,0xfa | * | Module Init and Probe | 0x011f | 0x4b,0xfa |
* | Mailbox commands | 0x1139 | 0x112c-0x112e | * | Mailbox commands | 0x1139 | 0x112c-0x112e |
* | Device Discovery | 0x2084 | | * | Device Discovery | 0x2084 | |
* | Queue Command and IO tracing | 0x302f | 0x3008 | * | Queue Command and IO tracing | 0x302f | 0x3006,0x3008 |
* | | | 0x302d-0x302e | * | | | 0x302d-0x302e |
* | DPC Thread | 0x401c | | * | DPC Thread | 0x401c | |
* | Async Events | 0x5057 | 0x5052 | * | Async Events | 0x5057 | 0x502b-0x502f |
* | | | 0x5047,0x5052 |
* | Timer Routines | 0x6011 | 0x600e-0x600f | * | Timer Routines | 0x6011 | 0x600e-0x600f |
* | User Space Interactions | 0x709e | 0x7018,0x702e | * | User Space Interactions | 0x709e | 0x7018,0x702e |
* | | | 0x7039,0x7045 | * | | | 0x7039,0x7045 |
......
...@@ -202,20 +202,12 @@ struct sd_dif_tuple { ...@@ -202,20 +202,12 @@ struct sd_dif_tuple {
/* /*
* SCSI Request Block * SCSI Request Block
*/ */
typedef struct srb { struct srb_cmd {
atomic_t ref_count;
struct fc_port *fcport;
uint32_t handle;
struct scsi_cmnd *cmd; /* Linux SCSI command pkt */ struct scsi_cmnd *cmd; /* Linux SCSI command pkt */
uint16_t flags;
uint32_t request_sense_length; uint32_t request_sense_length;
uint8_t *request_sense_ptr; uint8_t *request_sense_ptr;
void *ctx; void *ctx;
} srb_t; };
/* /*
* SRB flag definitions * SRB flag definitions
...@@ -254,10 +246,7 @@ struct srb_iocb { ...@@ -254,10 +246,7 @@ struct srb_iocb {
} u; } u;
struct timer_list timer; struct timer_list timer;
void (*timeout)(void *);
void (*done)(srb_t *);
void (*free)(srb_t *);
void (*timeout)(srb_t *);
}; };
/* Values for srb_ctx type */ /* Values for srb_ctx type */
...@@ -268,16 +257,37 @@ struct srb_iocb { ...@@ -268,16 +257,37 @@ struct srb_iocb {
#define SRB_CT_CMD 5 #define SRB_CT_CMD 5
#define SRB_ADISC_CMD 6 #define SRB_ADISC_CMD 6
#define SRB_TM_CMD 7 #define SRB_TM_CMD 7
#define SRB_SCSI_CMD 8
struct srb_ctx { typedef struct srb {
atomic_t ref_count;
struct fc_port *fcport;
uint32_t handle;
uint16_t flags;
uint16_t type; uint16_t type;
char *name; char *name;
int iocbs; int iocbs;
union { union {
struct srb_iocb *iocb_cmd; struct srb_iocb iocb_cmd;
struct fc_bsg_job *bsg_job; struct fc_bsg_job *bsg_job;
struct srb_cmd scmd;
} u; } u;
}; void (*done)(void *, void *, int);
void (*free)(void *, void *);
} srb_t;
#define GET_CMD_SP(sp) (sp->u.scmd.cmd)
#define SET_CMD_SP(sp, cmd) (sp->u.scmd.cmd = cmd)
#define GET_CMD_CTX_SP(sp) (sp->u.scmd.ctx)
#define GET_CMD_SENSE_LEN(sp) \
(sp->u.scmd.request_sense_length)
#define SET_CMD_SENSE_LEN(sp, len) \
(sp->u.scmd.request_sense_length = len)
#define GET_CMD_SENSE_PTR(sp) \
(sp->u.scmd.request_sense_ptr)
#define SET_CMD_SENSE_PTR(sp, ptr) \
(sp->u.scmd.request_sense_ptr = ptr)
struct msg_echo_lb { struct msg_echo_lb {
dma_addr_t send_dma; dma_addr_t send_dma;
......
...@@ -71,8 +71,6 @@ extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *, ...@@ -71,8 +71,6 @@ extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
uint16_t *); uint16_t *);
extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *, extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *,
uint16_t *); uint16_t *);
extern void qla2x00_async_tm_cmd_done(struct scsi_qla_host *, fc_port_t *,
struct srb_iocb *);
extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *); extern void *qla2x00_alloc_iocbs(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 *);
...@@ -156,8 +154,7 @@ extern void qla2x00_do_dpc_all_vps(scsi_qla_host_t *); ...@@ -156,8 +154,7 @@ extern void qla2x00_do_dpc_all_vps(scsi_qla_host_t *);
extern int qla24xx_vport_create_req_sanity_check(struct fc_vport *); extern int qla24xx_vport_create_req_sanity_check(struct fc_vport *);
extern scsi_qla_host_t * qla24xx_create_vhost(struct fc_vport *); extern scsi_qla_host_t * qla24xx_create_vhost(struct fc_vport *);
extern void qla2x00_sp_compl(struct qla_hw_data *, srb_t *); extern void qla2x00_sp_free_dma(void *, void *);
extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);
extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int); extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int);
...@@ -542,6 +539,10 @@ extern int qla82xx_restart_isp(scsi_qla_host_t *); ...@@ -542,6 +539,10 @@ extern int qla82xx_restart_isp(scsi_qla_host_t *);
/* IOCB related functions */ /* IOCB related functions */
extern int qla82xx_start_scsi(srb_t *); extern int qla82xx_start_scsi(srb_t *);
extern void qla2x00_sp_free(void *, void *);
extern void qla2x00_sp_timeout(unsigned long);
extern void qla2x00_bsg_job_done(void *, void *, int);
extern void qla2x00_bsg_sp_free(void *, void *);
/* Interrupt related */ /* Interrupt related */
extern irqreturn_t qla82xx_intr_handler(int, void *); extern irqreturn_t qla82xx_intr_handler(int, void *);
......
...@@ -41,11 +41,10 @@ static int qla25xx_init_queues(struct qla_hw_data *); ...@@ -41,11 +41,10 @@ static int qla25xx_init_queues(struct qla_hw_data *);
/* SRB Extensions ---------------------------------------------------------- */ /* SRB Extensions ---------------------------------------------------------- */
static void void
qla2x00_ctx_sp_timeout(unsigned long __data) qla2x00_sp_timeout(unsigned long __data)
{ {
srb_t *sp = (srb_t *)__data; srb_t *sp = (srb_t *)__data;
struct srb_ctx *ctx;
struct srb_iocb *iocb; struct srb_iocb *iocb;
fc_port_t *fcport = sp->fcport; fc_port_t *fcport = sp->fcport;
struct qla_hw_data *ha = fcport->vha->hw; struct qla_hw_data *ha = fcport->vha->hw;
...@@ -55,77 +54,23 @@ qla2x00_ctx_sp_timeout(unsigned long __data) ...@@ -55,77 +54,23 @@ qla2x00_ctx_sp_timeout(unsigned long __data)
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
req = ha->req_q_map[0]; req = ha->req_q_map[0];
req->outstanding_cmds[sp->handle] = NULL; req->outstanding_cmds[sp->handle] = NULL;
ctx = sp->ctx; iocb = &sp->u.iocb_cmd;
iocb = ctx->u.iocb_cmd;
iocb->timeout(sp); iocb->timeout(sp);
iocb->free(sp); sp->free(fcport->vha, sp);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
} }
static void void
qla2x00_ctx_sp_free(srb_t *sp) qla2x00_sp_free(void *data, void *ptr)
{ {
struct srb_ctx *ctx = sp->ctx; srb_t *sp = (srb_t *)ptr;
struct srb_iocb *iocb = ctx->u.iocb_cmd; struct srb_iocb *iocb = &sp->u.iocb_cmd;
struct scsi_qla_host *vha = sp->fcport->vha; struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
del_timer(&iocb->timer); del_timer(&iocb->timer);
kfree(iocb); mempool_free(sp, vha->hw->srb_mempool);
kfree(ctx);
mempool_free(sp, sp->fcport->vha->hw->srb_mempool);
QLA_VHA_MARK_NOT_BUSY(vha);
}
inline srb_t *
qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size,
unsigned long tmo)
{
srb_t *sp = NULL;
struct qla_hw_data *ha = vha->hw;
struct srb_ctx *ctx;
struct srb_iocb *iocb;
uint8_t bail;
QLA_VHA_MARK_BUSY(vha, bail);
if (bail)
return NULL;
sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL);
if (!sp)
goto done;
ctx = kzalloc(size, GFP_KERNEL);
if (!ctx) {
mempool_free(sp, ha->srb_mempool);
sp = NULL;
goto done;
}
iocb = kzalloc(sizeof(struct srb_iocb), GFP_KERNEL);
if (!iocb) {
mempool_free(sp, ha->srb_mempool);
sp = NULL;
kfree(ctx);
goto done;
}
memset(sp, 0, sizeof(*sp));
sp->fcport = fcport;
sp->ctx = ctx;
ctx->iocbs = 1;
ctx->u.iocb_cmd = iocb;
iocb->free = qla2x00_ctx_sp_free;
init_timer(&iocb->timer);
if (!tmo)
goto done;
iocb->timer.expires = jiffies + tmo * HZ;
iocb->timer.data = (unsigned long)sp;
iocb->timer.function = qla2x00_ctx_sp_timeout;
add_timer(&iocb->timer);
done:
if (!sp)
QLA_VHA_MARK_NOT_BUSY(vha); QLA_VHA_MARK_NOT_BUSY(vha);
return sp;
} }
/* Asynchronous Login/Logout Routines -------------------------------------- */ /* Asynchronous Login/Logout Routines -------------------------------------- */
...@@ -149,19 +94,19 @@ qla2x00_get_async_timeout(struct scsi_qla_host *vha) ...@@ -149,19 +94,19 @@ qla2x00_get_async_timeout(struct scsi_qla_host *vha)
} }
static void static void
qla2x00_async_iocb_timeout(srb_t *sp) qla2x00_async_iocb_timeout(void *data)
{ {
srb_t *sp = (srb_t *)data;
fc_port_t *fcport = sp->fcport; fc_port_t *fcport = sp->fcport;
struct srb_ctx *ctx = sp->ctx;
ql_dbg(ql_dbg_disc, fcport->vha, 0x2071, ql_dbg(ql_dbg_disc, fcport->vha, 0x2071,
"Async-%s timeout - hdl=%x portid=%02x%02x%02x.\n", "Async-%s timeout - hdl=%x portid=%02x%02x%02x.\n",
ctx->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area, sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa); fcport->d_id.b.al_pa);
fcport->flags &= ~FCF_ASYNC_SENT; fcport->flags &= ~FCF_ASYNC_SENT;
if (ctx->type == SRB_LOGIN_CMD) { if (sp->type == SRB_LOGIN_CMD) {
struct srb_iocb *lio = ctx->u.iocb_cmd; struct srb_iocb *lio = &sp->u.iocb_cmd;
qla2x00_post_async_logout_work(fcport->vha, fcport, NULL); qla2x00_post_async_logout_work(fcport->vha, fcport, NULL);
/* Retry as needed. */ /* Retry as needed. */
lio->u.logio.data[0] = MBS_COMMAND_ERROR; lio->u.logio.data[0] = MBS_COMMAND_ERROR;
...@@ -173,14 +118,16 @@ qla2x00_async_iocb_timeout(srb_t *sp) ...@@ -173,14 +118,16 @@ qla2x00_async_iocb_timeout(srb_t *sp)
} }
static void static void
qla2x00_async_login_ctx_done(srb_t *sp) qla2x00_async_login_sp_done(void *data, void *ptr, int res)
{ {
struct srb_ctx *ctx = sp->ctx; srb_t *sp = (srb_t *)ptr;
struct srb_iocb *lio = ctx->u.iocb_cmd; struct srb_iocb *lio = &sp->u.iocb_cmd;
struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
if (!test_bit(UNLOADING, &vha->dpc_flags))
qla2x00_post_async_login_done_work(sp->fcport->vha, sp->fcport, qla2x00_post_async_login_done_work(sp->fcport->vha, sp->fcport,
lio->u.logio.data); lio->u.logio.data);
lio->free(sp); sp->free(sp->fcport->vha, sp);
} }
int int
...@@ -188,22 +135,21 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -188,22 +135,21 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
uint16_t *data) uint16_t *data)
{ {
srb_t *sp; srb_t *sp;
struct srb_ctx *ctx;
struct srb_iocb *lio; struct srb_iocb *lio;
int rval; int rval;
rval = QLA_FUNCTION_FAILED; rval = QLA_FUNCTION_FAILED;
sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx), sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
qla2x00_get_async_timeout(vha) + 2);
if (!sp) if (!sp)
goto done; goto done;
ctx = sp->ctx; sp->type = SRB_LOGIN_CMD;
ctx->type = SRB_LOGIN_CMD; sp->name = "login";
ctx->name = "login"; qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
lio = ctx->u.iocb_cmd;
lio = &sp->u.iocb_cmd;
lio->timeout = qla2x00_async_iocb_timeout; lio->timeout = qla2x00_async_iocb_timeout;
lio->done = qla2x00_async_login_ctx_done; sp->done = qla2x00_async_login_sp_done;
lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI; lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
if (data[1] & QLA_LOGIO_LOGIN_RETRIED) if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
lio->u.logio.flags |= SRB_LOGIN_RETRIED; lio->u.logio.flags |= SRB_LOGIN_RETRIED;
...@@ -219,42 +165,43 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -219,42 +165,43 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
return rval; return rval;
done_free_sp: done_free_sp:
lio->free(sp); sp->free(fcport->vha, sp);
done: done:
return rval; return rval;
} }
static void static void
qla2x00_async_logout_ctx_done(srb_t *sp) qla2x00_async_logout_sp_done(void *data, void *ptr, int res)
{ {
struct srb_ctx *ctx = sp->ctx; srb_t *sp = (srb_t *)ptr;
struct srb_iocb *lio = ctx->u.iocb_cmd; struct srb_iocb *lio = &sp->u.iocb_cmd;
struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
if (!test_bit(UNLOADING, &vha->dpc_flags))
qla2x00_post_async_logout_done_work(sp->fcport->vha, sp->fcport, qla2x00_post_async_logout_done_work(sp->fcport->vha, sp->fcport,
lio->u.logio.data); lio->u.logio.data);
lio->free(sp); sp->free(sp->fcport->vha, sp);
} }
int int
qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport) qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
{ {
srb_t *sp; srb_t *sp;
struct srb_ctx *ctx;
struct srb_iocb *lio; struct srb_iocb *lio;
int rval; int rval;
rval = QLA_FUNCTION_FAILED; rval = QLA_FUNCTION_FAILED;
sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx), sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
qla2x00_get_async_timeout(vha) + 2);
if (!sp) if (!sp)
goto done; goto done;
ctx = sp->ctx; sp->type = SRB_LOGOUT_CMD;
ctx->type = SRB_LOGOUT_CMD; sp->name = "logout";
ctx->name = "logout"; qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
lio = ctx->u.iocb_cmd;
lio = &sp->u.iocb_cmd;
lio->timeout = qla2x00_async_iocb_timeout; lio->timeout = qla2x00_async_iocb_timeout;
lio->done = qla2x00_async_logout_ctx_done; sp->done = qla2x00_async_logout_sp_done;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) if (rval != QLA_SUCCESS)
goto done_free_sp; goto done_free_sp;
...@@ -266,20 +213,22 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport) ...@@ -266,20 +213,22 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
return rval; return rval;
done_free_sp: done_free_sp:
lio->free(sp); sp->free(fcport->vha, sp);
done: done:
return rval; return rval;
} }
static void static void
qla2x00_async_adisc_ctx_done(srb_t *sp) qla2x00_async_adisc_sp_done(void *data, void *ptr, int res)
{ {
struct srb_ctx *ctx = sp->ctx; srb_t *sp = (srb_t *)ptr;
struct srb_iocb *lio = ctx->u.iocb_cmd; struct srb_iocb *lio = &sp->u.iocb_cmd;
struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
if (!test_bit(UNLOADING, &vha->dpc_flags))
qla2x00_post_async_adisc_done_work(sp->fcport->vha, sp->fcport, qla2x00_post_async_adisc_done_work(sp->fcport->vha, sp->fcport,
lio->u.logio.data); lio->u.logio.data);
lio->free(sp); sp->free(sp->fcport->vha, sp);
} }
int int
...@@ -287,22 +236,21 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -287,22 +236,21 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
uint16_t *data) uint16_t *data)
{ {
srb_t *sp; srb_t *sp;
struct srb_ctx *ctx;
struct srb_iocb *lio; struct srb_iocb *lio;
int rval; int rval;
rval = QLA_FUNCTION_FAILED; rval = QLA_FUNCTION_FAILED;
sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx), sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
qla2x00_get_async_timeout(vha) + 2);
if (!sp) if (!sp)
goto done; goto done;
ctx = sp->ctx; sp->type = SRB_ADISC_CMD;
ctx->type = SRB_ADISC_CMD; sp->name = "adisc";
ctx->name = "adisc"; qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
lio = ctx->u.iocb_cmd;
lio = &sp->u.iocb_cmd;
lio->timeout = qla2x00_async_iocb_timeout; lio->timeout = qla2x00_async_iocb_timeout;
lio->done = qla2x00_async_adisc_ctx_done; sp->done = qla2x00_async_adisc_sp_done;
if (data[1] & QLA_LOGIO_LOGIN_RETRIED) if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
lio->u.logio.flags |= SRB_LOGIN_RETRIED; lio->u.logio.flags |= SRB_LOGIN_RETRIED;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
...@@ -316,46 +264,62 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -316,46 +264,62 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
return rval; return rval;
done_free_sp: done_free_sp:
lio->free(sp); sp->free(fcport->vha, sp);
done: done:
return rval; return rval;
} }
static void static void
qla2x00_async_tm_cmd_ctx_done(srb_t *sp) qla2x00_async_tm_cmd_done(void *data, void *ptr, int res)
{ {
struct srb_ctx *ctx = sp->ctx; srb_t *sp = (srb_t *)ptr;
struct srb_iocb *iocb = (struct srb_iocb *)ctx->u.iocb_cmd; struct srb_iocb *iocb = &sp->u.iocb_cmd;
struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
uint32_t flags;
uint16_t lun;
int rval;
if (!test_bit(UNLOADING, &vha->dpc_flags)) {
flags = iocb->u.tmf.flags;
lun = (uint16_t)iocb->u.tmf.lun;
/* Issue Marker IOCB */
rval = qla2x00_marker(vha, vha->hw->req_q_map[0],
vha->hw->rsp_q_map[0], sp->fcport->loop_id, lun,
flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
qla2x00_async_tm_cmd_done(sp->fcport->vha, sp->fcport, iocb); if ((rval != QLA_SUCCESS) || iocb->u.tmf.data) {
iocb->free(sp); ql_dbg(ql_dbg_taskm, vha, 0x8030,
"TM IOCB failed (%x).\n", rval);
}
}
sp->free(sp->fcport->vha, sp);
} }
int int
qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun, qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t tm_flags, uint32_t lun,
uint32_t tag) uint32_t tag)
{ {
struct scsi_qla_host *vha = fcport->vha; struct scsi_qla_host *vha = fcport->vha;
srb_t *sp; srb_t *sp;
struct srb_ctx *ctx;
struct srb_iocb *tcf; struct srb_iocb *tcf;
int rval; int rval;
rval = QLA_FUNCTION_FAILED; rval = QLA_FUNCTION_FAILED;
sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx), sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
qla2x00_get_async_timeout(vha) + 2);
if (!sp) if (!sp)
goto done; goto done;
ctx = sp->ctx; sp->type = SRB_TM_CMD;
ctx->type = SRB_TM_CMD; sp->name = "tmf";
ctx->name = "tmf"; qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
tcf = ctx->u.iocb_cmd;
tcf->u.tmf.flags = flags; tcf = &sp->u.iocb_cmd;
tcf->u.tmf.flags = tm_flags;
tcf->u.tmf.lun = lun; tcf->u.tmf.lun = lun;
tcf->u.tmf.data = tag; tcf->u.tmf.data = tag;
tcf->timeout = qla2x00_async_iocb_timeout; tcf->timeout = qla2x00_async_iocb_timeout;
tcf->done = qla2x00_async_tm_cmd_ctx_done; sp->done = qla2x00_async_tm_cmd_done;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) if (rval != QLA_SUCCESS)
...@@ -368,7 +332,7 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun, ...@@ -368,7 +332,7 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
return rval; return rval;
done_free_sp: done_free_sp:
tcf->free(sp); sp->free(fcport->vha, sp);
done: done:
return rval; return rval;
} }
...@@ -452,30 +416,6 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -452,30 +416,6 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport,
return; return;
} }
void
qla2x00_async_tm_cmd_done(struct scsi_qla_host *vha, fc_port_t *fcport,
struct srb_iocb *iocb)
{
int rval;
uint32_t flags;
uint16_t lun;
flags = iocb->u.tmf.flags;
lun = (uint16_t)iocb->u.tmf.lun;
/* Issue Marker IOCB */
rval = qla2x00_marker(vha, vha->hw->req_q_map[0],
vha->hw->rsp_q_map[0], fcport->loop_id, lun,
flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
if ((rval != QLA_SUCCESS) || iocb->u.tmf.data) {
ql_dbg(ql_dbg_taskm, vha, 0x8030,
"TM IOCB failed (%x).\n", rval);
}
return;
}
/****************************************************************************/ /****************************************************************************/
/* QLogic ISP2x00 Hardware Support Functions. */ /* QLogic ISP2x00 Hardware Support Functions. */
/****************************************************************************/ /****************************************************************************/
......
...@@ -72,16 +72,19 @@ static inline void ...@@ -72,16 +72,19 @@ static inline void
qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp) qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp)
{ {
struct dsd_dma *dsd_ptr, *tdsd_ptr; struct dsd_dma *dsd_ptr, *tdsd_ptr;
struct crc_context *ctx;
ctx = (struct crc_context *)GET_CMD_CTX_SP(sp);
/* clean up allocated prev pool */ /* clean up allocated prev pool */
list_for_each_entry_safe(dsd_ptr, tdsd_ptr, list_for_each_entry_safe(dsd_ptr, tdsd_ptr,
&((struct crc_context *)sp->ctx)->dsd_list, list) { &ctx->dsd_list, list) {
dma_pool_free(ha->dl_dma_pool, dsd_ptr->dsd_addr, dma_pool_free(ha->dl_dma_pool, dsd_ptr->dsd_addr,
dsd_ptr->dsd_list_dma); dsd_ptr->dsd_list_dma);
list_del(&dsd_ptr->list); list_del(&dsd_ptr->list);
kfree(dsd_ptr); kfree(dsd_ptr);
} }
INIT_LIST_HEAD(&((struct crc_context *)sp->ctx)->dsd_list); INIT_LIST_HEAD(&ctx->dsd_list);
} }
static inline void static inline void
...@@ -113,8 +116,7 @@ qla2x00_hba_err_chk_enabled(srb_t *sp) ...@@ -113,8 +116,7 @@ qla2x00_hba_err_chk_enabled(srb_t *sp)
return 0; return 0;
* *
*/ */
switch (scsi_get_prot_op(GET_CMD_SP(sp))) {
switch (scsi_get_prot_op(sp->cmd)) {
case SCSI_PROT_READ_STRIP: case SCSI_PROT_READ_STRIP:
case SCSI_PROT_WRITE_INSERT: case SCSI_PROT_WRITE_INSERT:
if (ql2xenablehba_err_chk >= 1) if (ql2xenablehba_err_chk >= 1)
...@@ -144,3 +146,38 @@ qla2x00_reset_active(scsi_qla_host_t *vha) ...@@ -144,3 +146,38 @@ qla2x00_reset_active(scsi_qla_host_t *vha)
test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) || test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags); test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
} }
static inline srb_t *
qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag)
{
srb_t *sp = NULL;
struct qla_hw_data *ha = vha->hw;
uint8_t bail;
QLA_VHA_MARK_BUSY(vha, bail);
if (unlikely(bail))
return NULL;
sp = mempool_alloc(ha->srb_mempool, flag);
if (!sp)
goto done;
memset(sp, 0, sizeof(*sp));
sp->fcport = fcport;
sp->iocbs = 1;
done:
if (!sp)
QLA_VHA_MARK_NOT_BUSY(vha);
return sp;
}
static inline void
qla2x00_init_timer(srb_t *sp, unsigned long tmo)
{
init_timer(&sp->u.iocb_cmd.timer);
sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ;
sp->u.iocb_cmd.timer.data = (unsigned long)sp;
sp->u.iocb_cmd.timer.function = qla2x00_sp_timeout;
add_timer(&sp->u.iocb_cmd.timer);
sp->free = qla2x00_sp_free;
}
...@@ -22,18 +22,19 @@ static inline uint16_t ...@@ -22,18 +22,19 @@ static inline uint16_t
qla2x00_get_cmd_direction(srb_t *sp) qla2x00_get_cmd_direction(srb_t *sp)
{ {
uint16_t cflags; uint16_t cflags;
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
cflags = 0; cflags = 0;
/* Set transfer direction */ /* Set transfer direction */
if (sp->cmd->sc_data_direction == DMA_TO_DEVICE) { if (cmd->sc_data_direction == DMA_TO_DEVICE) {
cflags = CF_WRITE; cflags = CF_WRITE;
sp->fcport->vha->hw->qla_stats.output_bytes += sp->fcport->vha->hw->qla_stats.output_bytes +=
scsi_bufflen(sp->cmd); scsi_bufflen(cmd);
} else if (sp->cmd->sc_data_direction == DMA_FROM_DEVICE) { } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
cflags = CF_READ; cflags = CF_READ;
sp->fcport->vha->hw->qla_stats.input_bytes += sp->fcport->vha->hw->qla_stats.input_bytes +=
scsi_bufflen(sp->cmd); scsi_bufflen(cmd);
} }
return (cflags); return (cflags);
} }
...@@ -143,12 +144,13 @@ qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, struct req_que *req) ...@@ -143,12 +144,13 @@ qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, struct req_que *req)
static inline int static inline int
qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts) qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
{ {
uint8_t guard = scsi_host_get_guard(sp->cmd->device->host); struct scsi_cmnd *cmd = GET_CMD_SP(sp);
uint8_t guard = scsi_host_get_guard(cmd->device->host);
/* We only support T10 DIF right now */ /* We only support T10 DIF right now */
if (guard != SHOST_DIX_GUARD_CRC) { if (guard != SHOST_DIX_GUARD_CRC) {
ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3007, ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3007,
"Unsupported guard: %d for cmd=%p.\n", guard, sp->cmd); "Unsupported guard: %d for cmd=%p.\n", guard, cmd);
return 0; return 0;
} }
...@@ -156,7 +158,7 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts) ...@@ -156,7 +158,7 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
*fw_prot_opts = 0; *fw_prot_opts = 0;
/* Translate SCSI opcode to a protection opcode */ /* Translate SCSI opcode to a protection opcode */
switch (scsi_get_prot_op(sp->cmd)) { switch (scsi_get_prot_op(cmd)) {
case SCSI_PROT_READ_STRIP: case SCSI_PROT_READ_STRIP:
*fw_prot_opts |= PO_MODE_DIF_REMOVE; *fw_prot_opts |= PO_MODE_DIF_REMOVE;
break; break;
...@@ -180,7 +182,7 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts) ...@@ -180,7 +182,7 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
break; break;
} }
return scsi_prot_sg_count(sp->cmd); return scsi_prot_sg_count(cmd);
} }
/* /*
...@@ -201,7 +203,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt, ...@@ -201,7 +203,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
struct scatterlist *sg; struct scatterlist *sg;
int i; int i;
cmd = sp->cmd; cmd = GET_CMD_SP(sp);
/* Update entry type to indicate Command Type 2 IOCB */ /* Update entry type to indicate Command Type 2 IOCB */
*((uint32_t *)(&cmd_pkt->entry_type)) = *((uint32_t *)(&cmd_pkt->entry_type)) =
...@@ -259,7 +261,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt, ...@@ -259,7 +261,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
struct scatterlist *sg; struct scatterlist *sg;
int i; int i;
cmd = sp->cmd; cmd = GET_CMD_SP(sp);
/* Update entry type to indicate Command Type 3 IOCB */ /* Update entry type to indicate Command Type 3 IOCB */
*((uint32_t *)(&cmd_pkt->entry_type)) = *((uint32_t *)(&cmd_pkt->entry_type)) =
...@@ -333,7 +335,7 @@ qla2x00_start_scsi(srb_t *sp) ...@@ -333,7 +335,7 @@ qla2x00_start_scsi(srb_t *sp)
vha = sp->fcport->vha; vha = sp->fcport->vha;
ha = vha->hw; ha = vha->hw;
reg = &ha->iobase->isp; reg = &ha->iobase->isp;
cmd = sp->cmd; cmd = GET_CMD_SP(sp);
req = ha->req_q_map[0]; req = ha->req_q_map[0];
rsp = ha->rsp_q_map[0]; rsp = ha->rsp_q_map[0];
/* So we know we haven't pci_map'ed anything yet */ /* So we know we haven't pci_map'ed anything yet */
...@@ -391,7 +393,7 @@ qla2x00_start_scsi(srb_t *sp) ...@@ -391,7 +393,7 @@ qla2x00_start_scsi(srb_t *sp)
req->current_outstanding_cmd = handle; req->current_outstanding_cmd = handle;
req->outstanding_cmds[handle] = sp; req->outstanding_cmds[handle] = sp;
sp->handle = handle; sp->handle = handle;
sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; cmd->host_scribble = (unsigned char *)(unsigned long)handle;
req->cnt -= req_cnt; req->cnt -= req_cnt;
cmd_pkt = (cmd_entry_t *)req->ring_ptr; cmd_pkt = (cmd_entry_t *)req->ring_ptr;
...@@ -403,7 +405,7 @@ qla2x00_start_scsi(srb_t *sp) ...@@ -403,7 +405,7 @@ qla2x00_start_scsi(srb_t *sp)
/* Set target ID and LUN number*/ /* Set target ID and LUN number*/
SET_TARGET_ID(ha, cmd_pkt->target, sp->fcport->loop_id); SET_TARGET_ID(ha, cmd_pkt->target, sp->fcport->loop_id);
cmd_pkt->lun = cpu_to_le16(sp->cmd->device->lun); cmd_pkt->lun = cpu_to_le16(cmd->device->lun);
/* Update tagged queuing modifier */ /* Update tagged queuing modifier */
if (scsi_populate_tag_msg(cmd, tag)) { if (scsi_populate_tag_msg(cmd, tag)) {
...@@ -608,7 +610,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, ...@@ -608,7 +610,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
struct dsd_dma *dsd_ptr; struct dsd_dma *dsd_ptr;
struct ct6_dsd *ctx; struct ct6_dsd *ctx;
cmd = sp->cmd; cmd = GET_CMD_SP(sp);
/* Update entry type to indicate Command Type 3 IOCB */ /* Update entry type to indicate Command Type 3 IOCB */
*((uint32_t *)(&cmd_pkt->entry_type)) = *((uint32_t *)(&cmd_pkt->entry_type)) =
...@@ -635,7 +637,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, ...@@ -635,7 +637,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
} }
cur_seg = scsi_sglist(cmd); cur_seg = scsi_sglist(cmd);
ctx = sp->ctx; ctx = GET_CMD_CTX_SP(sp);
while (tot_dsds) { while (tot_dsds) {
avail_dsds = (tot_dsds > QLA_DSDS_PER_IOCB) ? avail_dsds = (tot_dsds > QLA_DSDS_PER_IOCB) ?
...@@ -724,7 +726,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, ...@@ -724,7 +726,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
int i; int i;
struct req_que *req; struct req_que *req;
cmd = sp->cmd; cmd = GET_CMD_SP(sp);
/* Update entry type to indicate Command Type 3 IOCB */ /* Update entry type to indicate Command Type 3 IOCB */
*((uint32_t *)(&cmd_pkt->entry_type)) = *((uint32_t *)(&cmd_pkt->entry_type)) =
...@@ -744,12 +746,12 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, ...@@ -744,12 +746,12 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
cmd_pkt->task_mgmt_flags = cmd_pkt->task_mgmt_flags =
__constant_cpu_to_le16(TMF_WRITE_DATA); __constant_cpu_to_le16(TMF_WRITE_DATA);
sp->fcport->vha->hw->qla_stats.output_bytes += sp->fcport->vha->hw->qla_stats.output_bytes +=
scsi_bufflen(sp->cmd); scsi_bufflen(cmd);
} else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
cmd_pkt->task_mgmt_flags = cmd_pkt->task_mgmt_flags =
__constant_cpu_to_le16(TMF_READ_DATA); __constant_cpu_to_le16(TMF_READ_DATA);
sp->fcport->vha->hw->qla_stats.input_bytes += sp->fcport->vha->hw->qla_stats.input_bytes +=
scsi_bufflen(sp->cmd); scsi_bufflen(cmd);
} }
/* One DSD is available in the Command Type 3 IOCB */ /* One DSD is available in the Command Type 3 IOCB */
...@@ -796,7 +798,7 @@ static inline void ...@@ -796,7 +798,7 @@ static inline void
qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt, qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt,
unsigned int protcnt) unsigned int protcnt)
{ {
struct scsi_cmnd *cmd = sp->cmd; struct scsi_cmnd *cmd = GET_CMD_SP(sp);
scsi_qla_host_t *vha = shost_priv(cmd->device->host); scsi_qla_host_t *vha = shost_priv(cmd->device->host);
switch (scsi_get_prot_type(cmd)) { switch (scsi_get_prot_type(cmd)) {
...@@ -951,16 +953,16 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, ...@@ -951,16 +953,16 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
struct qla2_sgx sgx; struct qla2_sgx sgx;
dma_addr_t sle_dma; dma_addr_t sle_dma;
uint32_t sle_dma_len, tot_prot_dma_len = 0; uint32_t sle_dma_len, tot_prot_dma_len = 0;
struct scsi_cmnd *cmd = sp->cmd; struct scsi_cmnd *cmd = GET_CMD_SP(sp);
prot_int = cmd->device->sector_size; prot_int = cmd->device->sector_size;
memset(&sgx, 0, sizeof(struct qla2_sgx)); memset(&sgx, 0, sizeof(struct qla2_sgx));
sgx.tot_bytes = scsi_bufflen(sp->cmd); sgx.tot_bytes = scsi_bufflen(cmd);
sgx.cur_sg = scsi_sglist(sp->cmd); sgx.cur_sg = scsi_sglist(cmd);
sgx.sp = sp; sgx.sp = sp;
sg_prot = scsi_prot_sglist(sp->cmd); sg_prot = scsi_prot_sglist(cmd);
while (qla24xx_get_one_block_sg(prot_int, &sgx, &partial)) { while (qla24xx_get_one_block_sg(prot_int, &sgx, &partial)) {
...@@ -994,7 +996,7 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, ...@@ -994,7 +996,7 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
} }
list_add_tail(&dsd_ptr->list, list_add_tail(&dsd_ptr->list,
&((struct crc_context *)sp->ctx)->dsd_list); &((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
sp->flags |= SRB_CRC_CTX_DSD_VALID; sp->flags |= SRB_CRC_CTX_DSD_VALID;
...@@ -1043,11 +1045,12 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, ...@@ -1043,11 +1045,12 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
uint32_t *cur_dsd = dsd; uint32_t *cur_dsd = dsd;
int i; int i;
uint16_t used_dsds = tot_dsds; uint16_t used_dsds = tot_dsds;
scsi_qla_host_t *vha = shost_priv(sp->cmd->device->host); struct scsi_cmnd *cmd = GET_CMD_SP(sp);
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
uint8_t *cp; uint8_t *cp;
scsi_for_each_sg(sp->cmd, sg, tot_dsds, i) { scsi_for_each_sg(cmd, sg, tot_dsds, i) {
dma_addr_t sle_dma; dma_addr_t sle_dma;
/* Allocate additional continuation packets? */ /* Allocate additional continuation packets? */
...@@ -1077,7 +1080,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, ...@@ -1077,7 +1080,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
} }
list_add_tail(&dsd_ptr->list, list_add_tail(&dsd_ptr->list,
&((struct crc_context *)sp->ctx)->dsd_list); &((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
sp->flags |= SRB_CRC_CTX_DSD_VALID; sp->flags |= SRB_CRC_CTX_DSD_VALID;
...@@ -1090,17 +1093,16 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, ...@@ -1090,17 +1093,16 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
sle_dma = sg_dma_address(sg); sle_dma = sg_dma_address(sg);
ql_dbg(ql_dbg_io, vha, 0x300a, ql_dbg(ql_dbg_io, vha, 0x300a,
"sg entry %d - addr=0x%x 0x%x, " "len=%d for cmd=%p.\n", "sg entry %d - addr=0x%x 0x%x, " "len=%d for cmd=%p.\n",
i, LSD(sle_dma), MSD(sle_dma), sg_dma_len(sg), i, LSD(sle_dma), MSD(sle_dma), sg_dma_len(sg), cmd);
sp->cmd);
*cur_dsd++ = cpu_to_le32(LSD(sle_dma)); *cur_dsd++ = cpu_to_le32(LSD(sle_dma));
*cur_dsd++ = cpu_to_le32(MSD(sle_dma)); *cur_dsd++ = cpu_to_le32(MSD(sle_dma));
*cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); *cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
avail_dsds--; avail_dsds--;
if (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_PASS) { if (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_PASS) {
cp = page_address(sg_page(sg)) + sg->offset; cp = page_address(sg_page(sg)) + sg->offset;
ql_dbg(ql_dbg_io, vha, 0x300b, ql_dbg(ql_dbg_io, vha, 0x300b,
"User data buffer=%p for cmd=%p.\n", cp, sp->cmd); "User data buffer=%p for cmd=%p.\n", cp, cmd);
} }
} }
/* Null termination */ /* Null termination */
...@@ -1127,8 +1129,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, ...@@ -1127,8 +1129,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
uint8_t *cp; uint8_t *cp;
cmd = GET_CMD_SP(sp);
cmd = sp->cmd;
scsi_for_each_prot_sg(cmd, sg, tot_dsds, i) { scsi_for_each_prot_sg(cmd, sg, tot_dsds, i) {
dma_addr_t sle_dma; dma_addr_t sle_dma;
...@@ -1159,7 +1160,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, ...@@ -1159,7 +1160,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
} }
list_add_tail(&dsd_ptr->list, list_add_tail(&dsd_ptr->list,
&((struct crc_context *)sp->ctx)->dsd_list); &((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
sp->flags |= SRB_CRC_CTX_DSD_VALID; sp->flags |= SRB_CRC_CTX_DSD_VALID;
...@@ -1170,7 +1171,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, ...@@ -1170,7 +1171,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
cur_dsd = (uint32_t *)next_dsd; cur_dsd = (uint32_t *)next_dsd;
} }
sle_dma = sg_dma_address(sg); sle_dma = sg_dma_address(sg);
if (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_PASS) { if (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_PASS) {
ql_dbg(ql_dbg_io, vha, 0x3027, ql_dbg(ql_dbg_io, vha, 0x3027,
"%s(): %p, sg_entry %d - " "%s(): %p, sg_entry %d - "
"addr=0x%x0x%x, len=%d.\n", "addr=0x%x0x%x, len=%d.\n",
...@@ -1181,7 +1182,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, ...@@ -1181,7 +1182,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
*cur_dsd++ = cpu_to_le32(MSD(sle_dma)); *cur_dsd++ = cpu_to_le32(MSD(sle_dma));
*cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); *cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
if (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_PASS) { if (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_PASS) {
cp = page_address(sg_page(sg)) + sg->offset; cp = page_address(sg_page(sg)) + sg->offset;
ql_dbg(ql_dbg_io, vha, 0x3028, ql_dbg(ql_dbg_io, vha, 0x3028,
"%s(): Protection Data buffer = %p.\n", __func__, "%s(): Protection Data buffer = %p.\n", __func__,
...@@ -1227,7 +1228,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, ...@@ -1227,7 +1228,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
dma_addr_t crc_ctx_dma; dma_addr_t crc_ctx_dma;
char tag[2]; char tag[2];
cmd = sp->cmd; cmd = GET_CMD_SP(sp);
sgc = 0; sgc = 0;
/* Update entry type to indicate Command Type CRC_2 IOCB */ /* Update entry type to indicate Command Type CRC_2 IOCB */
...@@ -1255,15 +1256,15 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, ...@@ -1255,15 +1256,15 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
__constant_cpu_to_le16(CF_READ_DATA); __constant_cpu_to_le16(CF_READ_DATA);
} }
if ((scsi_get_prot_op(sp->cmd) == SCSI_PROT_READ_INSERT) || if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) ||
(scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_STRIP) || (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP) ||
(scsi_get_prot_op(sp->cmd) == SCSI_PROT_READ_STRIP) || (scsi_get_prot_op(cmd) == SCSI_PROT_READ_STRIP) ||
(scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_INSERT)) (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_INSERT))
bundling = 0; bundling = 0;
/* Allocate CRC context from global pool */ /* Allocate CRC context from global pool */
crc_ctx_pkt = sp->ctx = dma_pool_alloc(ha->dl_dma_pool, crc_ctx_pkt = sp->u.scmd.ctx =
GFP_ATOMIC, &crc_ctx_dma); dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma);
if (!crc_ctx_pkt) if (!crc_ctx_pkt)
goto crc_queuing_error; goto crc_queuing_error;
...@@ -1309,7 +1310,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, ...@@ -1309,7 +1310,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
else if (cmd->sc_data_direction == DMA_FROM_DEVICE) else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
fcp_cmnd->additional_cdb_len |= 2; fcp_cmnd->additional_cdb_len |= 2;
int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); int_to_scsilun(cmd->device->lun, &fcp_cmnd->lun);
memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len);
cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32(
...@@ -1344,7 +1345,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, ...@@ -1344,7 +1345,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
blk_size = cmd->device->sector_size; blk_size = cmd->device->sector_size;
dif_bytes = (data_bytes / blk_size) * 8; dif_bytes = (data_bytes / blk_size) * 8;
switch (scsi_get_prot_op(sp->cmd)) { switch (scsi_get_prot_op(GET_CMD_SP(sp))) {
case SCSI_PROT_READ_INSERT: case SCSI_PROT_READ_INSERT:
case SCSI_PROT_WRITE_STRIP: case SCSI_PROT_WRITE_STRIP:
total_bytes = data_bytes; total_bytes = data_bytes;
...@@ -1444,7 +1445,7 @@ qla24xx_start_scsi(srb_t *sp) ...@@ -1444,7 +1445,7 @@ qla24xx_start_scsi(srb_t *sp)
uint16_t tot_dsds; uint16_t tot_dsds;
struct req_que *req = NULL; struct req_que *req = NULL;
struct rsp_que *rsp = NULL; struct rsp_que *rsp = NULL;
struct scsi_cmnd *cmd = sp->cmd; struct scsi_cmnd *cmd = GET_CMD_SP(sp);
struct scsi_qla_host *vha = sp->fcport->vha; struct scsi_qla_host *vha = sp->fcport->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
char tag[2]; char tag[2];
...@@ -1509,7 +1510,7 @@ qla24xx_start_scsi(srb_t *sp) ...@@ -1509,7 +1510,7 @@ qla24xx_start_scsi(srb_t *sp)
req->current_outstanding_cmd = handle; req->current_outstanding_cmd = handle;
req->outstanding_cmds[handle] = sp; req->outstanding_cmds[handle] = sp;
sp->handle = handle; sp->handle = handle;
sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; cmd->host_scribble = (unsigned char *)(unsigned long)handle;
req->cnt -= req_cnt; req->cnt -= req_cnt;
cmd_pkt = (struct cmd_type_7 *)req->ring_ptr; cmd_pkt = (struct cmd_type_7 *)req->ring_ptr;
...@@ -1528,7 +1529,7 @@ qla24xx_start_scsi(srb_t *sp) ...@@ -1528,7 +1529,7 @@ qla24xx_start_scsi(srb_t *sp)
cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
cmd_pkt->vp_index = sp->fcport->vp_idx; cmd_pkt->vp_index = sp->fcport->vp_idx;
int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
/* Update tagged queuing modifier -- default is TSK_SIMPLE (0). */ /* Update tagged queuing modifier -- default is TSK_SIMPLE (0). */
...@@ -1610,7 +1611,7 @@ qla24xx_dif_start_scsi(srb_t *sp) ...@@ -1610,7 +1611,7 @@ qla24xx_dif_start_scsi(srb_t *sp)
uint16_t fw_prot_opts = 0; uint16_t fw_prot_opts = 0;
struct req_que *req = NULL; struct req_que *req = NULL;
struct rsp_que *rsp = NULL; struct rsp_que *rsp = NULL;
struct scsi_cmnd *cmd = sp->cmd; struct scsi_cmnd *cmd = GET_CMD_SP(sp);
struct scsi_qla_host *vha = sp->fcport->vha; struct scsi_qla_host *vha = sp->fcport->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct cmd_type_crc_2 *cmd_pkt; struct cmd_type_crc_2 *cmd_pkt;
...@@ -1727,7 +1728,7 @@ qla24xx_dif_start_scsi(srb_t *sp) ...@@ -1727,7 +1728,7 @@ qla24xx_dif_start_scsi(srb_t *sp)
req->current_outstanding_cmd = handle; req->current_outstanding_cmd = handle;
req->outstanding_cmds[handle] = sp; req->outstanding_cmds[handle] = sp;
sp->handle = handle; sp->handle = handle;
sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; cmd->host_scribble = (unsigned char *)(unsigned long)handle;
req->cnt -= req_cnt; req->cnt -= req_cnt;
/* Fill-in common area */ /* Fill-in common area */
...@@ -1743,7 +1744,7 @@ qla24xx_dif_start_scsi(srb_t *sp) ...@@ -1743,7 +1744,7 @@ qla24xx_dif_start_scsi(srb_t *sp)
cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
/* Total Data and protection segment(s) */ /* Total Data and protection segment(s) */
...@@ -1796,7 +1797,7 @@ qla24xx_dif_start_scsi(srb_t *sp) ...@@ -1796,7 +1797,7 @@ qla24xx_dif_start_scsi(srb_t *sp)
static void qla25xx_set_que(srb_t *sp, struct rsp_que **rsp) static void qla25xx_set_que(srb_t *sp, struct rsp_que **rsp)
{ {
struct scsi_cmnd *cmd = sp->cmd; struct scsi_cmnd *cmd = GET_CMD_SP(sp);
struct qla_hw_data *ha = sp->fcport->vha->hw; struct qla_hw_data *ha = sp->fcport->vha->hw;
int affinity = cmd->request->cpu; int affinity = cmd->request->cpu;
...@@ -1817,7 +1818,6 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp) ...@@ -1817,7 +1818,6 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp)
uint32_t index, handle; uint32_t index, handle;
request_t *pkt; request_t *pkt;
uint16_t cnt, req_cnt; uint16_t cnt, req_cnt;
struct srb_ctx *ctx;
pkt = NULL; pkt = NULL;
req_cnt = 1; req_cnt = 1;
...@@ -1847,10 +1847,8 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp) ...@@ -1847,10 +1847,8 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp)
sp->handle = handle; sp->handle = handle;
/* Adjust entry-counts as needed. */ /* Adjust entry-counts as needed. */
if (sp->ctx) { if (sp->type != SRB_SCSI_CMD)
ctx = sp->ctx; req_cnt = sp->iocbs;
req_cnt = ctx->iocbs;
}
skip_cmd_array: skip_cmd_array:
/* Check for room on request queue. */ /* Check for room on request queue. */
...@@ -1888,8 +1886,7 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp) ...@@ -1888,8 +1886,7 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *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)
{ {
struct srb_ctx *ctx = sp->ctx; struct srb_iocb *lio = &sp->u.iocb_cmd;
struct srb_iocb *lio = ctx->u.iocb_cmd;
logio->entry_type = LOGINOUT_PORT_IOCB_TYPE; logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI); logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
...@@ -1908,8 +1905,7 @@ static void ...@@ -1908,8 +1905,7 @@ static void
qla2x00_login_iocb(srb_t *sp, struct mbx_entry *mbx) qla2x00_login_iocb(srb_t *sp, struct mbx_entry *mbx)
{ {
struct qla_hw_data *ha = sp->fcport->vha->hw; struct qla_hw_data *ha = sp->fcport->vha->hw;
struct srb_ctx *ctx = sp->ctx; struct srb_iocb *lio = &sp->u.iocb_cmd;
struct srb_iocb *lio = ctx->u.iocb_cmd;
uint16_t opts; uint16_t opts;
mbx->entry_type = MBX_IOCB_TYPE; mbx->entry_type = MBX_IOCB_TYPE;
...@@ -1998,8 +1994,7 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk) ...@@ -1998,8 +1994,7 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
struct fc_port *fcport = sp->fcport; struct fc_port *fcport = sp->fcport;
scsi_qla_host_t *vha = fcport->vha; scsi_qla_host_t *vha = fcport->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct srb_ctx *ctx = sp->ctx; struct srb_iocb *iocb = &sp->u.iocb_cmd;
struct srb_iocb *iocb = ctx->u.iocb_cmd;
struct req_que *req = vha->req; struct req_que *req = vha->req;
flags = iocb->u.tmf.flags; flags = iocb->u.tmf.flags;
...@@ -2026,7 +2021,7 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk) ...@@ -2026,7 +2021,7 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
static void static void
qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
{ {
struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job; struct fc_bsg_job *bsg_job = sp->u.bsg_job;
els_iocb->entry_type = ELS_IOCB_TYPE; els_iocb->entry_type = ELS_IOCB_TYPE;
els_iocb->entry_count = 1; els_iocb->entry_count = 1;
...@@ -2040,7 +2035,7 @@ qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) ...@@ -2040,7 +2035,7 @@ qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
els_iocb->rx_dsd_count = __constant_cpu_to_le16(bsg_job->reply_payload.sg_cnt); els_iocb->rx_dsd_count = __constant_cpu_to_le16(bsg_job->reply_payload.sg_cnt);
els_iocb->opcode = els_iocb->opcode =
(((struct srb_ctx *)sp->ctx)->type == SRB_ELS_CMD_RPT) ? sp->type == SRB_ELS_CMD_RPT ?
bsg_job->request->rqst_data.r_els.els_code : bsg_job->request->rqst_data.r_els.els_code :
bsg_job->request->rqst_data.h_els.command_code; bsg_job->request->rqst_data.h_els.command_code;
els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa; els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
...@@ -2077,7 +2072,7 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb) ...@@ -2077,7 +2072,7 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb)
uint16_t tot_dsds; uint16_t tot_dsds;
scsi_qla_host_t *vha = sp->fcport->vha; scsi_qla_host_t *vha = sp->fcport->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job; struct fc_bsg_job *bsg_job = sp->u.bsg_job;
int loop_iterartion = 0; int loop_iterartion = 0;
int cont_iocb_prsnt = 0; int cont_iocb_prsnt = 0;
int entry_count = 1; int entry_count = 1;
...@@ -2154,7 +2149,7 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) ...@@ -2154,7 +2149,7 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb)
uint16_t tot_dsds; uint16_t tot_dsds;
scsi_qla_host_t *vha = sp->fcport->vha; scsi_qla_host_t *vha = sp->fcport->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job; struct fc_bsg_job *bsg_job = sp->u.bsg_job;
int loop_iterartion = 0; int loop_iterartion = 0;
int cont_iocb_prsnt = 0; int cont_iocb_prsnt = 0;
int entry_count = 1; int entry_count = 1;
...@@ -2249,7 +2244,7 @@ qla82xx_start_scsi(srb_t *sp) ...@@ -2249,7 +2244,7 @@ qla82xx_start_scsi(srb_t *sp)
/* Setup device pointers. */ /* Setup device pointers. */
ret = 0; ret = 0;
reg = &ha->iobase->isp82; reg = &ha->iobase->isp82;
cmd = sp->cmd; cmd = GET_CMD_SP(sp);
req = vha->req; req = vha->req;
rsp = ha->rsp_q_map[0]; rsp = ha->rsp_q_map[0];
...@@ -2353,12 +2348,14 @@ qla82xx_start_scsi(srb_t *sp) ...@@ -2353,12 +2348,14 @@ qla82xx_start_scsi(srb_t *sp)
if (req->cnt < (req_cnt + 2)) if (req->cnt < (req_cnt + 2))
goto queuing_error; goto queuing_error;
ctx = sp->ctx = mempool_alloc(ha->ctx_mempool, GFP_ATOMIC); ctx = sp->u.scmd.ctx =
if (!sp->ctx) { mempool_alloc(ha->ctx_mempool, GFP_ATOMIC);
if (!ctx) {
ql_log(ql_log_fatal, vha, 0x3010, ql_log(ql_log_fatal, vha, 0x3010,
"Failed to allocate ctx for cmd=%p.\n", cmd); "Failed to allocate ctx for cmd=%p.\n", cmd);
goto queuing_error; goto queuing_error;
} }
memset(ctx, 0, sizeof(struct ct6_dsd)); memset(ctx, 0, sizeof(struct ct6_dsd));
ctx->fcp_cmnd = dma_pool_alloc(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd = dma_pool_alloc(ha->fcp_cmnd_dma_pool,
GFP_ATOMIC, &ctx->fcp_cmnd_dma); GFP_ATOMIC, &ctx->fcp_cmnd_dma);
...@@ -2409,12 +2406,12 @@ qla82xx_start_scsi(srb_t *sp) ...@@ -2409,12 +2406,12 @@ qla82xx_start_scsi(srb_t *sp)
if (qla24xx_build_scsi_type_6_iocbs(sp, cmd_pkt, tot_dsds)) if (qla24xx_build_scsi_type_6_iocbs(sp, cmd_pkt, tot_dsds))
goto queuing_error_fcp_cmnd; goto queuing_error_fcp_cmnd;
int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
/* build FCP_CMND IU */ /* build FCP_CMND IU */
memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd));
int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun); int_to_scsilun(cmd->device->lun, &ctx->fcp_cmnd->lun);
ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len; ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len;
if (cmd->sc_data_direction == DMA_TO_DEVICE) if (cmd->sc_data_direction == DMA_TO_DEVICE)
...@@ -2494,7 +2491,7 @@ qla82xx_start_scsi(srb_t *sp) ...@@ -2494,7 +2491,7 @@ qla82xx_start_scsi(srb_t *sp)
cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
cmd_pkt->vp_index = sp->fcport->vp_idx; cmd_pkt->vp_index = sp->fcport->vp_idx;
int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, host_to_fcp_swap((uint8_t *)&cmd_pkt->lun,
sizeof(cmd_pkt->lun)); sizeof(cmd_pkt->lun));
...@@ -2537,7 +2534,7 @@ qla82xx_start_scsi(srb_t *sp) ...@@ -2537,7 +2534,7 @@ qla82xx_start_scsi(srb_t *sp)
req->current_outstanding_cmd = handle; req->current_outstanding_cmd = handle;
req->outstanding_cmds[handle] = sp; req->outstanding_cmds[handle] = sp;
sp->handle = handle; sp->handle = handle;
sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; cmd->host_scribble = (unsigned char *)(unsigned long)handle;
req->cnt -= req_cnt; req->cnt -= req_cnt;
wmb(); wmb();
...@@ -2583,9 +2580,9 @@ qla82xx_start_scsi(srb_t *sp) ...@@ -2583,9 +2580,9 @@ qla82xx_start_scsi(srb_t *sp)
if (tot_dsds) if (tot_dsds)
scsi_dma_unmap(cmd); scsi_dma_unmap(cmd);
if (sp->ctx) { if (sp->u.scmd.ctx) {
mempool_free(sp->ctx, ha->ctx_mempool); mempool_free(sp->u.scmd.ctx, ha->ctx_mempool);
sp->ctx = NULL; sp->u.scmd.ctx = NULL;
} }
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
...@@ -2598,7 +2595,6 @@ qla2x00_start_sp(srb_t *sp) ...@@ -2598,7 +2595,6 @@ qla2x00_start_sp(srb_t *sp)
int rval; int rval;
struct qla_hw_data *ha = sp->fcport->vha->hw; struct qla_hw_data *ha = sp->fcport->vha->hw;
void *pkt; void *pkt;
struct srb_ctx *ctx = sp->ctx;
unsigned long flags; unsigned long flags;
rval = QLA_FUNCTION_FAILED; rval = QLA_FUNCTION_FAILED;
...@@ -2611,7 +2607,7 @@ qla2x00_start_sp(srb_t *sp) ...@@ -2611,7 +2607,7 @@ qla2x00_start_sp(srb_t *sp)
} }
rval = QLA_SUCCESS; rval = QLA_SUCCESS;
switch (ctx->type) { switch (sp->type) {
case SRB_LOGIN_CMD: case SRB_LOGIN_CMD:
IS_FWI2_CAPABLE(ha) ? IS_FWI2_CAPABLE(ha) ?
qla24xx_login_iocb(sp, pkt) : qla24xx_login_iocb(sp, pkt) :
......
...@@ -853,8 +853,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha, ...@@ -853,8 +853,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
req->outstanding_cmds[index] = NULL; req->outstanding_cmds[index] = NULL;
/* Save ISP completion status */ /* Save ISP completion status */
sp->cmd->result = DID_OK << 16; sp->done(ha, sp, DID_OK << 16);
qla2x00_sp_compl(ha, sp);
} else { } else {
ql_log(ql_log_warn, vha, 0x3016, "Invalid SCSI SRB.\n"); ql_log(ql_log_warn, vha, 0x3016, "Invalid SCSI SRB.\n");
...@@ -911,7 +910,6 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -911,7 +910,6 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
fc_port_t *fcport; fc_port_t *fcport;
srb_t *sp; srb_t *sp;
struct srb_iocb *lio; struct srb_iocb *lio;
struct srb_ctx *ctx;
uint16_t *data; uint16_t *data;
uint16_t status; uint16_t status;
...@@ -919,9 +917,8 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -919,9 +917,8 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
if (!sp) if (!sp)
return; return;
ctx = sp->ctx; lio = &sp->u.iocb_cmd;
lio = ctx->u.iocb_cmd; type = sp->name;
type = ctx->name;
fcport = sp->fcport; fcport = sp->fcport;
data = lio->u.logio.data; data = lio->u.logio.data;
...@@ -945,7 +942,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -945,7 +942,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
} }
status = le16_to_cpu(mbx->status); status = le16_to_cpu(mbx->status);
if (status == 0x30 && ctx->type == SRB_LOGIN_CMD && if (status == 0x30 && sp->type == SRB_LOGIN_CMD &&
le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE)
status = 0; status = 0;
if (!status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) { if (!status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) {
...@@ -956,7 +953,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -956,7 +953,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
le16_to_cpu(mbx->mb1)); le16_to_cpu(mbx->mb1));
data[0] = MBS_COMMAND_COMPLETE; data[0] = MBS_COMMAND_COMPLETE;
if (ctx->type == SRB_LOGIN_CMD) { if (sp->type == SRB_LOGIN_CMD) {
fcport->port_type = FCT_TARGET; fcport->port_type = FCT_TARGET;
if (le16_to_cpu(mbx->mb1) & BIT_0) if (le16_to_cpu(mbx->mb1) & BIT_0)
fcport->port_type = FCT_INITIATOR; fcport->port_type = FCT_INITIATOR;
...@@ -987,7 +984,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -987,7 +984,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
le16_to_cpu(mbx->mb7)); le16_to_cpu(mbx->mb7));
logio_done: logio_done:
lio->done(sp); sp->done(vha, sp, 0);
} }
static void static void
...@@ -996,29 +993,18 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -996,29 +993,18 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
{ {
const char func[] = "CT_IOCB"; const char func[] = "CT_IOCB";
const char *type; const char *type;
struct qla_hw_data *ha = vha->hw;
srb_t *sp; srb_t *sp;
struct srb_ctx *sp_bsg;
struct fc_bsg_job *bsg_job; struct fc_bsg_job *bsg_job;
uint16_t comp_status; uint16_t comp_status;
int res;
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
if (!sp) if (!sp)
return; return;
sp_bsg = sp->ctx; bsg_job = sp->u.bsg_job;
bsg_job = sp_bsg->u.bsg_job;
type = NULL;
switch (sp_bsg->type) {
case SRB_CT_CMD:
type = "ct pass-through"; type = "ct pass-through";
break;
default:
ql_log(ql_log_warn, vha, 0x5047,
"Unrecognized SRB: (%p) type=%d.\n", sp, sp_bsg->type);
return;
}
comp_status = le16_to_cpu(pkt->comp_status); comp_status = le16_to_cpu(pkt->comp_status);
...@@ -1030,7 +1016,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1030,7 +1016,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
if (comp_status != CS_COMPLETE) { if (comp_status != CS_COMPLETE) {
if (comp_status == CS_DATA_UNDERRUN) { if (comp_status == CS_DATA_UNDERRUN) {
bsg_job->reply->result = DID_OK << 16; res = DID_OK << 16;
bsg_job->reply->reply_payload_rcv_len = bsg_job->reply->reply_payload_rcv_len =
le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len); le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len);
...@@ -1043,30 +1029,19 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1043,30 +1029,19 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
ql_log(ql_log_warn, vha, 0x5049, ql_log(ql_log_warn, vha, 0x5049,
"CT pass-through-%s error " "CT pass-through-%s error "
"comp_status-status=0x%x.\n", type, comp_status); "comp_status-status=0x%x.\n", type, comp_status);
bsg_job->reply->result = DID_ERROR << 16; res = DID_ERROR << 16;
bsg_job->reply->reply_payload_rcv_len = 0; bsg_job->reply->reply_payload_rcv_len = 0;
} }
ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035, ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035,
(uint8_t *)pkt, sizeof(*pkt)); (uint8_t *)pkt, sizeof(*pkt));
} else { } else {
bsg_job->reply->result = DID_OK << 16; res = DID_OK << 16;
bsg_job->reply->reply_payload_rcv_len = bsg_job->reply->reply_payload_rcv_len =
bsg_job->reply_payload.payload_len; bsg_job->reply_payload.payload_len;
bsg_job->reply_len = 0; bsg_job->reply_len = 0;
} }
dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, sp->done(vha, sp, res);
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
if (sp_bsg->type == SRB_ELS_CMD_HST || sp_bsg->type == SRB_CT_CMD)
kfree(sp->fcport);
kfree(sp->ctx);
mempool_free(sp, ha->srb_mempool);
bsg_job->job_done(bsg_job);
} }
static void static void
...@@ -1075,22 +1050,20 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1075,22 +1050,20 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
{ {
const char func[] = "ELS_CT_IOCB"; const char func[] = "ELS_CT_IOCB";
const char *type; const char *type;
struct qla_hw_data *ha = vha->hw;
srb_t *sp; srb_t *sp;
struct srb_ctx *sp_bsg;
struct fc_bsg_job *bsg_job; struct fc_bsg_job *bsg_job;
uint16_t comp_status; uint16_t comp_status;
uint32_t fw_status[3]; uint32_t fw_status[3];
uint8_t* fw_sts_ptr; uint8_t* fw_sts_ptr;
int res;
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
if (!sp) if (!sp)
return; return;
sp_bsg = sp->ctx; bsg_job = sp->u.bsg_job;
bsg_job = sp_bsg->u.bsg_job;
type = NULL; type = NULL;
switch (sp_bsg->type) { switch (sp->type) {
case SRB_ELS_CMD_RPT: case SRB_ELS_CMD_RPT:
case SRB_ELS_CMD_HST: case SRB_ELS_CMD_HST:
type = "els"; type = "els";
...@@ -1100,7 +1073,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1100,7 +1073,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
break; break;
default: default:
ql_log(ql_log_warn, vha, 0x503e, ql_log(ql_log_warn, vha, 0x503e,
"Unrecognized SRB: (%p) type=%d.\n", sp, sp_bsg->type); "Unrecognized SRB: (%p) type=%d.\n", sp, sp->type);
return; return;
} }
...@@ -1116,9 +1089,9 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1116,9 +1089,9 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
if (comp_status != CS_COMPLETE) { if (comp_status != CS_COMPLETE) {
if (comp_status == CS_DATA_UNDERRUN) { if (comp_status == CS_DATA_UNDERRUN) {
bsg_job->reply->result = DID_OK << 16; res = DID_OK << 16;
bsg_job->reply->reply_payload_rcv_len = bsg_job->reply->reply_payload_rcv_len =
le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count); le16_to_cpu(((struct els_sts_entry_24xx *)pkt)->total_byte_count);
ql_log(ql_log_info, vha, 0x503f, ql_log(ql_log_info, vha, 0x503f,
"ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x " "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x "
...@@ -1138,7 +1111,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1138,7 +1111,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
pkt)->error_subcode_1), pkt)->error_subcode_1),
le16_to_cpu(((struct els_sts_entry_24xx *) le16_to_cpu(((struct els_sts_entry_24xx *)
pkt)->error_subcode_2)); pkt)->error_subcode_2));
bsg_job->reply->result = DID_ERROR << 16; res = DID_ERROR << 16;
bsg_job->reply->reply_payload_rcv_len = 0; bsg_job->reply->reply_payload_rcv_len = 0;
fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply); fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
memcpy( fw_sts_ptr, fw_status, sizeof(fw_status)); memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
...@@ -1147,23 +1120,12 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1147,23 +1120,12 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
(uint8_t *)pkt, sizeof(*pkt)); (uint8_t *)pkt, sizeof(*pkt));
} }
else { else {
bsg_job->reply->result = DID_OK << 16; res = DID_OK << 16;
bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len; bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
bsg_job->reply_len = 0; bsg_job->reply_len = 0;
} }
dma_unmap_sg(&ha->pdev->dev, sp->done(vha, sp, res);
bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
dma_unmap_sg(&ha->pdev->dev,
bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
if ((sp_bsg->type == SRB_ELS_CMD_HST) ||
(sp_bsg->type == SRB_CT_CMD))
kfree(sp->fcport);
kfree(sp->ctx);
mempool_free(sp, ha->srb_mempool);
bsg_job->job_done(bsg_job);
} }
static void static void
...@@ -1175,7 +1137,6 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1175,7 +1137,6 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
fc_port_t *fcport; fc_port_t *fcport;
srb_t *sp; srb_t *sp;
struct srb_iocb *lio; struct srb_iocb *lio;
struct srb_ctx *ctx;
uint16_t *data; uint16_t *data;
uint32_t iop[2]; uint32_t iop[2];
...@@ -1183,9 +1144,8 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1183,9 +1144,8 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
if (!sp) if (!sp)
return; return;
ctx = sp->ctx; lio = &sp->u.iocb_cmd;
lio = ctx->u.iocb_cmd; type = sp->name;
type = ctx->name;
fcport = sp->fcport; fcport = sp->fcport;
data = lio->u.logio.data; data = lio->u.logio.data;
...@@ -1213,7 +1173,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1213,7 +1173,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
le32_to_cpu(logio->io_parameter[0])); le32_to_cpu(logio->io_parameter[0]));
data[0] = MBS_COMMAND_COMPLETE; data[0] = MBS_COMMAND_COMPLETE;
if (ctx->type != SRB_LOGIN_CMD) if (sp->type != SRB_LOGIN_CMD)
goto logio_done; goto logio_done;
iop[0] = le32_to_cpu(logio->io_parameter[0]); iop[0] = le32_to_cpu(logio->io_parameter[0]);
...@@ -1256,7 +1216,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1256,7 +1216,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
le32_to_cpu(logio->io_parameter[1])); le32_to_cpu(logio->io_parameter[1]));
logio_done: logio_done:
lio->done(sp); sp->done(vha, sp, 0);
} }
static void static void
...@@ -1268,7 +1228,6 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1268,7 +1228,6 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
fc_port_t *fcport; fc_port_t *fcport;
srb_t *sp; srb_t *sp;
struct srb_iocb *iocb; struct srb_iocb *iocb;
struct srb_ctx *ctx;
struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk; struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk;
int error = 1; int error = 1;
...@@ -1276,9 +1235,8 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1276,9 +1235,8 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
if (!sp) if (!sp)
return; return;
ctx = sp->ctx; iocb = &sp->u.iocb_cmd;
iocb = ctx->u.iocb_cmd; type = sp->name;
type = ctx->name;
fcport = sp->fcport; fcport = sp->fcport;
if (sts->entry_status) { if (sts->entry_status) {
...@@ -1312,7 +1270,7 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1312,7 +1270,7 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
(uint8_t *)sts, sizeof(*sts)); (uint8_t *)sts, sizeof(*sts));
} }
iocb->done(sp); sp->done(vha, sp, 0);
} }
/** /**
...@@ -1398,25 +1356,32 @@ qla2x00_process_response_queue(struct rsp_que *rsp) ...@@ -1398,25 +1356,32 @@ qla2x00_process_response_queue(struct rsp_que *rsp)
static inline void static inline void
qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len, qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len,
uint32_t sense_len, struct rsp_que *rsp) uint32_t sense_len, struct rsp_que *rsp, int res)
{ {
struct scsi_qla_host *vha = sp->fcport->vha; struct scsi_qla_host *vha = sp->fcport->vha;
struct scsi_cmnd *cp = sp->cmd; struct scsi_cmnd *cp = GET_CMD_SP(sp);
uint32_t track_sense_len;
if (sense_len >= SCSI_SENSE_BUFFERSIZE) if (sense_len >= SCSI_SENSE_BUFFERSIZE)
sense_len = SCSI_SENSE_BUFFERSIZE; sense_len = SCSI_SENSE_BUFFERSIZE;
sp->request_sense_length = sense_len; SET_CMD_SENSE_LEN(sp, sense_len);
sp->request_sense_ptr = cp->sense_buffer; SET_CMD_SENSE_PTR(sp, cp->sense_buffer);
if (sp->request_sense_length > par_sense_len) track_sense_len = sense_len;
if (sense_len > par_sense_len)
sense_len = par_sense_len; sense_len = par_sense_len;
memcpy(cp->sense_buffer, sense_data, sense_len); memcpy(cp->sense_buffer, sense_data, sense_len);
sp->request_sense_ptr += sense_len; SET_CMD_SENSE_PTR(sp, cp->sense_buffer + sense_len);
sp->request_sense_length -= sense_len; track_sense_len -= sense_len;
if (sp->request_sense_length != 0) SET_CMD_SENSE_LEN(sp, track_sense_len);
if (track_sense_len != 0) {
rsp->status_srb = sp; rsp->status_srb = sp;
cp->result = res;
}
if (sense_len) { if (sense_len) {
ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x301c, ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x301c,
...@@ -1444,7 +1409,7 @@ static inline int ...@@ -1444,7 +1409,7 @@ static inline int
qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
{ {
struct scsi_qla_host *vha = sp->fcport->vha; struct scsi_qla_host *vha = sp->fcport->vha;
struct scsi_cmnd *cmd = sp->cmd; struct scsi_cmnd *cmd = GET_CMD_SP(sp);
uint8_t *ap = &sts24->data[12]; uint8_t *ap = &sts24->data[12];
uint8_t *ep = &sts24->data[20]; uint8_t *ep = &sts24->data[20];
uint32_t e_ref_tag, a_ref_tag; uint32_t e_ref_tag, a_ref_tag;
...@@ -1588,6 +1553,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1588,6 +1553,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
uint16_t que; uint16_t que;
struct req_que *req; struct req_que *req;
int logit = 1; int logit = 1;
int res = 0;
sts = (sts_entry_t *) pkt; sts = (sts_entry_t *) pkt;
sts24 = (struct sts_entry_24xx *) pkt; sts24 = (struct sts_entry_24xx *) pkt;
...@@ -1627,7 +1593,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1627,7 +1593,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
qla2xxx_wake_dpc(vha); qla2xxx_wake_dpc(vha);
return; return;
} }
cp = sp->cmd; cp = GET_CMD_SP(sp);
if (cp == NULL) { if (cp == NULL) {
ql_dbg(ql_dbg_io, vha, 0x3018, ql_dbg(ql_dbg_io, vha, 0x3018,
"Command already returned (0x%x/%p).\n", "Command already returned (0x%x/%p).\n",
...@@ -1680,7 +1646,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1680,7 +1646,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
"FCP I/O protocol failure (0x%x/0x%x).\n", "FCP I/O protocol failure (0x%x/0x%x).\n",
rsp_info_len, rsp_info[3]); rsp_info_len, rsp_info[3]);
cp->result = DID_BUS_BUSY << 16; res = DID_BUS_BUSY << 16;
goto out; goto out;
} }
} }
...@@ -1697,7 +1663,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1697,7 +1663,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
case CS_COMPLETE: case CS_COMPLETE:
case CS_QUEUE_FULL: case CS_QUEUE_FULL:
if (scsi_status == 0) { if (scsi_status == 0) {
cp->result = DID_OK << 16; res = DID_OK << 16;
break; break;
} }
if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) { if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
...@@ -1712,11 +1678,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1712,11 +1678,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
"detected (0x%x of 0x%x bytes).\n", "detected (0x%x of 0x%x bytes).\n",
resid, scsi_bufflen(cp)); resid, scsi_bufflen(cp));
cp->result = DID_ERROR << 16; res = DID_ERROR << 16;
break; break;
} }
} }
cp->result = DID_OK << 16 | lscsi_status; res = DID_OK << 16 | lscsi_status;
if (lscsi_status == SAM_STAT_TASK_SET_FULL) { if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
ql_dbg(ql_dbg_io, vha, 0x301b, ql_dbg(ql_dbg_io, vha, 0x301b,
...@@ -1732,7 +1698,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1732,7 +1698,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
break; break;
qla2x00_handle_sense(sp, sense_data, par_sense_len, sense_len, qla2x00_handle_sense(sp, sense_data, par_sense_len, sense_len,
rsp); rsp, res);
break; break;
case CS_DATA_UNDERRUN: case CS_DATA_UNDERRUN:
...@@ -1746,7 +1712,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1746,7 +1712,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
"(0x%x of 0x%x bytes).\n", "(0x%x of 0x%x bytes).\n",
resid, scsi_bufflen(cp)); resid, scsi_bufflen(cp));
cp->result = DID_ERROR << 16 | lscsi_status; res = DID_ERROR << 16 | lscsi_status;
goto check_scsi_status; goto check_scsi_status;
} }
...@@ -1758,7 +1724,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1758,7 +1724,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
"detected (0x%x of 0x%x bytes).\n", "detected (0x%x of 0x%x bytes).\n",
resid, scsi_bufflen(cp)); resid, scsi_bufflen(cp));
cp->result = DID_ERROR << 16; res = DID_ERROR << 16;
break; break;
} }
} else { } else {
...@@ -1766,11 +1732,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1766,11 +1732,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
"Dropped frame(s) detected (0x%x " "Dropped frame(s) detected (0x%x "
"of 0x%x bytes).\n", resid, scsi_bufflen(cp)); "of 0x%x bytes).\n", resid, scsi_bufflen(cp));
cp->result = DID_ERROR << 16 | lscsi_status; res = DID_ERROR << 16 | lscsi_status;
goto check_scsi_status; goto check_scsi_status;
} }
cp->result = DID_OK << 16 | lscsi_status; res = DID_OK << 16 | lscsi_status;
logit = 0; logit = 0;
check_scsi_status: check_scsi_status:
...@@ -1793,7 +1759,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1793,7 +1759,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
break; break;
qla2x00_handle_sense(sp, sense_data, par_sense_len, qla2x00_handle_sense(sp, sense_data, par_sense_len,
sense_len, rsp); sense_len, rsp, res);
} }
break; break;
...@@ -1810,7 +1776,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1810,7 +1776,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
* while we try to recover so instruct the mid layer * while we try to recover so instruct the mid layer
* to requeue until the class decides how to handle this. * to requeue until the class decides how to handle this.
*/ */
cp->result = DID_TRANSPORT_DISRUPTED << 16; res = DID_TRANSPORT_DISRUPTED << 16;
if (comp_status == CS_TIMEOUT) { if (comp_status == CS_TIMEOUT) {
if (IS_FWI2_CAPABLE(ha)) if (IS_FWI2_CAPABLE(ha))
...@@ -1829,14 +1795,14 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1829,14 +1795,14 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
break; break;
case CS_ABORTED: case CS_ABORTED:
cp->result = DID_RESET << 16; res = DID_RESET << 16;
break; break;
case CS_DIF_ERROR: case CS_DIF_ERROR:
logit = qla2x00_handle_dif_error(sp, sts24); logit = qla2x00_handle_dif_error(sp, sts24);
break; break;
default: default:
cp->result = DID_ERROR << 16; res = DID_ERROR << 16;
break; break;
} }
...@@ -1847,7 +1813,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1847,7 +1813,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
"nexus=%ld:%d:%d portid=%02x%02x%02x oxid=0x%x " "nexus=%ld:%d:%d portid=%02x%02x%02x oxid=0x%x "
"cdb=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x len=0x%x " "cdb=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x len=0x%x "
"rsp_info=0x%x resid=0x%x fw_resid=0x%x.\n", "rsp_info=0x%x resid=0x%x fw_resid=0x%x.\n",
comp_status, scsi_status, cp->result, vha->host_no, comp_status, scsi_status, res, vha->host_no,
cp->device->id, cp->device->lun, fcport->d_id.b.domain, cp->device->id, cp->device->lun, fcport->d_id.b.domain,
fcport->d_id.b.area, fcport->d_id.b.al_pa, ox_id, fcport->d_id.b.area, fcport->d_id.b.al_pa, ox_id,
cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3], cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
...@@ -1856,7 +1822,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1856,7 +1822,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
resid_len, fw_resid_len); resid_len, fw_resid_len);
if (rsp->status_srb == NULL) if (rsp->status_srb == NULL)
qla2x00_sp_compl(ha, sp); sp->done(ha, sp, res);
} }
/** /**
...@@ -1874,79 +1840,47 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) ...@@ -1874,79 +1840,47 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev); struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev);
srb_t *sp = rsp->status_srb; srb_t *sp = rsp->status_srb;
struct scsi_cmnd *cp; struct scsi_cmnd *cp;
uint32_t sense_len;
uint8_t *sense_ptr;
if (!sp || !GET_CMD_SENSE_LEN(sp))
return;
sense_len = GET_CMD_SENSE_LEN(sp);
sense_ptr = GET_CMD_SENSE_PTR(sp);
if (sp != NULL && sp->request_sense_length != 0) { cp = GET_CMD_SP(sp);
cp = sp->cmd;
if (cp == NULL) { if (cp == NULL) {
ql_log(ql_log_warn, vha, 0x3025, ql_log(ql_log_warn, vha, 0x3025,
"cmd is NULL: already returned to OS (sp=%p).\n", "cmd is NULL: already returned to OS (sp=%p).\n", sp);
sp);
rsp->status_srb = NULL; rsp->status_srb = NULL;
return; return;
} }
if (sp->request_sense_length > sizeof(pkt->data)) { if (sense_len > sizeof(pkt->data))
sense_sz = sizeof(pkt->data); sense_sz = sizeof(pkt->data);
} else { else
sense_sz = sp->request_sense_length; sense_sz = sense_len;
}
/* Move sense data. */ /* Move sense data. */
if (IS_FWI2_CAPABLE(ha)) if (IS_FWI2_CAPABLE(ha))
host_to_fcp_swap(pkt->data, sizeof(pkt->data)); host_to_fcp_swap(pkt->data, sizeof(pkt->data));
memcpy(sp->request_sense_ptr, pkt->data, sense_sz); memcpy(sense_ptr, pkt->data, sense_sz);
ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302c, ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302c,
sp->request_sense_ptr, sense_sz); sense_ptr, sense_sz);
sense_len -= sense_sz;
sense_ptr += sense_sz;
sp->request_sense_ptr += sense_sz; SET_CMD_SENSE_PTR(sp, sense_ptr);
sp->request_sense_length -= sense_sz; SET_CMD_SENSE_LEN(sp, sense_len);
/* Place command on done queue. */ /* Place command on done queue. */
if (sp->request_sense_length == 0) { if (sense_len == 0) {
rsp->status_srb = NULL; rsp->status_srb = NULL;
qla2x00_sp_compl(ha, sp); sp->done(ha, sp, cp->result);
}
}
}
static int
qla2x00_free_sp_ctx(scsi_qla_host_t *vha, srb_t *sp)
{
struct qla_hw_data *ha = vha->hw;
struct srb_ctx *ctx;
if (!sp->ctx)
return 1;
ctx = sp->ctx;
if (ctx->type == SRB_LOGIN_CMD ||
ctx->type == SRB_LOGOUT_CMD ||
ctx->type == SRB_TM_CMD) {
ctx->u.iocb_cmd->done(sp);
return 0;
} else if (ctx->type == SRB_ADISC_CMD) {
ctx->u.iocb_cmd->free(sp);
return 0;
} else {
struct fc_bsg_job *bsg_job;
bsg_job = ctx->u.bsg_job;
if (ctx->type == SRB_ELS_CMD_HST ||
ctx->type == SRB_CT_CMD)
kfree(sp->fcport);
bsg_job->reply->reply_data.ctels_reply.status =
FC_CTELS_STATUS_OK;
bsg_job->reply->result = DID_ERROR << 16;
bsg_job->reply->reply_payload_rcv_len = 0;
kfree(sp->ctx);
mempool_free(sp, ha->srb_mempool);
bsg_job->job_done(bsg_job);
return 0;
} }
return 1;
} }
/** /**
...@@ -1962,43 +1896,18 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt) ...@@ -1962,43 +1896,18 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
const char func[] = "ERROR-IOCB"; const char func[] = "ERROR-IOCB";
uint16_t que = MSW(pkt->handle); uint16_t que = MSW(pkt->handle);
struct req_que *req = ha->req_q_map[que]; struct req_que *req = ha->req_q_map[que];
int res = DID_ERROR << 16;
if (pkt->entry_status & RF_INV_E_ORDER)
ql_dbg(ql_dbg_async, vha, 0x502a, ql_dbg(ql_dbg_async, vha, 0x502a,
"Invalid Entry Order.\n"); "type of error status in response: 0x%x\n", pkt->entry_status);
else if (pkt->entry_status & RF_INV_E_COUNT)
ql_dbg(ql_dbg_async, vha, 0x502b, if (pkt->entry_status & RF_BUSY)
"Invalid Entry Count.\n"); res = DID_BUS_BUSY << 16;
else if (pkt->entry_status & RF_INV_E_PARAM)
ql_dbg(ql_dbg_async, vha, 0x502c,
"Invalid Entry Parameter.\n");
else if (pkt->entry_status & RF_INV_E_TYPE)
ql_dbg(ql_dbg_async, vha, 0x502d,
"Invalid Entry Type.\n");
else if (pkt->entry_status & RF_BUSY)
ql_dbg(ql_dbg_async, vha, 0x502e,
"Busy.\n");
else
ql_dbg(ql_dbg_async, vha, 0x502f,
"UNKNOWN flag error.\n");
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
if (sp) { if (sp)
if (qla2x00_free_sp_ctx(vha, sp)) { sp->done(ha, sp, res);
if (pkt->entry_status & else {
(RF_INV_E_ORDER | RF_INV_E_COUNT |
RF_INV_E_PARAM | RF_INV_E_TYPE)) {
sp->cmd->result = DID_ERROR << 16;
} else if (pkt->entry_status & RF_BUSY) {
sp->cmd->result = DID_BUS_BUSY << 16;
} else {
sp->cmd->result = DID_ERROR << 16;
}
qla2x00_sp_compl(ha, sp);
}
} else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7
|| pkt->entry_type == COMMAND_TYPE_6) {
ql_log(ql_log_warn, vha, 0x5030, ql_log(ql_log_warn, vha, 0x5030,
"Error entry - invalid handle.\n"); "Error entry - invalid handle.\n");
......
...@@ -874,6 +874,7 @@ qla2x00_abort_command(srb_t *sp) ...@@ -874,6 +874,7 @@ qla2x00_abort_command(srb_t *sp)
scsi_qla_host_t *vha = fcport->vha; scsi_qla_host_t *vha = fcport->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct req_que *req = vha->req; struct req_que *req = vha->req;
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
ql_dbg(ql_dbg_mbx, vha, 0x103b, "Entered %s.\n", __func__); ql_dbg(ql_dbg_mbx, vha, 0x103b, "Entered %s.\n", __func__);
...@@ -896,7 +897,7 @@ qla2x00_abort_command(srb_t *sp) ...@@ -896,7 +897,7 @@ qla2x00_abort_command(srb_t *sp)
mcp->mb[1] = fcport->loop_id << 8; mcp->mb[1] = fcport->loop_id << 8;
mcp->mb[2] = (uint16_t)handle; mcp->mb[2] = (uint16_t)handle;
mcp->mb[3] = (uint16_t)(handle >> 16); mcp->mb[3] = (uint16_t)(handle >> 16);
mcp->mb[6] = (uint16_t)sp->cmd->device->lun; mcp->mb[6] = (uint16_t)cmd->device->lun;
mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_0; mcp->in_mb = MBX_0;
mcp->tov = MBX_TOV_SECONDS; mcp->tov = MBX_TOV_SECONDS;
......
...@@ -3608,7 +3608,7 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha) ...@@ -3608,7 +3608,7 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
sp = req->outstanding_cmds[cnt]; sp = req->outstanding_cmds[cnt];
if (sp) { if (sp) {
if (!sp->ctx || if (!sp->u.scmd.ctx ||
(sp->flags & SRB_FCP_CMND_DMA_VALID)) { (sp->flags & SRB_FCP_CMND_DMA_VALID)) {
spin_unlock_irqrestore( spin_unlock_irqrestore(
&ha->hardware_lock, flags); &ha->hardware_lock, flags);
......
...@@ -304,7 +304,6 @@ static int qla2x00_mem_alloc(struct qla_hw_data *, uint16_t, uint16_t, ...@@ -304,7 +304,6 @@ static int qla2x00_mem_alloc(struct qla_hw_data *, uint16_t, uint16_t,
struct req_que **, struct rsp_que **); struct req_que **, struct rsp_que **);
static void qla2x00_free_fw_dump(struct qla_hw_data *); static void qla2x00_free_fw_dump(struct qla_hw_data *);
static void qla2x00_mem_free(struct qla_hw_data *); static void qla2x00_mem_free(struct qla_hw_data *);
static void qla2x00_sp_free_dma(srb_t *);
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
static int qla2x00_alloc_queues(struct qla_hw_data *ha) static int qla2x00_alloc_queues(struct qla_hw_data *ha)
...@@ -559,28 +558,75 @@ qla24xx_fw_version_str(struct scsi_qla_host *vha, char *str) ...@@ -559,28 +558,75 @@ qla24xx_fw_version_str(struct scsi_qla_host *vha, char *str)
return str; return str;
} }
static inline srb_t * void
qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport, qla2x00_sp_free_dma(void *vha, void *ptr)
struct scsi_cmnd *cmd)
{ {
srb_t *sp; srb_t *sp = (srb_t *)ptr;
struct qla_hw_data *ha = vha->hw; struct scsi_cmnd *cmd = GET_CMD_SP(sp);
struct qla_hw_data *ha = sp->fcport->vha->hw;
void *ctx = GET_CMD_CTX_SP(sp);
sp = mempool_alloc(ha->srb_mempool, GFP_ATOMIC); if (sp->flags & SRB_DMA_VALID) {
if (!sp) { scsi_dma_unmap(cmd);
ql_log(ql_log_warn, vha, 0x3006, sp->flags &= ~SRB_DMA_VALID;
"Memory allocation failed for sp.\n");
return sp;
} }
atomic_set(&sp->ref_count, 1); if (sp->flags & SRB_CRC_PROT_DMA_VALID) {
sp->fcport = fcport; dma_unmap_sg(&ha->pdev->dev, scsi_prot_sglist(cmd),
sp->cmd = cmd; scsi_prot_sg_count(cmd), cmd->sc_data_direction);
sp->flags = 0; sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
CMD_SP(cmd) = (void *)sp; }
sp->ctx = NULL;
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
/* List assured to be having elements */
qla2x00_clean_dsd_pool(ha, sp);
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
}
if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
dma_pool_free(ha->dl_dma_pool, ctx,
((struct crc_context *)ctx)->crc_ctx_dma);
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
}
if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx;
return sp; dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
ctx1->fcp_cmnd_dma);
list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list);
ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt;
ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
mempool_free(ctx1, ha->ctx_mempool);
ctx1 = NULL;
}
CMD_SP(cmd) = NULL;
mempool_free(sp, ha->srb_mempool);
}
static void
qla2x00_sp_compl(void *data, void *ptr, int res)
{
struct qla_hw_data *ha = (struct qla_hw_data *)data;
srb_t *sp = (srb_t *)ptr;
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
cmd->result = res;
if (atomic_read(&sp->ref_count) == 0) {
ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3015,
"SP reference-count to ZERO -- sp=%p cmd=%p.\n",
sp, GET_CMD_SP(sp));
if (ql2xextended_error_logging & ql_dbg_io)
BUG();
return;
}
if (!atomic_dec_and_test(&sp->ref_count))
return;
qla2x00_sp_free_dma(ha, sp);
cmd->scsi_done(cmd);
} }
static int static int
...@@ -644,10 +690,17 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) ...@@ -644,10 +690,17 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
goto qc24_target_busy; goto qc24_target_busy;
} }
sp = qla2x00_get_new_sp(base_vha, fcport, cmd); sp = qla2x00_get_sp(base_vha, fcport, GFP_ATOMIC);
if (!sp) if (!sp)
goto qc24_host_busy; goto qc24_host_busy;
sp->u.scmd.cmd = cmd;
sp->type = SRB_SCSI_CMD;
atomic_set(&sp->ref_count, 1);
CMD_SP(cmd) = (void *)sp;
sp->free = qla2x00_sp_free_dma;
sp->done = qla2x00_sp_compl;
rval = ha->isp_ops->start_scsi(sp); rval = ha->isp_ops->start_scsi(sp);
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_io, vha, 0x3013, ql_dbg(ql_dbg_io, vha, 0x3013,
...@@ -658,8 +711,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) ...@@ -658,8 +711,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
return 0; return 0;
qc24_host_busy_free_sp: qc24_host_busy_free_sp:
qla2x00_sp_free_dma(sp); qla2x00_sp_free_dma(ha, sp);
mempool_free(sp, ha->srb_mempool);
qc24_host_busy: qc24_host_busy:
return SCSI_MLQUEUE_HOST_BUSY; return SCSI_MLQUEUE_HOST_BUSY;
...@@ -893,7 +945,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) ...@@ -893,7 +945,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
} }
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
qla2x00_sp_compl(ha, sp); sp->done(ha, sp, 0);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
/* Did the command return during mailbox execution? */ /* Did the command return during mailbox execution? */
...@@ -925,6 +977,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, ...@@ -925,6 +977,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct req_que *req; struct req_que *req;
srb_t *sp; srb_t *sp;
struct scsi_cmnd *cmd;
status = QLA_SUCCESS; status = QLA_SUCCESS;
...@@ -935,28 +988,29 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, ...@@ -935,28 +988,29 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
sp = req->outstanding_cmds[cnt]; sp = req->outstanding_cmds[cnt];
if (!sp) if (!sp)
continue; continue;
if ((sp->ctx) && !IS_PROT_IO(sp)) if (sp->type != SRB_SCSI_CMD)
continue; continue;
if (vha->vp_idx != sp->fcport->vha->vp_idx) if (vha->vp_idx != sp->fcport->vha->vp_idx)
continue; continue;
match = 0; match = 0;
cmd = GET_CMD_SP(sp);
switch (type) { switch (type) {
case WAIT_HOST: case WAIT_HOST:
match = 1; match = 1;
break; break;
case WAIT_TARGET: case WAIT_TARGET:
match = sp->cmd->device->id == t; match = cmd->device->id == t;
break; break;
case WAIT_LUN: case WAIT_LUN:
match = (sp->cmd->device->id == t && match = (cmd->device->id == t &&
sp->cmd->device->lun == l); cmd->device->lun == l);
break; break;
} }
if (!match) if (!match)
continue; continue;
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
status = qla2x00_eh_wait_on_command(sp->cmd); status = qla2x00_eh_wait_on_command(cmd);
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
} }
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
...@@ -1249,7 +1303,6 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) ...@@ -1249,7 +1303,6 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
int que, cnt; int que, cnt;
unsigned long flags; unsigned long flags;
srb_t *sp; srb_t *sp;
struct srb_ctx *ctx;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct req_que *req; struct req_que *req;
...@@ -1262,31 +1315,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) ...@@ -1262,31 +1315,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
sp = req->outstanding_cmds[cnt]; sp = req->outstanding_cmds[cnt];
if (sp) { if (sp) {
req->outstanding_cmds[cnt] = NULL; req->outstanding_cmds[cnt] = NULL;
if (!sp->ctx || sp->done(vha, sp, res);
(sp->flags & SRB_FCP_CMND_DMA_VALID) ||
IS_PROT_IO(sp)) {
sp->cmd->result = res;
qla2x00_sp_compl(ha, sp);
} else {
ctx = sp->ctx;
if (ctx->type == SRB_ELS_CMD_RPT ||
ctx->type == SRB_ELS_CMD_HST ||
ctx->type == SRB_CT_CMD) {
struct fc_bsg_job *bsg_job =
ctx->u.bsg_job;
if (bsg_job->request->msgcode
== FC_BSG_HST_CT)
kfree(sp->fcport);
bsg_job->req->errors = 0;
bsg_job->reply->result = res;
bsg_job->job_done(bsg_job);
kfree(sp->ctx);
mempool_free(sp,
ha->srb_mempool);
} else {
ctx->u.iocb_cmd->free(sp);
}
}
} }
} }
} }
...@@ -3820,75 +3849,6 @@ qla2x00_rst_aen(scsi_qla_host_t *vha) ...@@ -3820,75 +3849,6 @@ qla2x00_rst_aen(scsi_qla_host_t *vha)
} }
} }
static void
qla2x00_sp_free_dma(srb_t *sp)
{
struct scsi_cmnd *cmd = sp->cmd;
struct qla_hw_data *ha = sp->fcport->vha->hw;
if (sp->flags & SRB_DMA_VALID) {
scsi_dma_unmap(cmd);
sp->flags &= ~SRB_DMA_VALID;
}
if (sp->flags & SRB_CRC_PROT_DMA_VALID) {
dma_unmap_sg(&ha->pdev->dev, scsi_prot_sglist(cmd),
scsi_prot_sg_count(cmd), cmd->sc_data_direction);
sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
}
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
/* List assured to be having elements */
qla2x00_clean_dsd_pool(ha, sp);
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
}
if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
dma_pool_free(ha->dl_dma_pool, sp->ctx,
((struct crc_context *)sp->ctx)->crc_ctx_dma);
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
}
if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
struct ct6_dsd *ctx = sp->ctx;
dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd,
ctx->fcp_cmnd_dma);
list_splice(&ctx->dsd_list, &ha->gbl_dsd_list);
ha->gbl_dsd_inuse -= ctx->dsd_use_cnt;
ha->gbl_dsd_avail += ctx->dsd_use_cnt;
mempool_free(sp->ctx, ha->ctx_mempool);
sp->ctx = NULL;
}
CMD_SP(cmd) = NULL;
}
static void
qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
{
struct scsi_cmnd *cmd = sp->cmd;
qla2x00_sp_free_dma(sp);
mempool_free(sp, ha->srb_mempool);
cmd->scsi_done(cmd);
}
void
qla2x00_sp_compl(struct qla_hw_data *ha, srb_t *sp)
{
if (atomic_read(&sp->ref_count) == 0) {
ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3015,
"SP reference-count to ZERO -- sp=%p cmd=%p.\n",
sp, sp->cmd);
if (ql2xextended_error_logging & ql_dbg_io)
BUG();
return;
}
if (!atomic_dec_and_test(&sp->ref_count))
return;
qla2x00_sp_final_compl(ha, sp);
}
/************************************************************************** /**************************************************************************
* qla2x00_timer * qla2x00_timer
* *
...@@ -3959,7 +3919,7 @@ qla2x00_timer(scsi_qla_host_t *vha) ...@@ -3959,7 +3919,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
sp = req->outstanding_cmds[index]; sp = req->outstanding_cmds[index];
if (!sp) if (!sp)
continue; continue;
if (sp->ctx && !IS_PROT_IO(sp)) if (sp->type != SRB_SCSI_CMD)
continue; continue;
sfcp = sp->fcport; sfcp = sp->fcport;
if (!(sfcp->flags & FCF_FCP2_DEVICE)) if (!(sfcp->flags & FCF_FCP2_DEVICE))
......
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