Skip to content

Commit

Permalink
[SCSI] qla2xxx: changes in multiq code
Browse files Browse the repository at this point in the history
Following changes have been made:
 1. Scan outstanding commands only in the queue where it is submitted
 2. Update queue registers directly in the fast path
 3. Queue specific BAR is remapped only for multiq capable adapters

Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
  • Loading branch information
Anirban Chakraborty authored and James Bottomley committed Dec 29, 2008
1 parent 20c09df commit 17d9863
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 115 deletions.
7 changes: 6 additions & 1 deletion drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,14 @@
#define RESPONSE_ENTRY_CNT_2100 64 /* Number of response entries.*/
#define RESPONSE_ENTRY_CNT_2300 512 /* Number of response entries.*/

struct req_que;

/*
* SCSI Request Block
*/
typedef struct srb {
struct scsi_qla_host *vha; /* HA the SP is queued on */
struct req_que *que;
struct fc_port *fcport;

struct scsi_cmnd *cmd; /* Linux SCSI command pkt */
Expand Down Expand Up @@ -2045,7 +2048,6 @@ typedef struct vport_params {
#define VP_RET_CODE_NOT_FOUND 6

struct qla_hw_data;
struct req_que;

/*
* ISP operations
Expand Down Expand Up @@ -2101,6 +2103,9 @@ struct isp_operations {

int (*get_flash_version) (struct scsi_qla_host *, void *);
int (*start_scsi) (srb_t *);
void (*wrt_req_reg) (struct qla_hw_data *, uint16_t, uint16_t);
void (*wrt_rsp_reg) (struct qla_hw_data *, uint16_t, uint16_t);
uint16_t (*rd_req_reg) (struct qla_hw_data *, uint16_t);
};

/* MSI-X Support *************************************************************/
Expand Down
6 changes: 6 additions & 0 deletions drivers/scsi/qla2xxx/qla_gbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,4 +391,10 @@ extern int qla25xx_delete_req_que(struct scsi_qla_host *, struct req_que *);
extern int qla25xx_delete_rsp_que(struct scsi_qla_host *, struct rsp_que *);
extern int qla25xx_create_queues(struct scsi_qla_host *, uint8_t);
extern int qla25xx_delete_queues(struct scsi_qla_host *, uint8_t);
extern uint16_t qla24xx_rd_req_reg(struct qla_hw_data *, uint16_t);
extern uint16_t qla25xx_rd_req_reg(struct qla_hw_data *, uint16_t);
extern void qla24xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t);
extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t);
extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);
extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);
#endif /* _QLA_GBL_H */
4 changes: 2 additions & 2 deletions drivers/scsi/qla2xxx/qla_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
if (!tc) {
qla_printk(KERN_WARNING, ha, "Unable to allocate "
"(%d KB) for FCE.\n", FCE_SIZE / 1024);
goto cont_alloc;
goto try_eft;
}

memset(tc, 0, FCE_SIZE);
Expand All @@ -808,7 +808,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc,
tc_dma);
ha->flags.fce_enabled = 0;
goto cont_alloc;
goto try_eft;
}

qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n",
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/qla2xxx/qla_inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,4 @@ qla2x00_is_reserved_id(scsi_qla_host_t *vha, uint16_t loop_id)

return ((loop_id > ha->max_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST);
};
}
68 changes: 43 additions & 25 deletions drivers/scsi/qla2xxx/qla_iocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
struct scatterlist *sg;
int i;
struct req_que *req;
uint16_t que_id;

cmd = sp->cmd;

Expand All @@ -175,8 +174,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
}

vha = sp->vha;
que_id = vha->req_ques[0];
req = vha->hw->req_q_map[que_id];
req = sp->que;

cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));

Expand Down Expand Up @@ -223,7 +221,6 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
struct scatterlist *sg;
int i;
struct req_que *req;
uint16_t que_id;

cmd = sp->cmd;

Expand All @@ -238,8 +235,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
}

vha = sp->vha;
que_id = vha->req_ques[0];
req = vha->hw->req_q_map[que_id];
req = sp->que;

cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));

Expand Down Expand Up @@ -358,6 +354,7 @@ qla2x00_start_scsi(srb_t *sp)
req->current_outstanding_cmd = handle;
req->outstanding_cmds[handle] = sp;
sp->vha = vha;
sp->que = req;
sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
req->cnt -= req_cnt;

Expand Down Expand Up @@ -573,6 +570,7 @@ qla2x00_isp_cmd(struct scsi_qla_host *vha, struct req_que *req)
{
struct qla_hw_data *ha = vha->hw;
device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id);
struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp;

