struct scatterlist *sg;
int i;
struct req_que *req;
- uint16_t que_id;
cmd = sp->cmd;
}
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));
struct scatterlist *sg;
int i;
struct req_que *req;
- uint16_t que_id;
cmd = sp->cmd;
}
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));
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;
{
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(
req->ring_ptr++;
/* Set chip new ring index. */
- if (ha->mqenable)
- RD_REG_DWORD(®->isp25mq.req_q_out);
+ if (ha->mqenable) {
+ WRT_REG_DWORD(®->isp25mq.req_q_in, req->ring_index);
+ RD_REG_DWORD(&ioreg->hccr);
+ }
else {
if (IS_FWI2_CAPABLE(ha)) {
WRT_REG_DWORD(®->isp24.req_q_in, req->ring_index);
struct scsi_cmnd *cmd;
struct scatterlist *sg;
int i;
- uint16_t que_id;
struct req_que *req;
cmd = sp->cmd;
}
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) {
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. */
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;
req_cnt = qla24xx_calc_iocbs(tot_dsds);
if (req->cnt < (req_cnt + 2)) {
- if (ha->mqenable)
- cnt = (uint16_t)
- RD_REG_DWORD_RELAXED(®->isp25mq.req_q_out);
- else
- cnt = (uint16_t)
- RD_REG_DWORD_RELAXED(®->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;
sp->flags |= SRB_DMA_VALID;
/* Set chip new ring index. */
- if (ha->mqenable)
- WRT_REG_DWORD(®->isp25mq.req_q_in, req->ring_index);
- else {
- WRT_REG_DWORD(®->isp24.req_q_in, req->ring_index);
- RD_REG_DWORD_RELAXED(®->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 &&
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(®->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(®->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(®->isp24.req_q_in, index);
+ RD_REG_DWORD_RELAXED(®->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(®->isp25mq.req_q_in, index);
+ RD_REG_DWORD(&ioreg->hccr); /* PCI posting */
+}
+
sp->vha = vha;
sp->fcport = fcport;
sp->cmd = cmd;
+ sp->que = ha->req_q_map[0];
sp->flags = 0;
CMD_SP(cmd) = (void *)sp;
cmd->scsi_done = done;
{
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
srb_t *sp;
- int ret, i, que;
+ int ret, i;
unsigned int id, lun;
unsigned long serial;
unsigned long flags;
int wait = 0;
struct qla_hw_data *ha = vha->hw;
struct req_que *req;
+ srb_t *spt;
qla2x00_block_error_handler(cmd);
id = cmd->device->id;
lun = cmd->device->lun;
serial = cmd->serial_number;
+ spt = (srb_t *) CMD_SP(cmd);
+ if (!spt)
+ return SUCCESS;
+ req = spt->que;
/* Check active list for command command. */
spin_lock_irqsave(&ha->hardware_lock, flags);
- for (que = 0; que < QLA_MAX_HOST_QUES; que++) {
- req = ha->req_q_map[vha->req_ques[que]];
- if (!req)
- continue;
- for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
- sp = req->outstanding_cmds[i];
+ for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
+ sp = req->outstanding_cmds[i];
- if (sp == NULL)
- continue;
+ if (sp == NULL)
+ continue;
- if (sp->cmd != cmd)
- continue;
+ if (sp->cmd != cmd)
+ continue;
- DEBUG2(printk("%s(%ld): aborting sp %p from RISC."
- " pid=%ld.\n", __func__, vha->host_no, sp, serial));
+ DEBUG2(printk("%s(%ld): aborting sp %p from RISC."
+ " pid=%ld.\n", __func__, vha->host_no, sp, serial));
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
- if (ha->isp_ops->abort_command(vha, sp, req)) {
- DEBUG2(printk("%s(%ld): abort_command "
- "mbx failed.\n", __func__, vha->host_no));
- } else {
- DEBUG3(printk("%s(%ld): abort_command "
- "mbx success.\n", __func__, vha->host_no));
- wait = 1;
- }
- spin_lock_irqsave(&ha->hardware_lock, flags);
- break;
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ if (ha->isp_ops->abort_command(vha, sp, req)) {
+ DEBUG2(printk("%s(%ld): abort_command "
+ "mbx failed.\n", __func__, vha->host_no));
+ } else {
+ DEBUG3(printk("%s(%ld): abort_command "
+ "mbx success.\n", __func__, vha->host_no));
+ wait = 1;
}
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+ break;
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
static int
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
- unsigned int l, enum nexus_wait_type type)
+ unsigned int l, srb_t *sp, enum nexus_wait_type type)
{
- int cnt, match, status, que;
- srb_t *sp;
+ int cnt, match, status;
unsigned long flags;
struct qla_hw_data *ha = vha->hw;
struct req_que *req;
status = QLA_SUCCESS;
+ if (!sp)
+ return status;
+
spin_lock_irqsave(&ha->hardware_lock, flags);
- for (que = 0; que < QLA_MAX_HOST_QUES; que++) {
- req = ha->req_q_map[vha->req_ques[que]];
- if (!req)
+ req = sp->que;
+ for (cnt = 1; status == QLA_SUCCESS &&
+ cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
+ sp = req->outstanding_cmds[cnt];
+ if (!sp)
continue;
- for (cnt = 1; status == QLA_SUCCESS &&
- cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
- sp = req->outstanding_cmds[cnt];
- if (!sp)
- continue;
-
- if (vha->vp_idx != sp->fcport->vha->vp_idx)
- continue;
- match = 0;
- switch (type) {
- case WAIT_HOST:
- match = 1;
- break;
- case WAIT_TARGET:
- match = sp->cmd->device->id == t;
- break;
- case WAIT_LUN:
- match = (sp->cmd->device->id == t &&
- sp->cmd->device->lun == l);
- break;
- }
- if (!match)
- continue;
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
- status = qla2x00_eh_wait_on_command(sp->cmd);
- spin_lock_irqsave(&ha->hardware_lock, flags);
+ if (vha->vp_idx != sp->fcport->vha->vp_idx)
+ continue;
+ match = 0;
+ switch (type) {
+ case WAIT_HOST:
+ match = 1;
+ break;
+ case WAIT_TARGET:
+ match = sp->cmd->device->id == t;
+ break;
+ case WAIT_LUN:
+ match = (sp->cmd->device->id == t &&
+ sp->cmd->device->lun == l);
+ break;
}
+ if (!match)
+ continue;
+
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ status = qla2x00_eh_wait_on_command(sp->cmd);
+ spin_lock_irqsave(&ha->hardware_lock, flags);
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
goto eh_reset_failed;
err = 3;
if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id,
- cmd->device->lun, type) != QLA_SUCCESS)
+ cmd->device->lun, (srb_t *) CMD_SP(cmd), type) != QLA_SUCCESS)
goto eh_reset_failed;
qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n",
int ret = FAILED;
unsigned int id, lun;
unsigned long serial;
+ srb_t *sp = (srb_t *) CMD_SP(cmd);
qla2x00_block_error_handler(cmd);
goto eh_bus_reset_done;
/* Flush outstanding commands. */
- if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) !=
+ if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, sp, WAIT_HOST) !=
QLA_SUCCESS)
ret = FAILED;
int ret = FAILED;
unsigned int id, lun;
unsigned long serial;
+ srb_t *sp = (srb_t *) CMD_SP(cmd);
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
qla2x00_block_error_handler(cmd);
}
/* Waiting for command to be returned to OS.*/
- if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) ==
+ if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, sp, WAIT_HOST) ==
QLA_SUCCESS)
ret = SUCCESS;
.write_optrom = qla2x00_write_optrom_data,
.get_flash_version = qla2x00_get_flash_version,
.start_scsi = qla2x00_start_scsi,
+ .wrt_req_reg = NULL,
+ .wrt_rsp_reg = NULL,
+ .rd_req_reg = NULL,
};
static struct isp_operations qla2300_isp_ops = {
.write_optrom = qla2x00_write_optrom_data,
.get_flash_version = qla2x00_get_flash_version,
.start_scsi = qla2x00_start_scsi,
+ .wrt_req_reg = NULL,
+ .wrt_rsp_reg = NULL,
+ .rd_req_reg = NULL,
};
static struct isp_operations qla24xx_isp_ops = {
.write_optrom = qla24xx_write_optrom_data,
.get_flash_version = qla24xx_get_flash_version,
.start_scsi = qla24xx_start_scsi,
+ .wrt_req_reg = qla24xx_wrt_req_reg,
+ .wrt_rsp_reg = qla24xx_wrt_rsp_reg,
+ .rd_req_reg = qla24xx_rd_req_reg,
};
static struct isp_operations qla25xx_isp_ops = {
.write_optrom = qla24xx_write_optrom_data,
.get_flash_version = qla24xx_get_flash_version,
.start_scsi = qla24xx_start_scsi,
+ .wrt_req_reg = qla24xx_wrt_req_reg,
+ .wrt_rsp_reg = qla24xx_wrt_rsp_reg,
+ .rd_req_reg = qla24xx_rd_req_reg,
};
static inline void
/* Determine queue resources */
ha->max_queues = 1;
- if (ql2xmaxqueues > 1) {
- ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3),
- pci_resource_len(ha->pdev, 3));
- if (ha->mqiobase) {
- /* Read MSIX vector size of the board */
- pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL,
- &msix);
- ha->msix_count = msix;
- /* Max queues are bounded by available msix vectors */
- /* queue 0 uses two msix vectors */
- if (ha->msix_count - 1 < ql2xmaxqueues)
- ha->max_queues = ha->msix_count - 1;
- else if (ql2xmaxqueues > QLA_MQ_SIZE)
- ha->max_queues = QLA_MQ_SIZE;
- else
- ha->max_queues = ql2xmaxqueues;
- qla_printk(KERN_INFO, ha,
- "MSI-X vector count: %d\n", msix);
- }
+ if (ql2xmaxqueues <= 1 || !IS_QLA25XX(ha))
+ goto mqiobase_exit;
+ ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3),
+ pci_resource_len(ha->pdev, 3));
+ if (ha->mqiobase) {
+ /* Read MSIX vector size of the board */
+ pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, &msix);
+ ha->msix_count = msix;
+ /* Max queues are bounded by available msix vectors */
+ /* queue 0 uses two msix vectors */
+ if (ha->msix_count - 1 < ql2xmaxqueues)
+ ha->max_queues = ha->msix_count - 1;
+ else if (ql2xmaxqueues > QLA_MQ_SIZE)
+ ha->max_queues = QLA_MQ_SIZE;
+ else
+ ha->max_queues = ql2xmaxqueues;
+ qla_printk(KERN_INFO, ha,
+ "MSI-X vector count: %d\n", msix);
}
+
+mqiobase_exit:
ha->msix_count = ha->max_queues + 1;
return (0);
ha->rsp_q_map[0] = rsp;
ha->req_q_map[0] = req;
+ if (ha->mqenable) {
+ ha->isp_ops->wrt_req_reg = qla25xx_wrt_req_reg;
+ ha->isp_ops->wrt_rsp_reg = qla25xx_wrt_rsp_reg;
+ ha->isp_ops->rd_req_reg = qla25xx_rd_req_reg;
+ }
+
if (qla2x00_initialize_adapter(base_vha)) {
qla_printk(KERN_WARNING, ha,
"Failed to initialize adapter\n");