aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorGiridhar Malavali <giridhar.malavali@qlogic.com>2012-02-09 11:15:36 -0800
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 08:14:08 -0600
commit9ba56b95a588906a65664a9299a9f8ac1a0f6a91 (patch)
tree93786c52320c2a7276c99cc4d9b3672ca6e0a50d /drivers/scsi/qla2xxx
parent69e5f1ea61a3e84c03103c6a18ee9cacef4cbb9e (diff)
[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: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c86
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c5
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h44
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h9
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c256
-rw-r--r--drivers/scsi/qla2xxx/qla_inline.h45
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c158
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c299
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c206
11 files changed, 485 insertions, 628 deletions
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 6887538d173..b2b664483ab 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -11,29 +11,36 @@
#include <linux/delay.h>
/* BSG support for ELS/CT pass through */
-inline srb_t *
-qla2x00_get_ctx_bsg_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size)
+void
+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 srb_ctx *ctx;
- 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;
- }
+ dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
+ bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
- memset(sp, 0, sizeof(*sp));
- sp->fcport = fcport;
- sp->ctx = ctx;
- ctx->iocbs = 1;
-done:
- return sp;
+ dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
+ bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+ if (sp->type == SRB_CT_CMD ||
+ sp->type == SRB_ELS_CMD_HST)
+ kfree(sp->fcport);
+ mempool_free(sp, vha->hw->srb_mempool);
}
int
@@ -217,6 +224,7 @@ exit_fcp_prio_cfg:
bsg_job->job_done(bsg_job);
return ret;
}
+
static int
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 rval = (DRIVER_ERROR << 16);
uint16_t nextlid = 0;
- struct srb_ctx *els;
if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
rport = bsg_job->rport;
@@ -337,20 +344,21 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
}
/* 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) {
rval = -ENOMEM;
goto done_unmap_sg;
}
- els = sp->ctx;
- els->type =
+ sp->type =
(bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
- els->name =
+ sp->name =
(bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
"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,
"bsg rqst type: %s els type: %x - loop-id=%x "
@@ -362,7 +370,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
if (rval != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0x700e,
"qla2x00_start_sp failed = %d\n", rval);
- kfree(sp->ctx);
mempool_free(sp, ha->srb_mempool);
rval = -EIO;
goto done_unmap_sg;
@@ -409,7 +416,6 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
uint16_t loop_id;
struct fc_port *fcport;
char *type = "FC_BSG_HST_CT";
- struct srb_ctx *ct;
req_sg_cnt =
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)
fcport->loop_id = loop_id;
/* 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) {
ql_log(ql_log_warn, vha, 0x7015,
- "qla2x00_get_ctx_bsg_sp failed.\n");
+ "qla2x00_get_sp failed.\n");
rval = -ENOMEM;
goto done_free_fcport;
}
- ct = sp->ctx;
- ct->type = SRB_CT_CMD;
- ct->name = "bsg_ct";
- ct->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
- ct->u.bsg_job = bsg_job;
+ sp->type = SRB_CT_CMD;
+ sp->name = "bsg_ct";
+ sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
+ sp->u.bsg_job = bsg_job;
+ sp->free = qla2x00_bsg_sp_free;
+ sp->done = qla2x00_bsg_job_done;
ql_dbg(ql_dbg_user, vha, 0x7016,
"bsg rqst type: %s else type: %x - "
@@ -511,7 +518,6 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
if (rval != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0x7017,
"qla2x00_start_sp failed=%d.\n", rval);
- kfree(sp->ctx);
mempool_free(sp, ha->srb_mempool);
rval = -EIO;
goto done_free_fcport;
@@ -1669,7 +1675,6 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
int cnt, que;
unsigned long flags;
struct req_que *req;
- struct srb_ctx *sp_bsg;
/* find the bsg job from the active list of commands */
spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -1681,11 +1686,9 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
sp = req->outstanding_cmds[cnt];
if (sp) {
- sp_bsg = sp->ctx;
-
- if (((sp_bsg->type == SRB_CT_CMD) ||
- (sp_bsg->type == SRB_ELS_CMD_HST))
- && (sp_bsg->u.bsg_job == bsg_job)) {
+ if (((sp->type == SRB_CT_CMD) ||
+ (sp->type == SRB_ELS_CMD_HST))
+ && (sp->u.bsg_job == bsg_job)) {
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (ha->isp_ops->abort_command(sp)) {
ql_log(ql_log_warn, vha, 0x7089,
@@ -1715,7 +1718,6 @@ done:
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (bsg_job->request->msgcode == FC_BSG_HST_CT)
kfree(sp->fcport);
- kfree(sp->ctx);
mempool_free(sp, ha->srb_mempool);
return 0;
}
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index e4c6b940993..cd278a09bea 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -14,10 +14,11 @@
* | Module Init and Probe | 0x011f | 0x4b,0xfa |
* | Mailbox commands | 0x1139 | 0x112c-0x112e |
* | Device Discovery | 0x2084 | |
- * | Queue Command and IO tracing | 0x302f | 0x3008 |
+ * | Queue Command and IO tracing | 0x302f | 0x3006,0x3008 |
* | | | 0x302d-0x302e |
* | DPC Thread | 0x401c | |
- * | Async Events | 0x5057 | 0x5052 |
+ * | Async Events | 0x5057 | 0x502b-0x502f |
+ * | | | 0x5047,0x5052 |
* | Timer Routines | 0x6011 | 0x600e-0x600f |
* | User Space Interactions | 0x709e | 0x7018,0x702e |
* | | | 0x7039,0x7045 |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 7b7d829bef8..6704ef84c45 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -202,20 +202,12 @@ struct sd_dif_tuple {
/*
* SCSI Request Block
*/
-typedef struct srb {
- atomic_t ref_count;
- struct fc_port *fcport;
- uint32_t handle;
-
+struct srb_cmd {
struct scsi_cmnd *cmd; /* Linux SCSI command pkt */
-
- uint16_t flags;
-
uint32_t request_sense_length;
uint8_t *request_sense_ptr;
-
void *ctx;
-} srb_t;
+};
/*
* SRB flag definitions
@@ -254,10 +246,7 @@ struct srb_iocb {
} u;
struct timer_list timer;
-
- void (*done)(srb_t *);
- void (*free)(srb_t *);
- void (*timeout)(srb_t *);
+ void (*timeout)(void *);
};
/* Values for srb_ctx type */
@@ -268,16 +257,37 @@ struct srb_iocb {
#define SRB_CT_CMD 5
#define SRB_ADISC_CMD 6
#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;
char *name;
int iocbs;
union {
- struct srb_iocb *iocb_cmd;
+ struct srb_iocb iocb_cmd;
struct fc_bsg_job *bsg_job;
+ struct srb_cmd scmd;
} 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 {
dma_addr_t send_dma;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 362d49cbcb7..87fee23fd16 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -71,8 +71,6 @@ extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_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 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 *);
extern int qla24xx_vport_create_req_sanity_check(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 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 *);
/* IOCB related functions */
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 */
extern irqreturn_t qla82xx_intr_handler(int, void *);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index e5b417aa9fc..4837b5872cd 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -41,11 +41,10 @@ static int qla25xx_init_queues(struct qla_hw_data *);
/* SRB Extensions ---------------------------------------------------------- */
-static void
-qla2x00_ctx_sp_timeout(unsigned long __data)
+void
+qla2x00_sp_timeout(unsigned long __data)
{
srb_t *sp = (srb_t *)__data;
- struct srb_ctx *ctx;
struct srb_iocb *iocb;
fc_port_t *fcport = sp->fcport;
struct qla_hw_data *ha = fcport->vha->hw;
@@ -55,79 +54,25 @@ qla2x00_ctx_sp_timeout(unsigned long __data)
spin_lock_irqsave(&ha->hardware_lock, flags);
req = ha->req_q_map[0];
req->outstanding_cmds[sp->handle] = NULL;
- ctx = sp->ctx;
- iocb = ctx->u.iocb_cmd;
+ iocb = &sp->u.iocb_cmd;
iocb->timeout(sp);
- iocb->free(sp);
+ sp->free(fcport->vha, sp);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
-static void
-qla2x00_ctx_sp_free(srb_t *sp)
+void
+qla2x00_sp_free(void *data, void *ptr)
{
- struct srb_ctx *ctx = sp->ctx;
- struct srb_iocb *iocb = ctx->u.iocb_cmd;
- struct scsi_qla_host *vha = sp->fcport->vha;
+ srb_t *sp = (srb_t *)ptr;
+ struct srb_iocb *iocb = &sp->u.iocb_cmd;
+ struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
del_timer(&iocb->timer);
- kfree(iocb);
- kfree(ctx);
- mempool_free(sp, sp->fcport->vha->hw->srb_mempool);
+ mempool_free(sp, 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);
- return sp;
-}
-
/* Asynchronous Login/Logout Routines -------------------------------------- */
static inline unsigned long
@@ -149,19 +94,19 @@ qla2x00_get_async_timeout(struct scsi_qla_host *vha)
}
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;
- struct srb_ctx *ctx = sp->ctx;
ql_dbg(ql_dbg_disc, fcport->vha, 0x2071,
"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->flags &= ~FCF_ASYNC_SENT;
- if (ctx->type == SRB_LOGIN_CMD) {
- struct srb_iocb *lio = ctx->u.iocb_cmd;
+ if (sp->type == SRB_LOGIN_CMD) {
+ struct srb_iocb *lio = &sp->u.iocb_cmd;
qla2x00_post_async_logout_work(fcport->vha, fcport, NULL);
/* Retry as needed. */
lio->u.logio.data[0] = MBS_COMMAND_ERROR;
@@ -173,14 +118,16 @@ qla2x00_async_iocb_timeout(srb_t *sp)
}
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;
- struct srb_iocb *lio = ctx->u.iocb_cmd;
-
- qla2x00_post_async_login_done_work(sp->fcport->vha, sp->fcport,
- lio->u.logio.data);
- lio->free(sp);
+ srb_t *sp = (srb_t *)ptr;
+ 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,
+ lio->u.logio.data);
+ sp->free(sp->fcport->vha, sp);
}
int
@@ -188,22 +135,21 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
uint16_t *data)
{
srb_t *sp;
- struct srb_ctx *ctx;
struct srb_iocb *lio;
int rval;
rval = QLA_FUNCTION_FAILED;
- sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx),
- qla2x00_get_async_timeout(vha) + 2);
+ sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
goto done;
- ctx = sp->ctx;
- ctx->type = SRB_LOGIN_CMD;
- ctx->name = "login";
- lio = ctx->u.iocb_cmd;
+ sp->type = SRB_LOGIN_CMD;
+ sp->name = "login";
+ qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
+ lio = &sp->u.iocb_cmd;
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;
if (data[1] & QLA_LOGIO_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,
return rval;
done_free_sp:
- lio->free(sp);
+ sp->free(fcport->vha, sp);
done:
return rval;
}
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;
- struct srb_iocb *lio = ctx->u.iocb_cmd;
-
- qla2x00_post_async_logout_done_work(sp->fcport->vha, sp->fcport,
- lio->u.logio.data);
- lio->free(sp);
+ srb_t *sp = (srb_t *)ptr;
+ 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,
+ lio->u.logio.data);
+ sp->free(sp->fcport->vha, sp);
}
int
qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
{
srb_t *sp;
- struct srb_ctx *ctx;
struct srb_iocb *lio;
int rval;
rval = QLA_FUNCTION_FAILED;
- sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx),
- qla2x00_get_async_timeout(vha) + 2);
+ sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
goto done;
- ctx = sp->ctx;
- ctx->type = SRB_LOGOUT_CMD;
- ctx->name = "logout";
- lio = ctx->u.iocb_cmd;
+ sp->type = SRB_LOGOUT_CMD;
+ sp->name = "logout";
+ qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
+ lio = &sp->u.iocb_cmd;
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);
if (rval != QLA_SUCCESS)
goto done_free_sp;
@@ -266,20 +213,22 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
return rval;
done_free_sp:
- lio->free(sp);
+ sp->free(fcport->vha, sp);
done:
return rval;
}
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;
- struct srb_iocb *lio = ctx->u.iocb_cmd;
-
- qla2x00_post_async_adisc_done_work(sp->fcport->vha, sp->fcport,
- lio->u.logio.data);
- lio->free(sp);
+ srb_t *sp = (srb_t *)ptr;
+ 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,
+ lio->u.logio.data);
+ sp->free(sp->fcport->vha, sp);
}
int
@@ -287,22 +236,21 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
uint16_t *data)
{
srb_t *sp;
- struct srb_ctx *ctx;
struct srb_iocb *lio;
int rval;
rval = QLA_FUNCTION_FAILED;
- sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx),
- qla2x00_get_async_timeout(vha) + 2);
+ sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
goto done;
- ctx = sp->ctx;
- ctx->type = SRB_ADISC_CMD;
- ctx->name = "adisc";
- lio = ctx->u.iocb_cmd;
+ sp->type = SRB_ADISC_CMD;
+ sp->name = "adisc";
+ qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
+ lio = &sp->u.iocb_cmd;
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)
lio->u.logio.flags |= SRB_LOGIN_RETRIED;
rval = qla2x00_start_sp(sp);
@@ -316,46 +264,62 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
return rval;
done_free_sp:
- lio->free(sp);
+ sp->free(fcport->vha, sp);
done:
return rval;
}
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;
- struct srb_iocb *iocb = (struct srb_iocb *)ctx->u.iocb_cmd;
+ srb_t *sp = (srb_t *)ptr;
+ 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;
- qla2x00_async_tm_cmd_done(sp->fcport->vha, sp->fcport, iocb);
- iocb->free(sp);
+ 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);
+
+ if ((rval != QLA_SUCCESS) || iocb->u.tmf.data) {
+ ql_dbg(ql_dbg_taskm, vha, 0x8030,
+ "TM IOCB failed (%x).\n", rval);
+ }
+ }
+ sp->free(sp->fcport->vha, sp);
}
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)
{
struct scsi_qla_host *vha = fcport->vha;
srb_t *sp;
- struct srb_ctx *ctx;
struct srb_iocb *tcf;
int rval;
rval = QLA_FUNCTION_FAILED;
- sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx),
- qla2x00_get_async_timeout(vha) + 2);
+ sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
goto done;
- ctx = sp->ctx;
- ctx->type = SRB_TM_CMD;
- ctx->name = "tmf";
- tcf = ctx->u.iocb_cmd;
- tcf->u.tmf.flags = flags;
+ sp->type = SRB_TM_CMD;
+ sp->name = "tmf";
+ qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
+ tcf = &sp->u.iocb_cmd;
+ tcf->u.tmf.flags = tm_flags;
tcf->u.tmf.lun = lun;
tcf->u.tmf.data = tag;
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);
if (rval != QLA_SUCCESS)
@@ -368,7 +332,7 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
return rval;
done_free_sp:
- tcf->free(sp);
+ sp->free(fcport->vha, sp);
done:
return rval;
}
@@ -452,30 +416,6 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport,
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. */
/****************************************************************************/
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index 7cc4f36cd53..3ea0cedc6e7 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -72,16 +72,19 @@ static inline void
qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp)
{
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 */
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,
dsd_ptr->dsd_list_dma);
list_del(&dsd_ptr->list);
kfree(dsd_ptr);
}
- INIT_LIST_HEAD(&((struct crc_context *)sp->ctx)->dsd_list);
+ INIT_LIST_HEAD(&ctx->dsd_list);
}
static inline void
@@ -113,8 +116,7 @@ qla2x00_hba_err_chk_enabled(srb_t *sp)
return 0;
*
*/
-
- switch (scsi_get_prot_op(sp->cmd)) {
+ switch (scsi_get_prot_op(GET_CMD_SP(sp))) {
case SCSI_PROT_READ_STRIP:
case SCSI_PROT_WRITE_INSERT:
if (ql2xenablehba_err_chk >= 1)
@@ -144,3 +146,38 @@ qla2x00_reset_active(scsi_qla_host_t *vha)
test_bit(ISP_ABORT_NEEDED, &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;
+}
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index a281b5422df..8ce810373b5 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -22,18 +22,19 @@ static inline uint16_t
qla2x00_get_cmd_direction(srb_t *sp)
{
uint16_t cflags;
+ struct scsi_cmnd *cmd = GET_CMD_SP(sp);
cflags = 0;
/* Set transfer direction */
- if (sp->cmd->sc_data_direction == DMA_TO_DEVICE) {
+ if (cmd->sc_data_direction == DMA_TO_DEVICE) {
cflags = CF_WRITE;
sp->fcport->vha->hw->qla_stats.output_bytes +=
- scsi_bufflen(sp->cmd);
- } else if (sp->cmd->sc_data_direction == DMA_FROM_DEVICE) {
+ scsi_bufflen(cmd);
+ } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
cflags = CF_READ;
sp->fcport->vha->hw->qla_stats.input_bytes +=
- scsi_bufflen(sp->cmd);
+ scsi_bufflen(cmd);
}
return (cflags);
}
@@ -143,12 +144,13 @@ qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, struct req_que *req)
static inline int
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 */
if (guard != SHOST_DIX_GUARD_CRC) {
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;
}
@@ -156,7 +158,7 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
*fw_prot_opts = 0;
/* 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:
*fw_prot_opts |= PO_MODE_DIF_REMOVE;
break;
@@ -180,7 +182,7 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
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,
struct scatterlist *sg;
int i;
- cmd = sp->cmd;
+ cmd = GET_CMD_SP(sp);
/* Update entry type to indicate Command Type 2 IOCB */
*((uint32_t *)(&cmd_pkt->entry_type)) =
@@ -259,7 +261,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
struct scatterlist *sg;
int i;
- cmd = sp->cmd;
+ cmd = GET_CMD_SP(sp);
/* Update entry type to indicate Command Type 3 IOCB */
*((uint32_t *)(&cmd_pkt->entry_type)) =
@@ -333,7 +335,7 @@ qla2x00_start_scsi(srb_t *sp)
vha = sp->fcport->vha;
ha = vha->hw;
reg = &ha->iobase->isp;
- cmd = sp->cmd;
+ cmd = GET_CMD_SP(sp);
req = ha->req_q_map[0];
rsp = ha->rsp_q_map[0];
/* So we know we haven't pci_map'ed anything yet */
@@ -391,7 +393,7 @@ qla2x00_start_scsi(srb_t *sp)
req->current_outstanding_cmd = handle;
req->outstanding_cmds[handle] = sp;
sp->handle = handle;
- sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
+ cmd->host_scribble = (unsigned char *)(unsigned long)handle;
req->cnt -= req_cnt;
cmd_pkt = (cmd_entry_t *)req->ring_ptr;
@@ -403,7 +405,7 @@ qla2x00_start_scsi(srb_t *sp)
/* Set target ID and LUN number*/
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 */
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,
struct dsd_dma *dsd_ptr;
struct ct6_dsd *ctx;
- cmd = sp->cmd;
+ cmd = GET_CMD_SP(sp);
/* Update entry type to indicate Command Type 3 IOCB */
*((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,
}
cur_seg = scsi_sglist(cmd);
- ctx = sp->ctx;
+ ctx = GET_CMD_CTX_SP(sp);
while (tot_dsds) {
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,
int i;
struct req_que *req;
- cmd = sp->cmd;
+ cmd = GET_CMD_SP(sp);
/* Update entry type to indicate Command Type 3 IOCB */
*((uint32_t *)(&cmd_pkt->entry_type)) =
@@ -744,12 +746,12 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
cmd_pkt->task_mgmt_flags =
__constant_cpu_to_le16(TMF_WRITE_DATA);
sp->fcport->vha->hw->qla_stats.output_bytes +=
- scsi_bufflen(sp->cmd);
+ scsi_bufflen(cmd);
} else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
cmd_pkt->task_mgmt_flags =
__constant_cpu_to_le16(TMF_READ_DATA);
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 */
@@ -796,7 +798,7 @@ static inline void
qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt,
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);
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,
struct qla2_sgx sgx;
dma_addr_t sle_dma;
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;
memset(&sgx, 0, sizeof(struct qla2_sgx));
- sgx.tot_bytes = scsi_bufflen(sp->cmd);
- sgx.cur_sg = scsi_sglist(sp->cmd);
+ sgx.tot_bytes = scsi_bufflen(cmd);
+ sgx.cur_sg = scsi_sglist(cmd);
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)) {
@@ -994,7