Skip to content

Commit

Permalink
[SCSI] qla2xxx: add support for multi-queue adapter
Browse files Browse the repository at this point in the history
Following changes have been made.
1. qla_hw_data structure holds an array for request queue pointers,
and an array for response queue pointers.
2. The base request and response queues are created by default.
3. Additional request and response queues are created at the time of vport
creation. If queue resources are exhausted during vport creation, newly
created vports use the default queue.
4. Requests are sent to the request queue that the vport was assigned
in the beginning.
5. Responses are completed on the response queue with which the request queue
is associated with.

[fixup memcpy argument reversal spotted by davej@redhat.com]
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 85b4aa4 commit 73208df
Show file tree
Hide file tree
Showing 16 changed files with 1,443 additions and 461 deletions.
30 changes: 29 additions & 1 deletion drivers/scsi/qla2xxx/qla_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1143,8 +1143,11 @@ static int
qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
{
int ret = 0;
int cnt = 0;
uint8_t qos = QLA_DEFAULT_QUE_QOS;
scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost);
scsi_qla_host_t *vha = NULL;
struct qla_hw_data *ha = base_vha->hw;

ret = qla24xx_vport_create_req_sanity_check(fc_vport);
if (ret) {
Expand Down Expand Up @@ -1200,6 +1203,22 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)

qla24xx_vport_disable(fc_vport, disable);

/* Create a queue pair for the vport */
if (ha->mqenable) {
if (ha->npiv_info) {
for (; cnt < ha->nvram_npiv_size; cnt++) {
if (ha->npiv_info[cnt].port_name ==
vha->port_name &&
ha->npiv_info[cnt].node_name ==
vha->node_name) {
qos = ha->npiv_info[cnt].q_qos;
break;
}
}
}
qla25xx_create_queues(vha, qos);
}

return 0;
vport_create_failed_2:
qla24xx_disable_vp(vha);
Expand All @@ -1213,11 +1232,20 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
{
scsi_qla_host_t *vha = fc_vport->dd_data;
fc_port_t *fcport, *tfcport;
struct qla_hw_data *ha = vha->hw;
uint16_t id = vha->vp_idx;

while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
msleep(1000);

if (ha->mqenable) {
if (qla25xx_delete_queues(vha, 0) != QLA_SUCCESS)
qla_printk(KERN_WARNING, ha,
"Queue delete failed.\n");
vha->req_ques[0] = ha->req_q_map[0]->id;
}

qla24xx_disable_vp(vha);

fc_remove_host(vha->host);
Expand All @@ -1240,7 +1268,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
}

scsi_host_put(vha->host);

qla_printk(KERN_INFO, ha, "vport %d deleted\n", id);
return 0;
}

Expand Down
67 changes: 53 additions & 14 deletions drivers/scsi/qla2xxx/qla_dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ qla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump)
}

static inline void *
qla2xxx_copy_queues(scsi_qla_host_t *vha, void *ptr)
qla2xxx_copy_queues(struct qla_hw_data *ha, void *ptr)
{
struct req_que *req = vha->hw->req;
struct rsp_que *rsp = vha->hw->rsp;

struct req_que *req = ha->req_q_map[0];
struct rsp_que *rsp = ha->rsp_q_map[0];
/* Request queue. */
memcpy(ptr, req->ring, req->length *
sizeof(request_t));
Expand Down Expand Up @@ -327,6 +326,7 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
unsigned long flags;
struct qla2300_fw_dump *fw;
void *nxt;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);

flags = 0;

Expand Down Expand Up @@ -461,7 +461,7 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
ha->fw_memory_size - 0x11000 + 1, &nxt);

if (rval == QLA_SUCCESS)
qla2xxx_copy_queues(vha, nxt);
qla2xxx_copy_queues(ha, nxt);

if (rval != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha,
Expand All @@ -471,7 +471,7 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
} else {
qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n",
vha->host_no, ha->fw_dump);
base_vha->host_no, ha->fw_dump);
ha->fw_dumped = 1;
}

Expand All @@ -497,6 +497,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
uint16_t __iomem *dmp_reg;
unsigned long flags;
struct qla2100_fw_dump *fw;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);

risc_address = 0;
mb0 = mb2 = 0;
Expand Down Expand Up @@ -667,7 +668,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
}

if (rval == QLA_SUCCESS)
qla2xxx_copy_queues(vha, &fw->risc_ram[cnt]);
qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]);

if (rval != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha,
Expand All @@ -677,7 +678,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
} else {
qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n",
vha->host_no, ha->fw_dump);
base_vha->host_no, ha->fw_dump);
ha->fw_dumped = 1;
}

Expand All @@ -701,6 +702,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
struct qla24xx_fw_dump *fw;
uint32_t ext_mem_cnt;
void *nxt;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);

risc_address = ext_mem_cnt = 0;
flags = 0;
Expand Down Expand Up @@ -910,7 +912,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
if (rval != QLA_SUCCESS)
goto qla24xx_fw_dump_failed_0;

nxt = qla2xxx_copy_queues(vha, nxt);
nxt = qla2xxx_copy_queues(ha, nxt);
if (ha->eft)
memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size));

Expand All @@ -923,7 +925,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
} else {
qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n",
vha->host_no, ha->fw_dump);
base_vha->host_no, ha->fw_dump);
ha->fw_dumped = 1;
}

