summaryrefslogtreecommitdiff
path: root/drivers/scsi/qla2xxx/qla_mr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_mr.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_mr.c64
1 files changed, 52 insertions, 12 deletions
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 0aaf6a9c87d3..abeb3901498b 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2013 QLogic Corporation
+ * Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -527,21 +527,63 @@ qlafx00_soc_cpu_reset(scsi_qla_host_t *vha)
struct qla_hw_data *ha = vha->hw;
int i, core;
uint32_t cnt;
+ uint32_t reg_val;
+
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+
+ QLAFX00_SET_HBA_SOC_REG(ha, 0x80004, 0);
+ QLAFX00_SET_HBA_SOC_REG(ha, 0x82004, 0);
+
+ /* stop the XOR DMA engines */
+ QLAFX00_SET_HBA_SOC_REG(ha, 0x60920, 0x02);
+ QLAFX00_SET_HBA_SOC_REG(ha, 0x60924, 0x02);
+ QLAFX00_SET_HBA_SOC_REG(ha, 0xf0920, 0x02);
+ QLAFX00_SET_HBA_SOC_REG(ha, 0xf0924, 0x02);
+
+ /* stop the IDMA engines */
+ reg_val = QLAFX00_GET_HBA_SOC_REG(ha, 0x60840);
+ reg_val &= ~(1<<12);
+ QLAFX00_SET_HBA_SOC_REG(ha, 0x60840, reg_val);
+
+ reg_val = QLAFX00_GET_HBA_SOC_REG(ha, 0x60844);
+ reg_val &= ~(1<<12);
+ QLAFX00_SET_HBA_SOC_REG(ha, 0x60844, reg_val);
+
+ reg_val = QLAFX00_GET_HBA_SOC_REG(ha, 0x60848);
+ reg_val &= ~(1<<12);
+ QLAFX00_SET_HBA_SOC_REG(ha, 0x60848, reg_val);
+
+ reg_val = QLAFX00_GET_HBA_SOC_REG(ha, 0x6084C);
+ reg_val &= ~(1<<12);
+ QLAFX00_SET_HBA_SOC_REG(ha, 0x6084C, reg_val);
+
+ for (i = 0; i < 100000; i++) {
+ if ((QLAFX00_GET_HBA_SOC_REG(ha, 0xd0000) & 0x10000000) == 0 &&
+ (QLAFX00_GET_HBA_SOC_REG(ha, 0x10600) & 0x1) == 0)
+ break;
+ udelay(100);
+ }
/* Set all 4 cores in reset */
for (i = 0; i < 4; i++) {
QLAFX00_SET_HBA_SOC_REG(ha,
(SOC_SW_RST_CONTROL_REG_CORE0 + 8*i), (0xF01));
- }
-
- /* Set all 4 core Clock gating control */
- for (i = 0; i < 4; i++) {
QLAFX00_SET_HBA_SOC_REG(ha,
(SOC_SW_RST_CONTROL_REG_CORE0 + 4 + 8*i), (0x01010101));
}
/* Reset all units in Fabric */
- QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_RST_CONTROL_REG, (0x11F0101));
+ QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_RST_CONTROL_REG, (0x011f0101));
+
+ /* */
+ QLAFX00_SET_HBA_SOC_REG(ha, 0x10610, 1);
+ QLAFX00_SET_HBA_SOC_REG(ha, 0x10600, 0);
+
+ /* Set all 4 core Memory Power Down Registers */
+ for (i = 0; i < 5; i++) {
+ QLAFX00_SET_HBA_SOC_REG(ha,
+ (SOC_PWR_MANAGEMENT_PWR_DOWN_REG + 4*i), (0x0));
+ }
/* Reset all interrupt control registers */
for (i = 0; i < 115; i++) {
@@ -564,20 +606,19 @@ qlafx00_soc_cpu_reset(scsi_qla_host_t *vha)
QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_CONTROL_REG, (0x2));
QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_CONFIG_REG, (0x3));
- spin_lock_irqsave(&ha->hardware_lock, flags);
-
/* Kick in Fabric units */
QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_RST_CONTROL_REG, (0x0));
/* Kick in Core0 to start boot process */
QLAFX00_SET_HBA_SOC_REG(ha, SOC_SW_RST_CONTROL_REG_CORE0, (0xF00));
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
/* Wait 10secs for soft-reset to complete. */
for (cnt = 10; cnt; cnt--) {
msleep(1000);
barrier();
}
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
/**
@@ -597,7 +638,6 @@ qlafx00_soft_reset(scsi_qla_host_t *vha)
ha->isp_ops->disable_intrs(ha);
qlafx00_soc_cpu_reset(vha);
- ha->isp_ops->enable_intrs(ha);
}
/**
@@ -2675,7 +2715,7 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha,
uint16_t lreq_q_out = 0;
lreq_q_in = RD_REG_DWORD(rsp->rsp_q_in);
- lreq_q_out = RD_REG_DWORD(rsp->rsp_q_out);
+ lreq_q_out = rsp->ring_index;
while (lreq_q_in != lreq_q_out) {
lptr = rsp->ring_ptr;
@@ -3426,7 +3466,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
sp->fcport->vha, 0x3047,
(uint8_t *)&fx_iocb, sizeof(struct fxdisc_entry_fx00));
- memcpy((void *)pfxiocb, &fx_iocb,
+ memcpy_toio((void __iomem *)pfxiocb, &fx_iocb,
sizeof(struct fxdisc_entry_fx00));
wmb();
}