Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17d98630 authored by Anirban Chakraborty's avatar Anirban Chakraborty Committed by James Bottomley
Browse files

[SCSI] qla2xxx: changes in multiq code



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: default avatarAnirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 20c09df7
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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 */
@@ -2045,7 +2048,6 @@ typedef struct vport_params {
#define VP_RET_CODE_NOT_FOUND		6

struct qla_hw_data;
struct req_que;

/*
 * ISP operations
@@ -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 *************************************************************/
+6 −0
Original line number Diff line number Diff line
@@ -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 */
+2 −2
Original line number Diff line number Diff line
@@ -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);
@@ -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",
+1 −1
Original line number Diff line number Diff line
@@ -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);
};
}
+43 −25
Original line number Diff line number Diff line
@@ -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;

@@ -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));

@@ -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;

@@ -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));

@@ -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;

@@ -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(
@@ -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);
@@ -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;
@@ -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) {
@@ -727,7 +725,6 @@ 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. */
@@ -735,7 +732,7 @@ qla24xx_start_scsi(srb_t *sp)
	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;
@@ -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;
@@ -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 &&
@@ -870,3 +857,34 @@ queuing_error:
	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 */
}
Loading