Expand All @@ -940,6 +942,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
uint32_t risc_address;
struct qla_hw_data *ha = vha->hw;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
struct device_reg_25xxmq __iomem *reg25;
uint32_t __iomem *dmp_reg;
uint32_t *iter_reg;
uint16_t __iomem *mbx_reg;
Expand All @@ -948,6 +951,11 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
uint32_t ext_mem_cnt;
void *nxt;
struct qla2xxx_fce_chain *fcec;
struct qla2xxx_mq_chain *mq = NULL;
uint32_t qreg_size;
uint8_t req_cnt, rsp_cnt, que_cnt;
uint32_t que_idx;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);

risc_address = ext_mem_cnt = 0;
flags = 0;
Expand Down Expand Up @@ -992,6 +1000,29 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++));
fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window));

/* Multi queue registers */
if (ha->mqenable) {
qreg_size = sizeof(struct qla2xxx_mq_chain);
mq = kzalloc(qreg_size, GFP_KERNEL);
if (!mq)
goto qla25xx_fw_dump_failed_0;
req_cnt = find_first_zero_bit(ha->req_qid_map, ha->max_queues);
rsp_cnt = find_first_zero_bit(ha->rsp_qid_map, ha->max_queues);
que_cnt = req_cnt > rsp_cnt ? req_cnt : rsp_cnt;
mq->count = htonl(que_cnt);
mq->chain_size = htonl(qreg_size);
mq->type = __constant_htonl(DUMP_CHAIN_MQ);
for (cnt = 0; cnt < que_cnt; cnt++) {
reg25 = (struct device_reg_25xxmq *) ((void *)
ha->mqiobase + cnt * QLA_QUE_PAGE);
que_idx = cnt * 4;
mq->qregs[que_idx] = htonl(reg25->req_q_in);
mq->qregs[que_idx+1] = htonl(reg25->req_q_out);
mq->qregs[que_idx+2] = htonl(reg25->rsp_q_in);
mq->qregs[que_idx+3] = htonl(reg25->rsp_q_out);
}
}
WRT_REG_DWORD(&reg->iobase_window, 0x00);
RD_REG_DWORD(&reg->iobase_window);

Expand Down Expand Up @@ -1219,7 +1250,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
goto qla25xx_fw_dump_failed_0;

/* Fibre Channel Trace Buffer. */
nxt = qla2xxx_copy_queues(vha, nxt);
nxt = qla2xxx_copy_queues(ha, nxt);
if (ha->eft)
memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size));

Expand All @@ -1229,7 +1260,14 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)

ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);

fcec = nxt + ntohl(ha->fw_dump->eft_size);
if (ha->mqenable) {
nxt = nxt + ntohl(ha->fw_dump->eft_size);
memcpy(nxt, mq, qreg_size);
kfree(mq);
fcec = nxt + qreg_size;
} else {
fcec = nxt + ntohl(ha->fw_dump->eft_size);
}
fcec->type = __constant_htonl(DUMP_CHAIN_FCE | DUMP_CHAIN_LAST);
fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) +
fce_calc_size(ha->fce_bufs));
Expand All @@ -1252,15 +1290,14 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
} else {
qla_printk(KERN_INFO, ha,
"Firmware dump saved to temp buffer (%ld/%p).\n",
vha->host_no, ha->fw_dump);
base_vha->host_no, ha->fw_dump);
ha->fw_dumped = 1;
}

qla25xx_fw_dump_failed:
if (!hardware_locked)
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}

/****************************************************************************/
/* Driver Debug Functions. */
/****************************************************************************/
Expand Down Expand Up @@ -1307,3 +1344,5 @@ qla2x00_dump_buffer(uint8_t * b, uint32_t size)
if (cnt % 16)
printk("\n");
}


15 changes: 14 additions & 1 deletion drivers/scsi/qla2xxx/qla_dbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/

#include "qla_def.h"

/*
* Driver debug definitions.
*/
Expand All @@ -23,6 +26,7 @@
/* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */
/* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */
/* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */
/* #define QL_DEBUG_LEVEL_17 */ /* Output MULTI-Q trace messages */

/*
* Macros use for debugging the driver.
Expand All @@ -43,6 +47,7 @@
#define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_16(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_17(x) do { if (ql2xextended_error_logging) { x; } } while (0)

#if defined(QL_DEBUG_LEVEL_3)
#define DEBUG3(x) do {x;} while (0)
Expand Down Expand Up @@ -127,7 +132,6 @@
#else
#define DEBUG16(x) do {} while (0)
#endif

/*
* Firmware Dump structure definition
*/
Expand Down Expand Up @@ -266,8 +270,17 @@ struct qla2xxx_fce_chain {
uint32_t eregs[8];
};

struct qla2xxx_mq_chain {
uint32_t type;
uint32_t chain_size;

uint32_t count;
uint32_t qregs[4 * QLA_MQ_SIZE];
};

#define DUMP_CHAIN_VARIANT 0x80000000
#define DUMP_CHAIN_FCE 0x7FFFFAF0
#define DUMP_CHAIN_MQ 0x7FFFFAF1
#define DUMP_CHAIN_LAST 0x80000000

struct qla2xxx_fw_dump {
Expand Down
Loading

0 comments on commit 73208df

Please sign in to comment.