DEBUG5(printk("%s(): IOCB data:\n", __func__));
DEBUG5(qla2x00_dump_buffer(
Expand All @@ -587,8 +585,10 @@ qla2x00_isp_cmd(struct scsi_qla_host *vha, struct req_que *req)
req->ring_ptr++;

/* Set chip new ring index. */
if (ha->mqenable)
RD_REG_DWORD(&reg->isp25mq.req_q_out);
if (ha->mqenable) {
WRT_REG_DWORD(&reg->isp25mq.req_q_in, req->ring_index);
RD_REG_DWORD(&ioreg->hccr);
}
else {
if (IS_FWI2_CAPABLE(ha)) {
WRT_REG_DWORD(&reg->isp24.req_q_in, req->ring_index);
Expand Down Expand Up @@ -642,7 +642,6 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
struct scsi_cmnd *cmd;
struct scatterlist *sg;
int i;
uint16_t que_id;
struct req_que *req;

cmd = sp->cmd;
Expand All @@ -658,8 +657,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
}

vha = sp->vha;
que_id = vha->req_ques[0];
req = vha->hw->req_q_map[que_id];
req = sp->que;

/* Set transfer direction */
if (cmd->sc_data_direction == DMA_TO_DEVICE) {
Expand Down Expand Up @@ -727,15 +725,14 @@ qla24xx_start_scsi(srb_t *sp)
struct scsi_cmnd *cmd = sp->cmd;
struct scsi_qla_host *vha = sp->vha;
struct qla_hw_data *ha = vha->hw;
device_reg_t __iomem *reg;
uint16_t que_id;

/* Setup device pointers. */
ret = 0;
que_id = vha->req_ques[0];

req = ha->req_q_map[que_id];
reg = ISP_QUE_REG(ha, req->id);
sp->que = req;

if (req->rsp)
rsp = req->rsp;
Expand Down Expand Up @@ -780,12 +777,7 @@ qla24xx_start_scsi(srb_t *sp)

req_cnt = qla24xx_calc_iocbs(tot_dsds);
if (req->cnt < (req_cnt + 2)) {
if (ha->mqenable)
cnt = (uint16_t)
RD_REG_DWORD_RELAXED(&reg->isp25mq.req_q_out);
else
cnt = (uint16_t)
RD_REG_DWORD_RELAXED(&reg->isp24.req_q_out);
cnt = ha->isp_ops->rd_req_reg(ha, req->id);

if (req->ring_index < cnt)
req->cnt = cnt - req->ring_index;
Expand Down Expand Up @@ -846,12 +838,7 @@ qla24xx_start_scsi(srb_t *sp)
sp->flags |= SRB_DMA_VALID;

/* Set chip new ring index. */
if (ha->mqenable)
WRT_REG_DWORD(&reg->isp25mq.req_q_in, req->ring_index);
else {
WRT_REG_DWORD(&reg->isp24.req_q_in, req->ring_index);
RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
}
ha->isp_ops->wrt_req_reg(ha, req->id, req->ring_index);

/* Manage unprocessed RIO/ZIO commands in response queue. */
if (vha->flags.process_response_queue &&
Expand All @@ -870,3 +857,34 @@ qla24xx_start_scsi(srb_t *sp)
return QLA_FUNCTION_FAILED;
}

uint16_t
qla24xx_rd_req_reg(struct qla_hw_data *ha, uint16_t id)
{
device_reg_t __iomem *reg = (void *) ha->iobase;
return RD_REG_DWORD_RELAXED(&reg->isp24.req_q_out);
}

uint16_t
qla25xx_rd_req_reg(struct qla_hw_data *ha, uint16_t id)
{
device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id;
return RD_REG_DWORD_RELAXED(&reg->isp25mq.req_q_out);
}

void
qla24xx_wrt_req_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
{
device_reg_t __iomem *reg = (void *) ha->iobase;
WRT_REG_DWORD(&reg->isp24.req_q_in, index);
RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
}

void
qla25xx_wrt_req_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
{
device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id;
struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp;
WRT_REG_DWORD(&reg->isp25mq.req_q_in, index);
RD_REG_DWORD(&ioreg->hccr); /* PCI posting */
}

22 changes: 16 additions & 6 deletions drivers/scsi/qla2xxx/qla_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1446,7 +1446,6 @@ void
qla24xx_process_response_queue(struct rsp_que *rsp)
{
struct qla_hw_data *ha = rsp->hw;
device_reg_t __iomem *reg = ISP_QUE_REG(ha, rsp->id);
struct sts_entry_24xx *pkt;
struct scsi_qla_host *vha;

Expand Down Expand Up @@ -1500,10 +1499,7 @@ qla24xx_process_response_queue(struct rsp_que *rsp)
}

/* Adjust ring index */
if (ha->mqenable)
WRT_REG_DWORD(&reg->isp25mq.rsp_q_out, rsp->ring_index);
else
WRT_REG_DWORD(&reg->isp24.rsp_q_out, rsp->ring_index);
ha->isp_ops->wrt_rsp_reg(ha, rsp->id, rsp->ring_index);
}

static void
Expand Down Expand Up @@ -1702,7 +1698,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
if (!rsp->id)
msix_disabled_hccr &= __constant_cpu_to_le32(BIT_22);
else
msix_disabled_hccr &= BIT_6;
msix_disabled_hccr &= __constant_cpu_to_le32(BIT_6);

qla24xx_process_response_queue(rsp);

Expand Down Expand Up @@ -2077,3 +2073,17 @@ int qla25xx_request_irq(struct rsp_que *rsp)
return ret;
}

void
qla25xx_wrt_rsp_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
{
device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id;
WRT_REG_DWORD(&reg->isp25mq.rsp_q_out, index);
}

void
qla24xx_wrt_rsp_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
{
device_reg_t __iomem *reg = (void *) ha->iobase;
WRT_REG_DWORD(&reg->isp24.rsp_q_out, index);
}

4 changes: 2 additions & 2 deletions drivers/scsi/qla2xxx/qla_mbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -3129,7 +3129,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req,
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);

rval = (int)qla2x00_mailbox_command(vha, mcp);
rval = qla2x00_mailbox_command(vha, mcp);
if (rval != QLA_SUCCESS)
DEBUG2_3_11(printk(KERN_WARNING "%s(%ld): failed=%x mb0=%x.\n",
__func__, vha->host_no, rval, mcp->mb[0]));
Expand Down Expand Up @@ -3180,7 +3180,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp,

spin_unlock_irqrestore(&ha->hardware_lock, flags);

rval = (int)qla2x00_mailbox_command(vha, mcp);
rval = qla2x00_mailbox_command(vha, mcp);
if (rval != QLA_SUCCESS)
DEBUG2_3_11(printk(KERN_WARNING "%s(%ld): failed=%x "
"mb0=%x.\n", __func__,
Expand Down
Loading

0 comments on commit 17d9863

Please sign in to comment.