|
@@ -338,26 +338,25 @@ update_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha, int number)
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * bar4_shift - function is called to shift BAR base address
|
|
|
|
- * @pm8001_ha : our hba card information
|
|
|
|
|
|
+ * pm8001_bar4_shift - function is called to shift BAR base address
|
|
|
|
+ * @pm8001_ha : our hba card infomation
|
|
* @shiftValue : shifting value in memory bar.
|
|
* @shiftValue : shifting value in memory bar.
|
|
*/
|
|
*/
|
|
-static int bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue)
|
|
|
|
|
|
+int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue)
|
|
{
|
|
{
|
|
u32 regVal;
|
|
u32 regVal;
|
|
- u32 max_wait_count;
|
|
|
|
|
|
+ unsigned long start;
|
|
|
|
|
|
/* program the inbound AXI translation Lower Address */
|
|
/* program the inbound AXI translation Lower Address */
|
|
pm8001_cw32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW, shiftValue);
|
|
pm8001_cw32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW, shiftValue);
|
|
|
|
|
|
/* confirm the setting is written */
|
|
/* confirm the setting is written */
|
|
- max_wait_count = 1 * 1000 * 1000; /* 1 sec */
|
|
|
|
|
|
+ start = jiffies + HZ; /* 1 sec */
|
|
do {
|
|
do {
|
|
- udelay(1);
|
|
|
|
regVal = pm8001_cr32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW);
|
|
regVal = pm8001_cr32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW);
|
|
- } while ((regVal != shiftValue) && (--max_wait_count));
|
|
|
|
|
|
+ } while ((regVal != shiftValue) && time_before(jiffies, start));
|
|
|
|
|
|
- if (!max_wait_count) {
|
|
|
|
|
|
+ if (regVal != shiftValue) {
|
|
PM8001_INIT_DBG(pm8001_ha,
|
|
PM8001_INIT_DBG(pm8001_ha,
|
|
pm8001_printk("TIMEOUT:SPC_IBW_AXI_TRANSLATION_LOW"
|
|
pm8001_printk("TIMEOUT:SPC_IBW_AXI_TRANSLATION_LOW"
|
|
" = 0x%x\n", regVal));
|
|
" = 0x%x\n", regVal));
|
|
@@ -375,6 +374,7 @@ static void __devinit
|
|
mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit)
|
|
mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit)
|
|
{
|
|
{
|
|
u32 value, offset, i;
|
|
u32 value, offset, i;
|
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
#define SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR 0x00030000
|
|
#define SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR 0x00030000
|
|
#define SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR 0x00040000
|
|
#define SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR 0x00040000
|
|
@@ -388,16 +388,23 @@ mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit)
|
|
* Using shifted destination address 0x3_0000:0x1074 + 0x4000*N (N=0:3)
|
|
* Using shifted destination address 0x3_0000:0x1074 + 0x4000*N (N=0:3)
|
|
* Using shifted destination address 0x4_0000:0x1074 + 0x4000*(N-4) (N=4:7)
|
|
* Using shifted destination address 0x4_0000:0x1074 + 0x4000*(N-4) (N=4:7)
|
|
*/
|
|
*/
|
|
- if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR))
|
|
|
|
|
|
+ spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
+ if (-1 == pm8001_bar4_shift(pm8001_ha,
|
|
|
|
+ SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR)) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
return;
|
|
return;
|
|
|
|
+ }
|
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
for (i = 0; i < 4; i++) {
|
|
offset = SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET + 0x4000 * i;
|
|
offset = SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET + 0x4000 * i;
|
|
pm8001_cw32(pm8001_ha, 2, offset, 0x80001501);
|
|
pm8001_cw32(pm8001_ha, 2, offset, 0x80001501);
|
|
}
|
|
}
|
|
/* shift membase 3 for SAS2_SETTINGS_LOCAL_PHY 4 - 7 */
|
|
/* shift membase 3 for SAS2_SETTINGS_LOCAL_PHY 4 - 7 */
|
|
- if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR))
|
|
|
|
|
|
+ if (-1 == pm8001_bar4_shift(pm8001_ha,
|
|
|
|
+ SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR)) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
return;
|
|
return;
|
|
|
|
+ }
|
|
for (i = 4; i < 8; i++) {
|
|
for (i = 4; i < 8; i++) {
|
|
offset = SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET + 0x4000 * (i-4);
|
|
offset = SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET + 0x4000 * (i-4);
|
|
pm8001_cw32(pm8001_ha, 2, offset, 0x80001501);
|
|
pm8001_cw32(pm8001_ha, 2, offset, 0x80001501);
|
|
@@ -421,7 +428,8 @@ mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit)
|
|
pm8001_cw32(pm8001_ha, 2, 0xd8, 0x8000C016);
|
|
pm8001_cw32(pm8001_ha, 2, 0xd8, 0x8000C016);
|
|
|
|
|
|
/*set the shifted destination address to 0x0 to avoid error operation */
|
|
/*set the shifted destination address to 0x0 to avoid error operation */
|
|
- bar4_shift(pm8001_ha, 0x0);
|
|
|
|
|
|
+ pm8001_bar4_shift(pm8001_ha, 0x0);
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -437,6 +445,7 @@ mpi_set_open_retry_interval_reg(struct pm8001_hba_info *pm8001_ha,
|
|
u32 offset;
|
|
u32 offset;
|
|
u32 value;
|
|
u32 value;
|
|
u32 i;
|
|
u32 i;
|
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
#define OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR 0x00030000
|
|
#define OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR 0x00030000
|
|
#define OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR 0x00040000
|
|
#define OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR 0x00040000
|
|
@@ -445,24 +454,30 @@ mpi_set_open_retry_interval_reg(struct pm8001_hba_info *pm8001_ha,
|
|
#define OPEN_RETRY_INTERVAL_REG_MASK 0x0000FFFF
|
|
#define OPEN_RETRY_INTERVAL_REG_MASK 0x0000FFFF
|
|
|
|
|
|
value = interval & OPEN_RETRY_INTERVAL_REG_MASK;
|
|
value = interval & OPEN_RETRY_INTERVAL_REG_MASK;
|
|
|
|
+ spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
/* shift bar and set the OPEN_REJECT(RETRY) interval time of PHY 0 -3.*/
|
|
/* shift bar and set the OPEN_REJECT(RETRY) interval time of PHY 0 -3.*/
|
|
- if (-1 == bar4_shift(pm8001_ha,
|
|
|
|
- OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR))
|
|
|
|
|
|
+ if (-1 == pm8001_bar4_shift(pm8001_ha,
|
|
|
|
+ OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR)) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
return;
|
|
return;
|
|
|
|
+ }
|
|
for (i = 0; i < 4; i++) {
|
|
for (i = 0; i < 4; i++) {
|
|
offset = OPEN_RETRY_INTERVAL_PHY_0_3_OFFSET + 0x4000 * i;
|
|
offset = OPEN_RETRY_INTERVAL_PHY_0_3_OFFSET + 0x4000 * i;
|
|
pm8001_cw32(pm8001_ha, 2, offset, value);
|
|
pm8001_cw32(pm8001_ha, 2, offset, value);
|
|
}
|
|
}
|
|
|
|
|
|
- if (-1 == bar4_shift(pm8001_ha,
|
|
|
|
- OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR))
|
|
|
|
|
|
+ if (-1 == pm8001_bar4_shift(pm8001_ha,
|
|
|
|
+ OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR)) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
return;
|
|
return;
|
|
|
|
+ }
|
|
for (i = 4; i < 8; i++) {
|
|
for (i = 4; i < 8; i++) {
|
|
offset = OPEN_RETRY_INTERVAL_PHY_4_7_OFFSET + 0x4000 * (i-4);
|
|
offset = OPEN_RETRY_INTERVAL_PHY_4_7_OFFSET + 0x4000 * (i-4);
|
|
pm8001_cw32(pm8001_ha, 2, offset, value);
|
|
pm8001_cw32(pm8001_ha, 2, offset, value);
|
|
}
|
|
}
|
|
/*set the shifted destination address to 0x0 to avoid error operation */
|
|
/*set the shifted destination address to 0x0 to avoid error operation */
|
|
- bar4_shift(pm8001_ha, 0x0);
|
|
|
|
|
|
+ pm8001_bar4_shift(pm8001_ha, 0x0);
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -607,7 +622,8 @@ static int __devinit pm8001_chip_init(struct pm8001_hba_info *pm8001_ha)
|
|
update_inbnd_queue_table(pm8001_ha, 0);
|
|
update_inbnd_queue_table(pm8001_ha, 0);
|
|
update_outbnd_queue_table(pm8001_ha, 0);
|
|
update_outbnd_queue_table(pm8001_ha, 0);
|
|
mpi_set_phys_g3_with_ssc(pm8001_ha, 0);
|
|
mpi_set_phys_g3_with_ssc(pm8001_ha, 0);
|
|
- mpi_set_open_retry_interval_reg(pm8001_ha, 7);
|
|
|
|
|
|
+ /* 7->130ms, 34->500ms, 119->1.5s */
|
|
|
|
+ mpi_set_open_retry_interval_reg(pm8001_ha, 119);
|
|
/* notify firmware update finished and check initialization status */
|
|
/* notify firmware update finished and check initialization status */
|
|
if (0 == mpi_init_check(pm8001_ha)) {
|
|
if (0 == mpi_init_check(pm8001_ha)) {
|
|
PM8001_INIT_DBG(pm8001_ha,
|
|
PM8001_INIT_DBG(pm8001_ha,
|
|
@@ -688,8 +704,11 @@ static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha)
|
|
PM8001_INIT_DBG(pm8001_ha,
|
|
PM8001_INIT_DBG(pm8001_ha,
|
|
pm8001_printk("Firmware is ready for reset .\n"));
|
|
pm8001_printk("Firmware is ready for reset .\n"));
|
|
} else {
|
|
} else {
|
|
- /* Trigger NMI twice via RB6 */
|
|
|
|
- if (-1 == bar4_shift(pm8001_ha, RB6_ACCESS_REG)) {
|
|
|
|
|
|
+ unsigned long flags;
|
|
|
|
+ /* Trigger NMI twice via RB6 */
|
|
|
|
+ spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
+ if (-1 == pm8001_bar4_shift(pm8001_ha, RB6_ACCESS_REG)) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
pm8001_printk("Shift Bar4 to 0x%x failed\n",
|
|
pm8001_printk("Shift Bar4 to 0x%x failed\n",
|
|
RB6_ACCESS_REG));
|
|
RB6_ACCESS_REG));
|
|
@@ -715,8 +734,10 @@ static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha)
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
|
|
pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
|
|
pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3)));
|
|
pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3)));
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -733,6 +754,7 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
|
|
u32 regVal, toggleVal;
|
|
u32 regVal, toggleVal;
|
|
u32 max_wait_count;
|
|
u32 max_wait_count;
|
|
u32 regVal1, regVal2, regVal3;
|
|
u32 regVal1, regVal2, regVal3;
|
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
/* step1: Check FW is ready for soft reset */
|
|
/* step1: Check FW is ready for soft reset */
|
|
if (soft_reset_ready_check(pm8001_ha) != 0) {
|
|
if (soft_reset_ready_check(pm8001_ha) != 0) {
|
|
@@ -743,7 +765,9 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
|
|
/* step 2: clear NMI status register on AAP1 and IOP, write the same
|
|
/* step 2: clear NMI status register on AAP1 and IOP, write the same
|
|
value to clear */
|
|
value to clear */
|
|
/* map 0x60000 to BAR4(0x20), BAR2(win) */
|
|
/* map 0x60000 to BAR4(0x20), BAR2(win) */
|
|
- if (-1 == bar4_shift(pm8001_ha, MBIC_AAP1_ADDR_BASE)) {
|
|
|
|
|
|
+ spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
+ if (-1 == pm8001_bar4_shift(pm8001_ha, MBIC_AAP1_ADDR_BASE)) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
pm8001_printk("Shift Bar4 to 0x%x failed\n",
|
|
pm8001_printk("Shift Bar4 to 0x%x failed\n",
|
|
MBIC_AAP1_ADDR_BASE));
|
|
MBIC_AAP1_ADDR_BASE));
|
|
@@ -754,7 +778,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
|
|
pm8001_printk("MBIC - NMI Enable VPE0 (IOP)= 0x%x\n", regVal));
|
|
pm8001_printk("MBIC - NMI Enable VPE0 (IOP)= 0x%x\n", regVal));
|
|
pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP, 0x0);
|
|
pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP, 0x0);
|
|
/* map 0x70000 to BAR4(0x20), BAR2(win) */
|
|
/* map 0x70000 to BAR4(0x20), BAR2(win) */
|
|
- if (-1 == bar4_shift(pm8001_ha, MBIC_IOP_ADDR_BASE)) {
|
|
|
|
|
|
+ if (-1 == pm8001_bar4_shift(pm8001_ha, MBIC_IOP_ADDR_BASE)) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
pm8001_printk("Shift Bar4 to 0x%x failed\n",
|
|
pm8001_printk("Shift Bar4 to 0x%x failed\n",
|
|
MBIC_IOP_ADDR_BASE));
|
|
MBIC_IOP_ADDR_BASE));
|
|
@@ -796,7 +821,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
|
|
|
|
|
|
/* read required registers for confirmming */
|
|
/* read required registers for confirmming */
|
|
/* map 0x0700000 to BAR4(0x20), BAR2(win) */
|
|
/* map 0x0700000 to BAR4(0x20), BAR2(win) */
|
|
- if (-1 == bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {
|
|
|
|
|
|
+ if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
pm8001_printk("Shift Bar4 to 0x%x failed\n",
|
|
pm8001_printk("Shift Bar4 to 0x%x failed\n",
|
|
GSM_ADDR_BASE));
|
|
GSM_ADDR_BASE));
|
|
@@ -862,7 +888,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
|
|
/* step 5: delay 10 usec */
|
|
/* step 5: delay 10 usec */
|
|
udelay(10);
|
|
udelay(10);
|
|
/* step 5-b: set GPIO-0 output control to tristate anyway */
|
|
/* step 5-b: set GPIO-0 output control to tristate anyway */
|
|
- if (-1 == bar4_shift(pm8001_ha, GPIO_ADDR_BASE)) {
|
|
|
|
|
|
+ if (-1 == pm8001_bar4_shift(pm8001_ha, GPIO_ADDR_BASE)) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
PM8001_INIT_DBG(pm8001_ha,
|
|
PM8001_INIT_DBG(pm8001_ha,
|
|
pm8001_printk("Shift Bar4 to 0x%x failed\n",
|
|
pm8001_printk("Shift Bar4 to 0x%x failed\n",
|
|
GPIO_ADDR_BASE));
|
|
GPIO_ADDR_BASE));
|
|
@@ -878,7 +905,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
|
|
|
|
|
|
/* Step 6: Reset the IOP and AAP1 */
|
|
/* Step 6: Reset the IOP and AAP1 */
|
|
/* map 0x00000 to BAR4(0x20), BAR2(win) */
|
|
/* map 0x00000 to BAR4(0x20), BAR2(win) */
|
|
- if (-1 == bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {
|
|
|
|
|
|
+ if (-1 == pm8001_bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
pm8001_printk("SPC Shift Bar4 to 0x%x failed\n",
|
|
pm8001_printk("SPC Shift Bar4 to 0x%x failed\n",
|
|
SPC_TOP_LEVEL_ADDR_BASE));
|
|
SPC_TOP_LEVEL_ADDR_BASE));
|
|
@@ -915,7 +943,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
|
|
|
|
|
|
/* step 11: reads and sets the GSM Configuration and Reset Register */
|
|
/* step 11: reads and sets the GSM Configuration and Reset Register */
|
|
/* map 0x0700000 to BAR4(0x20), BAR2(win) */
|
|
/* map 0x0700000 to BAR4(0x20), BAR2(win) */
|
|
- if (-1 == bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {
|
|
|
|
|
|
+ if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
pm8001_printk("SPC Shift Bar4 to 0x%x failed\n",
|
|
pm8001_printk("SPC Shift Bar4 to 0x%x failed\n",
|
|
GSM_ADDR_BASE));
|
|
GSM_ADDR_BASE));
|
|
@@ -968,7 +997,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
|
|
|
|
|
|
/* step 13: bring the IOP and AAP1 out of reset */
|
|
/* step 13: bring the IOP and AAP1 out of reset */
|
|
/* map 0x00000 to BAR4(0x20), BAR2(win) */
|
|
/* map 0x00000 to BAR4(0x20), BAR2(win) */
|
|
- if (-1 == bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {
|
|
|
|
|
|
+ if (-1 == pm8001_bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
pm8001_printk("Shift Bar4 to 0x%x failed\n",
|
|
pm8001_printk("Shift Bar4 to 0x%x failed\n",
|
|
SPC_TOP_LEVEL_ADDR_BASE));
|
|
SPC_TOP_LEVEL_ADDR_BASE));
|
|
@@ -1010,6 +1040,7 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
|
|
pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
|
|
pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
|
|
pm8001_cr32(pm8001_ha, 0,
|
|
pm8001_cr32(pm8001_ha, 0,
|
|
MSGU_SCRATCH_PAD_3)));
|
|
MSGU_SCRATCH_PAD_3)));
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1039,9 +1070,12 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
|
|
pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
|
|
pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
|
|
pm8001_cr32(pm8001_ha, 0,
|
|
pm8001_cr32(pm8001_ha, 0,
|
|
MSGU_SCRATCH_PAD_3)));
|
|
MSGU_SCRATCH_PAD_3)));
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ pm8001_bar4_shift(pm8001_ha, 0);
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
|
|
PM8001_INIT_DBG(pm8001_ha,
|
|
PM8001_INIT_DBG(pm8001_ha,
|
|
pm8001_printk("SPC soft reset Complete\n"));
|
|
pm8001_printk("SPC soft reset Complete\n"));
|
|
@@ -1157,8 +1191,8 @@ pm8001_chip_msix_interrupt_disable(struct pm8001_hba_info *pm8001_ha,
|
|
msi_index = int_vec_idx * MSIX_TABLE_ELEMENT_SIZE;
|
|
msi_index = int_vec_idx * MSIX_TABLE_ELEMENT_SIZE;
|
|
msi_index += MSIX_TABLE_BASE;
|
|
msi_index += MSIX_TABLE_BASE;
|
|
pm8001_cw32(pm8001_ha, 0, msi_index, MSIX_INTERRUPT_DISABLE);
|
|
pm8001_cw32(pm8001_ha, 0, msi_index, MSIX_INTERRUPT_DISABLE);
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* pm8001_chip_interrupt_enable - enable PM8001 chip interrupt
|
|
* pm8001_chip_interrupt_enable - enable PM8001 chip interrupt
|
|
* @pm8001_ha: our hba card information
|
|
* @pm8001_ha: our hba card information
|
|
@@ -1212,7 +1246,7 @@ static int mpi_msg_free_get(struct inbound_queue_table *circularQ,
|
|
consumer_index = pm8001_read_32(circularQ->ci_virt);
|
|
consumer_index = pm8001_read_32(circularQ->ci_virt);
|
|
circularQ->consumer_index = cpu_to_le32(consumer_index);
|
|
circularQ->consumer_index = cpu_to_le32(consumer_index);
|
|
if (((circularQ->producer_idx + bcCount) % 256) ==
|
|
if (((circularQ->producer_idx + bcCount) % 256) ==
|
|
- circularQ->consumer_index) {
|
|
|
|
|
|
+ le32_to_cpu(circularQ->consumer_index)) {
|
|
*messagePtr = NULL;
|
|
*messagePtr = NULL;
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -1321,7 +1355,8 @@ static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha,
|
|
u32 header_tmp;
|
|
u32 header_tmp;
|
|
do {
|
|
do {
|
|
/* If there are not-yet-delivered messages ... */
|
|
/* If there are not-yet-delivered messages ... */
|
|
- if (circularQ->producer_index != circularQ->consumer_idx) {
|
|
|
|
|
|
+ if (le32_to_cpu(circularQ->producer_index)
|
|
|
|
+ != circularQ->consumer_idx) {
|
|
/*Get the pointer to the circular queue buffer element*/
|
|
/*Get the pointer to the circular queue buffer element*/
|
|
msgHeader = (struct mpi_msg_hdr *)
|
|
msgHeader = (struct mpi_msg_hdr *)
|
|
(circularQ->base_virt +
|
|
(circularQ->base_virt +
|
|
@@ -1329,14 +1364,14 @@ static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha,
|
|
/* read header */
|
|
/* read header */
|
|
header_tmp = pm8001_read_32(msgHeader);
|
|
header_tmp = pm8001_read_32(msgHeader);
|
|
msgHeader_tmp = cpu_to_le32(header_tmp);
|
|
msgHeader_tmp = cpu_to_le32(header_tmp);
|
|
- if (0 != (msgHeader_tmp & 0x80000000)) {
|
|
|
|
|
|
+ if (0 != (le32_to_cpu(msgHeader_tmp) & 0x80000000)) {
|
|
if (OPC_OUB_SKIP_ENTRY !=
|
|
if (OPC_OUB_SKIP_ENTRY !=
|
|
- (msgHeader_tmp & 0xfff)) {
|
|
|
|
|
|
+ (le32_to_cpu(msgHeader_tmp) & 0xfff)) {
|
|
*messagePtr1 =
|
|
*messagePtr1 =
|
|
((u8 *)msgHeader) +
|
|
((u8 *)msgHeader) +
|
|
sizeof(struct mpi_msg_hdr);
|
|
sizeof(struct mpi_msg_hdr);
|
|
- *pBC = (u8)((msgHeader_tmp >> 24) &
|
|
|
|
- 0x1f);
|
|
|
|
|
|
+ *pBC = (u8)((le32_to_cpu(msgHeader_tmp)
|
|
|
|
+ >> 24) & 0x1f);
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
pm8001_printk(": CI=%d PI=%d "
|
|
pm8001_printk(": CI=%d PI=%d "
|
|
"msgHeader=%x\n",
|
|
"msgHeader=%x\n",
|
|
@@ -1347,8 +1382,8 @@ static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha,
|
|
} else {
|
|
} else {
|
|
circularQ->consumer_idx =
|
|
circularQ->consumer_idx =
|
|
(circularQ->consumer_idx +
|
|
(circularQ->consumer_idx +
|
|
- ((msgHeader_tmp >> 24) & 0x1f))
|
|
|
|
- % 256;
|
|
|
|
|
|
+ ((le32_to_cpu(msgHeader_tmp)
|
|
|
|
+ >> 24) & 0x1f)) % 256;
|
|
msgHeader_tmp = 0;
|
|
msgHeader_tmp = 0;
|
|
pm8001_write_32(msgHeader, 0, 0);
|
|
pm8001_write_32(msgHeader, 0, 0);
|
|
/* update the CI of outbound queue */
|
|
/* update the CI of outbound queue */
|
|
@@ -1360,7 +1395,8 @@ static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha,
|
|
} else {
|
|
} else {
|
|
circularQ->consumer_idx =
|
|
circularQ->consumer_idx =
|
|
(circularQ->consumer_idx +
|
|
(circularQ->consumer_idx +
|
|
- ((msgHeader_tmp >> 24) & 0x1f)) % 256;
|
|
|
|
|
|
+ ((le32_to_cpu(msgHeader_tmp) >> 24) &
|
|
|
|
+ 0x1f)) % 256;
|
|
msgHeader_tmp = 0;
|
|
msgHeader_tmp = 0;
|
|
pm8001_write_32(msgHeader, 0, 0);
|
|
pm8001_write_32(msgHeader, 0, 0);
|
|
/* update the CI of outbound queue */
|
|
/* update the CI of outbound queue */
|
|
@@ -1376,7 +1412,8 @@ static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha,
|
|
producer_index = pm8001_read_32(pi_virt);
|
|
producer_index = pm8001_read_32(pi_virt);
|
|
circularQ->producer_index = cpu_to_le32(producer_index);
|
|
circularQ->producer_index = cpu_to_le32(producer_index);
|
|
}
|
|
}
|
|
- } while (circularQ->producer_index != circularQ->consumer_idx);
|
|
|
|
|
|
+ } while (le32_to_cpu(circularQ->producer_index) !=
|
|
|
|
+ circularQ->consumer_idx);
|
|
/* while we don't have any more not-yet-delivered message */
|
|
/* while we don't have any more not-yet-delivered message */
|
|
/* report empty */
|
|
/* report empty */
|
|
return MPI_IO_STATUS_BUSY;
|
|
return MPI_IO_STATUS_BUSY;
|
|
@@ -1388,24 +1425,191 @@ static void pm8001_work_fn(struct work_struct *work)
|
|
struct pm8001_device *pm8001_dev;
|
|
struct pm8001_device *pm8001_dev;
|
|
struct domain_device *dev;
|
|
struct domain_device *dev;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * So far, all users of this stash an associated structure here.
|
|
|
|
+ * If we get here, and this pointer is null, then the action
|
|
|
|
+ * was cancelled. This nullification happens when the device
|
|
|
|
+ * goes away.
|
|
|
|
+ */
|
|
|
|
+ pm8001_dev = pw->data; /* Most stash device structure */
|
|
|
|
+ if ((pm8001_dev == NULL)
|
|
|
|
+ || ((pw->handler != IO_XFER_ERROR_BREAK)
|
|
|
|
+ && (pm8001_dev->dev_type == NO_DEVICE))) {
|
|
|
|
+ kfree(pw);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
switch (pw->handler) {
|
|
switch (pw->handler) {
|
|
|
|
+ case IO_XFER_ERROR_BREAK:
|
|
|
|
+ { /* This one stashes the sas_task instead */
|
|
|
|
+ struct sas_task *t = (struct sas_task *)pm8001_dev;
|
|
|
|
+ u32 tag;
|
|
|
|
+ struct pm8001_ccb_info *ccb;
|
|
|
|
+ struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;
|
|
|
|
+ unsigned long flags, flags1;
|
|
|
|
+ struct task_status_struct *ts;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ if (pm8001_query_task(t) == TMF_RESP_FUNC_SUCC)
|
|
|
|
+ break; /* Task still on lu */
|
|
|
|
+ spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
+
|
|
|
|
+ spin_lock_irqsave(&t->task_state_lock, flags1);
|
|
|
|
+ if (unlikely((t->task_state_flags & SAS_TASK_STATE_DONE))) {
|
|
|
|
+ spin_unlock_irqrestore(&t->task_state_lock, flags1);
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
+ break; /* Task got completed by another */
|
|
|
|
+ }
|
|
|
|
+ spin_unlock_irqrestore(&t->task_state_lock, flags1);
|
|
|
|
+
|
|
|
|
+ /* Search for a possible ccb that matches the task */
|
|
|
|
+ for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
|
|
|
|
+ ccb = &pm8001_ha->ccb_info[i];
|
|
|
|
+ tag = ccb->ccb_tag;
|
|
|
|
+ if ((tag != 0xFFFFFFFF) && (ccb->task == t))
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (!ccb) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
+ break; /* Task got freed by another */
|
|
|
|
+ }
|
|
|
|
+ ts = &t->task_status;
|
|
|
|
+ ts->resp = SAS_TASK_COMPLETE;
|
|
|
|
+ /* Force the midlayer to retry */
|
|
|
|
+ ts->stat = SAS_QUEUE_FULL;
|
|
|
|
+ pm8001_dev = ccb->device;
|
|
|
|
+ if (pm8001_dev)
|
|
|
|
+ pm8001_dev->running_req--;
|
|
|
|
+ spin_lock_irqsave(&t->task_state_lock, flags1);
|
|
|
|
+ t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
|
|
|
|
+ t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
|
|
|
|
+ t->task_state_flags |= SAS_TASK_STATE_DONE;
|
|
|
|
+ if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
|
|
|
|
+ spin_unlock_irqrestore(&t->task_state_lock, flags1);
|
|
|
|
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("task 0x%p"
|
|
|
|
+ " done with event 0x%x resp 0x%x stat 0x%x but"
|
|
|
|
+ " aborted by upper layer!\n",
|
|
|
|
+ t, pw->handler, ts->resp, ts->stat));
|
|
|
|
+ pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
+ } else {
|
|
|
|
+ spin_unlock_irqrestore(&t->task_state_lock, flags1);
|
|
|
|
+ pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
|
|
+ mb();/* in order to force CPU ordering */
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
+ t->task_done(t);
|
|
|
|
+ }
|
|
|
|
+ } break;
|
|
|
|
+ case IO_XFER_OPEN_RETRY_TIMEOUT:
|
|
|
|
+ { /* This one stashes the sas_task instead */
|
|
|
|
+ struct sas_task *t = (struct sas_task *)pm8001_dev;
|
|
|
|
+ u32 tag;
|
|
|
|
+ struct pm8001_ccb_info *ccb;
|
|
|
|
+ struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;
|
|
|
|
+ unsigned long flags, flags1;
|
|
|
|
+ int i, ret = 0;
|
|
|
|
+
|
|
|
|
+ PM8001_IO_DBG(pm8001_ha,
|
|
|
|
+ pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
|
|
|
|
+
|
|
|
|
+ ret = pm8001_query_task(t);
|
|
|
|
+
|
|
|
|
+ PM8001_IO_DBG(pm8001_ha,
|
|
|
|
+ switch (ret) {
|
|
|
|
+ case TMF_RESP_FUNC_SUCC:
|
|
|
|
+ pm8001_printk("...Task on lu\n");
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case TMF_RESP_FUNC_COMPLETE:
|
|
|
|
+ pm8001_printk("...Task NOT on lu\n");
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ pm8001_printk("...query task failed!!!\n");
|
|
|
|
+ break;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
+
|
|
|
|
+ spin_lock_irqsave(&t->task_state_lock, flags1);
|
|
|
|
+
|
|
|
|
+ if (unlikely((t->task_state_flags & SAS_TASK_STATE_DONE))) {
|
|
|
|
+ spin_unlock_irqrestore(&t->task_state_lock, flags1);
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
+ if (ret == TMF_RESP_FUNC_SUCC) /* task on lu */
|
|
|
|
+ (void)pm8001_abort_task(t);
|
|
|
|
+ break; /* Task got completed by another */
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ spin_unlock_irqrestore(&t->task_state_lock, flags1);
|
|
|
|
+
|
|
|
|
+ /* Search for a possible ccb that matches the task */
|
|
|
|
+ for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
|
|
|
|
+ ccb = &pm8001_ha->ccb_info[i];
|
|
|
|
+ tag = ccb->ccb_tag;
|
|
|
|
+ if ((tag != 0xFFFFFFFF) && (ccb->task == t))
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (!ccb) {
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
+ if (ret == TMF_RESP_FUNC_SUCC) /* task on lu */
|
|
|
|
+ (void)pm8001_abort_task(t);
|
|
|
|
+ break; /* Task got freed by another */
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pm8001_dev = ccb->device;
|
|
|
|
+ dev = pm8001_dev->sas_device;
|
|
|
|
+
|
|
|
|
+ switch (ret) {
|
|
|
|
+ case TMF_RESP_FUNC_SUCC: /* task on lu */
|
|
|
|
+ ccb->open_retry = 1; /* Snub completion */
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
+ ret = pm8001_abort_task(t);
|
|
|
|
+ ccb->open_retry = 0;
|
|
|
|
+ switch (ret) {
|
|
|
|
+ case TMF_RESP_FUNC_SUCC:
|
|
|
|
+ case TMF_RESP_FUNC_COMPLETE:
|
|
|
|
+ break;
|
|
|
|
+ default: /* device misbehavior */
|
|
|
|
+ ret = TMF_RESP_FUNC_FAILED;
|
|
|
|
+ PM8001_IO_DBG(pm8001_ha,
|
|
|
|
+ pm8001_printk("...Reset phy\n"));
|
|
|
|
+ pm8001_I_T_nexus_reset(dev);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case TMF_RESP_FUNC_COMPLETE: /* task not on lu */
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
+ /* Do we need to abort the task locally? */
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default: /* device misbehavior */
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
+ ret = TMF_RESP_FUNC_FAILED;
|
|
|
|
+ PM8001_IO_DBG(pm8001_ha,
|
|
|
|
+ pm8001_printk("...Reset phy\n"));
|
|
|
|
+ pm8001_I_T_nexus_reset(dev);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ret == TMF_RESP_FUNC_FAILED)
|
|
|
|
+ t = NULL;
|
|
|
|
+ pm8001_open_reject_retry(pm8001_ha, t, pm8001_dev);
|
|
|
|
+ PM8001_IO_DBG(pm8001_ha, pm8001_printk("...Complete\n"));
|
|
|
|
+ } break;
|
|
case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
|
|
case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
|
|
- pm8001_dev = pw->data;
|
|
|
|
dev = pm8001_dev->sas_device;
|
|
dev = pm8001_dev->sas_device;
|
|
pm8001_I_T_nexus_reset(dev);
|
|
pm8001_I_T_nexus_reset(dev);
|
|
break;
|
|
break;
|
|
case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
|
|
case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
|
|
- pm8001_dev = pw->data;
|
|
|
|
dev = pm8001_dev->sas_device;
|
|
dev = pm8001_dev->sas_device;
|
|
pm8001_I_T_nexus_reset(dev);
|
|
pm8001_I_T_nexus_reset(dev);
|
|
break;
|
|
break;
|
|
case IO_DS_IN_ERROR:
|
|
case IO_DS_IN_ERROR:
|
|
- pm8001_dev = pw->data;
|
|
|
|
dev = pm8001_dev->sas_device;
|
|
dev = pm8001_dev->sas_device;
|
|
pm8001_I_T_nexus_reset(dev);
|
|
pm8001_I_T_nexus_reset(dev);
|
|
break;
|
|
break;
|
|
case IO_DS_NON_OPERATIONAL:
|
|
case IO_DS_NON_OPERATIONAL:
|
|
- pm8001_dev = pw->data;
|
|
|
|
dev = pm8001_dev->sas_device;
|
|
dev = pm8001_dev->sas_device;
|
|
pm8001_I_T_nexus_reset(dev);
|
|
pm8001_I_T_nexus_reset(dev);
|
|
break;
|
|
break;
|
|
@@ -1460,6 +1664,11 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
|
|
status = le32_to_cpu(psspPayload->status);
|
|
status = le32_to_cpu(psspPayload->status);
|
|
tag = le32_to_cpu(psspPayload->tag);
|
|
tag = le32_to_cpu(psspPayload->tag);
|
|
ccb = &pm8001_ha->ccb_info[tag];
|
|
ccb = &pm8001_ha->ccb_info[tag];
|
|
|
|
+ if ((status == IO_ABORTED) && ccb->open_retry) {
|
|
|
|
+ /* Being completed by another */
|
|
|
|
+ ccb->open_retry = 0;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
pm8001_dev = ccb->device;
|
|
pm8001_dev = ccb->device;
|
|
param = le32_to_cpu(psspPayload->param);
|
|
param = le32_to_cpu(psspPayload->param);
|
|
|
|
|
|
@@ -1515,6 +1724,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
|
|
pm8001_printk("IO_XFER_ERROR_BREAK\n"));
|
|
pm8001_printk("IO_XFER_ERROR_BREAK\n"));
|
|
ts->resp = SAS_TASK_COMPLETE;
|
|
ts->resp = SAS_TASK_COMPLETE;
|
|
ts->stat = SAS_OPEN_REJECT;
|
|
ts->stat = SAS_OPEN_REJECT;
|
|
|
|
+ /* Force the midlayer to retry */
|
|
|
|
+ ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
|
|
break;
|
|
break;
|
|
case IO_XFER_ERROR_PHY_NOT_READY:
|
|
case IO_XFER_ERROR_PHY_NOT_READY:
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
@@ -1719,9 +1930,8 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
|
|
case IO_XFER_ERROR_BREAK:
|
|
case IO_XFER_ERROR_BREAK:
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
pm8001_printk("IO_XFER_ERROR_BREAK\n"));
|
|
pm8001_printk("IO_XFER_ERROR_BREAK\n"));
|
|
- ts->resp = SAS_TASK_COMPLETE;
|
|
|
|
- ts->stat = SAS_INTERRUPTED;
|
|
|
|
- break;
|
|
|
|
|
|
+ pm8001_handle_event(pm8001_ha, t, IO_XFER_ERROR_BREAK);
|
|
|
|
+ return;
|
|
case IO_XFER_ERROR_PHY_NOT_READY:
|
|
case IO_XFER_ERROR_PHY_NOT_READY:
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
|
|
pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
|
|
@@ -1800,10 +2010,8 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
|
|
case IO_XFER_OPEN_RETRY_TIMEOUT:
|
|
case IO_XFER_OPEN_RETRY_TIMEOUT:
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
|
|
pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
|
|
- ts->resp = SAS_TASK_COMPLETE;
|
|
|
|
- ts->stat = SAS_OPEN_REJECT;
|
|
|
|
- ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
|
|
|
|
- break;
|
|
|
|
|
|
+ pm8001_handle_event(pm8001_ha, t, IO_XFER_OPEN_RETRY_TIMEOUT);
|
|
|
|
+ return;
|
|
case IO_XFER_ERROR_UNEXPECTED_PHASE:
|
|
case IO_XFER_ERROR_UNEXPECTED_PHASE:
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n"));
|
|
pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n"));
|
|
@@ -1877,7 +2085,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
{
|
|
{
|
|
struct sas_task *t;
|
|
struct sas_task *t;
|
|
struct pm8001_ccb_info *ccb;
|
|
struct pm8001_ccb_info *ccb;
|
|
- unsigned long flags = 0;
|
|
|
|
u32 param;
|
|
u32 param;
|
|
u32 status;
|
|
u32 status;
|
|
u32 tag;
|
|
u32 tag;
|
|
@@ -2016,9 +2223,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
ts->stat = SAS_QUEUE_FULL;
|
|
ts->stat = SAS_QUEUE_FULL;
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
mb();/*in order to force CPU ordering*/
|
|
mb();/*in order to force CPU ordering*/
|
|
- spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&pm8001_ha->lock);
|
|
t->task_done(t);
|
|
t->task_done(t);
|
|
- spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_lock_irq(&pm8001_ha->lock);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -2036,9 +2243,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
ts->stat = SAS_QUEUE_FULL;
|
|
ts->stat = SAS_QUEUE_FULL;
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
mb();/*ditto*/
|
|
mb();/*ditto*/
|
|
- spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&pm8001_ha->lock);
|
|
t->task_done(t);
|
|
t->task_done(t);
|
|
- spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_lock_irq(&pm8001_ha->lock);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -2064,9 +2271,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
ts->stat = SAS_QUEUE_FULL;
|
|
ts->stat = SAS_QUEUE_FULL;
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
mb();/* ditto*/
|
|
mb();/* ditto*/
|
|
- spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&pm8001_ha->lock);
|
|
t->task_done(t);
|
|
t->task_done(t);
|
|
- spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_lock_irq(&pm8001_ha->lock);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -2131,9 +2338,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
ts->stat = SAS_QUEUE_FULL;
|
|
ts->stat = SAS_QUEUE_FULL;
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
mb();/*ditto*/
|
|
mb();/*ditto*/
|
|
- spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&pm8001_ha->lock);
|
|
t->task_done(t);
|
|
t->task_done(t);
|
|
- spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_lock_irq(&pm8001_ha->lock);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -2155,9 +2362,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
ts->stat = SAS_QUEUE_FULL;
|
|
ts->stat = SAS_QUEUE_FULL;
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
mb();/*ditto*/
|
|
mb();/*ditto*/
|
|
- spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&pm8001_ha->lock);
|
|
t->task_done(t);
|
|
t->task_done(t);
|
|
- spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_lock_irq(&pm8001_ha->lock);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -2175,31 +2382,31 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
ts->stat = SAS_DEV_NO_RESPONSE;
|
|
ts->stat = SAS_DEV_NO_RESPONSE;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- spin_lock_irqsave(&t->task_state_lock, flags);
|
|
|
|
|
|
+ spin_lock_irq(&t->task_state_lock);
|
|
t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
|
|
t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
|
|
t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
|
|
t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
|
|
t->task_state_flags |= SAS_TASK_STATE_DONE;
|
|
t->task_state_flags |= SAS_TASK_STATE_DONE;
|
|
if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
|
|
if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
|
|
- spin_unlock_irqrestore(&t->task_state_lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&t->task_state_lock);
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
pm8001_printk("task 0x%p done with io_status 0x%x"
|
|
pm8001_printk("task 0x%p done with io_status 0x%x"
|
|
" resp 0x%x stat 0x%x but aborted by upper layer!\n",
|
|
" resp 0x%x stat 0x%x but aborted by upper layer!\n",
|
|
t, status, ts->resp, ts->stat));
|
|
t, status, ts->resp, ts->stat));
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
} else if (t->uldd_task) {
|
|
} else if (t->uldd_task) {
|
|
- spin_unlock_irqrestore(&t->task_state_lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&t->task_state_lock);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
mb();/* ditto */
|
|
mb();/* ditto */
|
|
- spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&pm8001_ha->lock);
|
|
t->task_done(t);
|
|
t->task_done(t);
|
|
- spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_lock_irq(&pm8001_ha->lock);
|
|
} else if (!t->uldd_task) {
|
|
} else if (!t->uldd_task) {
|
|
- spin_unlock_irqrestore(&t->task_state_lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&t->task_state_lock);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
mb();/*ditto*/
|
|
mb();/*ditto*/
|
|
- spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&pm8001_ha->lock);
|
|
t->task_done(t);
|
|
t->task_done(t);
|
|
- spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_lock_irq(&pm8001_ha->lock);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2207,7 +2414,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
|
|
static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
|
|
{
|
|
{
|
|
struct sas_task *t;
|
|
struct sas_task *t;
|
|
- unsigned long flags = 0;
|
|
|
|
struct task_status_struct *ts;
|
|
struct task_status_struct *ts;
|
|
struct pm8001_ccb_info *ccb;
|
|
struct pm8001_ccb_info *ccb;
|
|
struct pm8001_device *pm8001_dev;
|
|
struct pm8001_device *pm8001_dev;
|
|
@@ -2287,9 +2493,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
|
|
ts->stat = SAS_QUEUE_FULL;
|
|
ts->stat = SAS_QUEUE_FULL;
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
mb();/*ditto*/
|
|
mb();/*ditto*/
|
|
- spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&pm8001_ha->lock);
|
|
t->task_done(t);
|
|
t->task_done(t);
|
|
- spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_lock_irq(&pm8001_ha->lock);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -2387,31 +2593,31 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
|
|
ts->stat = SAS_OPEN_TO;
|
|
ts->stat = SAS_OPEN_TO;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- spin_lock_irqsave(&t->task_state_lock, flags);
|
|
|
|
|
|
+ spin_lock_irq(&t->task_state_lock);
|
|
t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
|
|
t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
|
|
t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
|
|
t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
|
|
t->task_state_flags |= SAS_TASK_STATE_DONE;
|
|
t->task_state_flags |= SAS_TASK_STATE_DONE;
|
|
if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
|
|
if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
|
|
- spin_unlock_irqrestore(&t->task_state_lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&t->task_state_lock);
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
PM8001_FAIL_DBG(pm8001_ha,
|
|
pm8001_printk("task 0x%p done with io_status 0x%x"
|
|
pm8001_printk("task 0x%p done with io_status 0x%x"
|
|
" resp 0x%x stat 0x%x but aborted by upper layer!\n",
|
|
" resp 0x%x stat 0x%x but aborted by upper layer!\n",
|
|
t, event, ts->resp, ts->stat));
|
|
t, event, ts->resp, ts->stat));
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
} else if (t->uldd_task) {
|
|
} else if (t->uldd_task) {
|
|
- spin_unlock_irqrestore(&t->task_state_lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&t->task_state_lock);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
mb();/* ditto */
|
|
mb();/* ditto */
|
|
- spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&pm8001_ha->lock);
|
|
t->task_done(t);
|
|
t->task_done(t);
|
|
- spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_lock_irq(&pm8001_ha->lock);
|
|
} else if (!t->uldd_task) {
|
|
} else if (!t->uldd_task) {
|
|
- spin_unlock_irqrestore(&t->task_state_lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&t->task_state_lock);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
mb();/*ditto*/
|
|
mb();/*ditto*/
|
|
- spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_unlock_irq(&pm8001_ha->lock);
|
|
t->task_done(t);
|
|
t->task_done(t);
|
|
- spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
|
|
+ spin_lock_irq(&pm8001_ha->lock);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2857,7 +3063,7 @@ static void pm8001_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha,
|
|
|
|
|
|
memset((u8 *)&payload, 0, sizeof(payload));
|
|
memset((u8 *)&payload, 0, sizeof(payload));
|
|
circularQ = &pm8001_ha->inbnd_q_tbl[Qnum];
|
|
circularQ = &pm8001_ha->inbnd_q_tbl[Qnum];
|
|
- payload.tag = 1;
|
|
|
|
|
|
+ payload.tag = cpu_to_le32(1);
|
|
payload.sea_phyid_portid = cpu_to_le32(((SEA & 0xFFFF) << 8) |
|
|
payload.sea_phyid_portid = cpu_to_le32(((SEA & 0xFFFF) << 8) |
|
|
((phyId & 0x0F) << 4) | (port_id & 0x0F));
|
|
((phyId & 0x0F) << 4) | (port_id & 0x0F));
|
|
payload.param0 = cpu_to_le32(param0);
|
|
payload.param0 = cpu_to_le32(param0);
|
|
@@ -2929,9 +3135,9 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
phy->phy_type |= PORT_TYPE_SAS;
|
|
phy->phy_type |= PORT_TYPE_SAS;
|
|
phy->identify.device_type = deviceType;
|
|
phy->identify.device_type = deviceType;
|
|
phy->phy_attached = 1;
|
|
phy->phy_attached = 1;
|
|
- if (phy->identify.device_type == SAS_END_DEV)
|
|
|
|
|
|
+ if (phy->identify.device_type == SAS_END_DEVICE)
|
|
phy->identify.target_port_protocols = SAS_PROTOCOL_SSP;
|
|
phy->identify.target_port_protocols = SAS_PROTOCOL_SSP;
|
|
- else if (phy->identify.device_type != NO_DEVICE)
|
|
|
|
|
|
+ else if (phy->identify.device_type != SAS_PHY_UNUSED)
|
|
phy->identify.target_port_protocols = SAS_PROTOCOL_SMP;
|
|
phy->identify.target_port_protocols = SAS_PROTOCOL_SMP;
|
|
phy->sas_phy.oob_mode = SAS_OOB_MODE;
|
|
phy->sas_phy.oob_mode = SAS_OOB_MODE;
|
|
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
|
|
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
|
|
@@ -3075,7 +3281,7 @@ static int mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
(struct dev_reg_resp *)(piomb + 4);
|
|
(struct dev_reg_resp *)(piomb + 4);
|
|
|
|
|
|
htag = le32_to_cpu(registerRespPayload->tag);
|
|
htag = le32_to_cpu(registerRespPayload->tag);
|
|
- ccb = &pm8001_ha->ccb_info[registerRespPayload->tag];
|
|
|
|
|
|
+ ccb = &pm8001_ha->ccb_info[htag];
|
|
pm8001_dev = ccb->device;
|
|
pm8001_dev = ccb->device;
|
|
status = le32_to_cpu(registerRespPayload->status);
|
|
status = le32_to_cpu(registerRespPayload->status);
|
|
device_id = le32_to_cpu(registerRespPayload->device_id);
|
|
device_id = le32_to_cpu(registerRespPayload->device_id);
|
|
@@ -3149,7 +3355,7 @@ mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
struct fw_control_ex fw_control_context;
|
|
struct fw_control_ex fw_control_context;
|
|
struct fw_flash_Update_resp *ppayload =
|
|
struct fw_flash_Update_resp *ppayload =
|
|
(struct fw_flash_Update_resp *)(piomb + 4);
|
|
(struct fw_flash_Update_resp *)(piomb + 4);
|
|
- u32 tag = le32_to_cpu(ppayload->tag);
|
|
|
|
|
|
+ u32 tag = ppayload->tag;
|
|
struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];
|
|
struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];
|
|
status = le32_to_cpu(ppayload->status);
|
|
status = le32_to_cpu(ppayload->status);
|
|
memcpy(&fw_control_context,
|
|
memcpy(&fw_control_context,
|
|
@@ -3238,13 +3444,12 @@ mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
|
|
|
|
struct task_abort_resp *pPayload =
|
|
struct task_abort_resp *pPayload =
|
|
(struct task_abort_resp *)(piomb + 4);
|
|
(struct task_abort_resp *)(piomb + 4);
|
|
- ccb = &pm8001_ha->ccb_info[pPayload->tag];
|
|
|
|
- t = ccb->task;
|
|
|
|
-
|
|
|
|
|
|
|
|
status = le32_to_cpu(pPayload->status);
|
|
status = le32_to_cpu(pPayload->status);
|
|
tag = le32_to_cpu(pPayload->tag);
|
|
tag = le32_to_cpu(pPayload->tag);
|
|
scp = le32_to_cpu(pPayload->scp);
|
|
scp = le32_to_cpu(pPayload->scp);
|
|
|
|
+ ccb = &pm8001_ha->ccb_info[tag];
|
|
|
|
+ t = ccb->task;
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
PM8001_IO_DBG(pm8001_ha,
|
|
pm8001_printk(" status = 0x%x\n", status));
|
|
pm8001_printk(" status = 0x%x\n", status));
|
|
if (t == NULL)
|
|
if (t == NULL)
|
|
@@ -3270,7 +3475,7 @@ mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
|
|
t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
|
|
t->task_state_flags |= SAS_TASK_STATE_DONE;
|
|
t->task_state_flags |= SAS_TASK_STATE_DONE;
|
|
spin_unlock_irqrestore(&t->task_state_lock, flags);
|
|
spin_unlock_irqrestore(&t->task_state_lock, flags);
|
|
- pm8001_ccb_task_free(pm8001_ha, t, ccb, pPayload->tag);
|
|
|
|
|
|
+ pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
|
|
mb();
|
|
mb();
|
|
t->task_done(t);
|
|
t->task_done(t);
|
|
return 0;
|
|
return 0;
|
|
@@ -3497,7 +3702,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
|
static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|
{
|
|
{
|
|
u32 pHeader = (u32)*(u32 *)piomb;
|
|
u32 pHeader = (u32)*(u32 *)piomb;
|
|
- u8 opc = (u8)((le32_to_cpu(pHeader)) & 0xFFF);
|
|
|
|
|
|
+ u8 opc = (u8)(pHeader & 0xFFF);
|
|
|
|
|
|
PM8001_MSG_DBG(pm8001_ha, pm8001_printk("process_one_iomb:"));
|
|
PM8001_MSG_DBG(pm8001_ha, pm8001_printk("process_one_iomb:"));
|
|
|
|
|
|
@@ -3664,9 +3869,11 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha)
|
|
{
|
|
{
|
|
struct outbound_queue_table *circularQ;
|
|
struct outbound_queue_table *circularQ;
|
|
void *pMsg1 = NULL;
|
|
void *pMsg1 = NULL;
|
|
- u8 bc = 0;
|
|
|
|
|
|
+ u8 uninitialized_var(bc);
|
|
u32 ret = MPI_IO_STATUS_FAIL;
|
|
u32 ret = MPI_IO_STATUS_FAIL;
|
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
|
|
+ spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
circularQ = &pm8001_ha->outbnd_q_tbl[0];
|
|
circularQ = &pm8001_ha->outbnd_q_tbl[0];
|
|
do {
|
|
do {
|
|
ret = mpi_msg_consume(pm8001_ha, circularQ, &pMsg1, &bc);
|
|
ret = mpi_msg_consume(pm8001_ha, circularQ, &pMsg1, &bc);
|
|
@@ -3677,16 +3884,16 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha)
|
|
mpi_msg_free_set(pm8001_ha, pMsg1, circularQ, bc);
|
|
mpi_msg_free_set(pm8001_ha, pMsg1, circularQ, bc);
|
|
}
|
|
}
|
|
if (MPI_IO_STATUS_BUSY == ret) {
|
|
if (MPI_IO_STATUS_BUSY == ret) {
|
|
- u32 producer_idx;
|
|
|
|
/* Update the producer index from SPC */
|
|
/* Update the producer index from SPC */
|
|
- producer_idx = pm8001_read_32(circularQ->pi_virt);
|
|
|
|
- circularQ->producer_index = cpu_to_le32(producer_idx);
|
|
|
|
- if (circularQ->producer_index ==
|
|
|
|
|
|
+ circularQ->producer_index =
|
|
|
|
+ cpu_to_le32(pm8001_read_32(circularQ->pi_virt));
|
|
|
|
+ if (le32_to_cpu(circularQ->producer_index) ==
|
|
circularQ->consumer_idx)
|
|
circularQ->consumer_idx)
|
|
/* OQ is empty */
|
|
/* OQ is empty */
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
} while (1);
|
|
} while (1);
|
|
|
|
+ spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3712,9 +3919,9 @@ pm8001_chip_make_sg(struct scatterlist *scatter, int nr, void *prd)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static void build_smp_cmd(u32 deviceID, u32 hTag, struct smp_req *psmp_cmd)
|
|
|
|
|
|
+static void build_smp_cmd(u32 deviceID, __le32 hTag, struct smp_req *psmp_cmd)
|
|
{
|
|
{
|
|
- psmp_cmd->tag = cpu_to_le32(hTag);
|
|
|
|
|
|
+ psmp_cmd->tag = hTag;
|
|
psmp_cmd->device_id = cpu_to_le32(deviceID);
|
|
psmp_cmd->device_id = cpu_to_le32(deviceID);
|
|
psmp_cmd->len_ip_ir = cpu_to_le32(1|(1 << 1));
|
|
psmp_cmd->len_ip_ir = cpu_to_le32(1|(1 << 1));
|
|
}
|
|
}
|
|
@@ -3798,7 +4005,7 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
|
|
struct ssp_ini_io_start_req ssp_cmd;
|
|
struct ssp_ini_io_start_req ssp_cmd;
|
|
u32 tag = ccb->ccb_tag;
|
|
u32 tag = ccb->ccb_tag;
|
|
int ret;
|
|
int ret;
|
|
- __le64 phys_addr;
|
|
|
|
|
|
+ u64 phys_addr;
|
|
struct inbound_queue_table *circularQ;
|
|
struct inbound_queue_table *circularQ;
|
|
u32 opc = OPC_INB_SSPINIIOSTART;
|
|
u32 opc = OPC_INB_SSPINIIOSTART;
|
|
memset(&ssp_cmd, 0, sizeof(ssp_cmd));
|
|
memset(&ssp_cmd, 0, sizeof(ssp_cmd));
|
|
@@ -3819,15 +4026,15 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
|
|
/* fill in PRD (scatter/gather) table, if any */
|
|
/* fill in PRD (scatter/gather) table, if any */
|
|
if (task->num_scatter > 1) {
|
|
if (task->num_scatter > 1) {
|
|
pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd);
|
|
pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd);
|
|
- phys_addr = cpu_to_le64(ccb->ccb_dma_handle +
|
|
|
|
- offsetof(struct pm8001_ccb_info, buf_prd[0]));
|
|
|
|
- ssp_cmd.addr_low = lower_32_bits(phys_addr);
|
|
|
|
- ssp_cmd.addr_high = upper_32_bits(phys_addr);
|
|
|
|
|
|
+ phys_addr = ccb->ccb_dma_handle +
|
|
|
|
+ offsetof(struct pm8001_ccb_info, buf_prd[0]);
|
|
|
|
+ ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(phys_addr));
|
|
|
|
+ ssp_cmd.addr_high = cpu_to_le32(upper_32_bits(phys_addr));
|
|
ssp_cmd.esgl = cpu_to_le32(1<<31);
|
|
ssp_cmd.esgl = cpu_to_le32(1<<31);
|
|
} else if (task->num_scatter == 1) {
|
|
} else if (task->num_scatter == 1) {
|
|
- __le64 dma_addr = cpu_to_le64(sg_dma_address(task->scatter));
|
|
|
|
- ssp_cmd.addr_low = lower_32_bits(dma_addr);
|
|
|
|
- ssp_cmd.addr_high = upper_32_bits(dma_addr);
|
|
|
|
|
|
+ u64 dma_addr = sg_dma_address(task->scatter);
|
|
|
|
+ ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(dma_addr));
|
|
|
|
+ ssp_cmd.addr_high = cpu_to_le32(upper_32_bits(dma_addr));
|
|
ssp_cmd.len = cpu_to_le32(task->total_xfer_len);
|
|
ssp_cmd.len = cpu_to_le32(task->total_xfer_len);
|
|
ssp_cmd.esgl = 0;
|
|
ssp_cmd.esgl = 0;
|
|
} else if (task->num_scatter == 0) {
|
|
} else if (task->num_scatter == 0) {
|
|
@@ -3850,7 +4057,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
|
|
int ret;
|
|
int ret;
|
|
struct sata_start_req sata_cmd;
|
|
struct sata_start_req sata_cmd;
|
|
u32 hdr_tag, ncg_tag = 0;
|
|
u32 hdr_tag, ncg_tag = 0;
|
|
- __le64 phys_addr;
|
|
|
|
|
|
+ u64 phys_addr;
|
|
u32 ATAP = 0x0;
|
|
u32 ATAP = 0x0;
|
|
u32 dir;
|
|
u32 dir;
|
|
struct inbound_queue_table *circularQ;
|
|
struct inbound_queue_table *circularQ;
|
|
@@ -3889,13 +4096,13 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
|
|
/* fill in PRD (scatter/gather) table, if any */
|
|
/* fill in PRD (scatter/gather) table, if any */
|
|
if (task->num_scatter > 1) {
|
|
if (task->num_scatter > 1) {
|
|
pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd);
|
|
pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd);
|
|
- phys_addr = cpu_to_le64(ccb->ccb_dma_handle +
|
|
|
|
- offsetof(struct pm8001_ccb_info, buf_prd[0]));
|
|
|
|
|
|
+ phys_addr = ccb->ccb_dma_handle +
|
|
|
|
+ offsetof(struct pm8001_ccb_info, buf_prd[0]);
|
|
sata_cmd.addr_low = lower_32_bits(phys_addr);
|
|
sata_cmd.addr_low = lower_32_bits(phys_addr);
|
|
sata_cmd.addr_high = upper_32_bits(phys_addr);
|
|
sata_cmd.addr_high = upper_32_bits(phys_addr);
|
|
sata_cmd.esgl = cpu_to_le32(1 << 31);
|
|
sata_cmd.esgl = cpu_to_le32(1 << 31);
|
|
} else if (task->num_scatter == 1) {
|
|
} else if (task->num_scatter == 1) {
|
|
- __le64 dma_addr = cpu_to_le64(sg_dma_address(task->scatter));
|
|
|
|
|
|
+ u64 dma_addr = sg_dma_address(task->scatter);
|
|
sata_cmd.addr_low = lower_32_bits(dma_addr);
|
|
sata_cmd.addr_low = lower_32_bits(dma_addr);
|
|
sata_cmd.addr_high = upper_32_bits(dma_addr);
|
|
sata_cmd.addr_high = upper_32_bits(dma_addr);
|
|
sata_cmd.len = cpu_to_le32(task->total_xfer_len);
|
|
sata_cmd.len = cpu_to_le32(task->total_xfer_len);
|
|
@@ -4039,7 +4246,7 @@ static int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha,
|
|
|
|
|
|
circularQ = &pm8001_ha->inbnd_q_tbl[0];
|
|
circularQ = &pm8001_ha->inbnd_q_tbl[0];
|
|
memset(&payload, 0, sizeof(payload));
|
|
memset(&payload, 0, sizeof(payload));
|
|
- payload.tag = 1;
|
|
|
|
|
|
+ payload.tag = cpu_to_le32(1);
|
|
payload.device_id = cpu_to_le32(device_id);
|
|
payload.device_id = cpu_to_le32(device_id);
|
|
PM8001_MSG_DBG(pm8001_ha,
|
|
PM8001_MSG_DBG(pm8001_ha,
|
|
pm8001_printk("unregister device device_id = %d\n", device_id));
|
|
pm8001_printk("unregister device device_id = %d\n", device_id));
|
|
@@ -4063,7 +4270,7 @@ static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
|
|
u32 opc = OPC_INB_LOCAL_PHY_CONTROL;
|
|
u32 opc = OPC_INB_LOCAL_PHY_CONTROL;
|
|
memset(&payload, 0, sizeof(payload));
|
|
memset(&payload, 0, sizeof(payload));
|
|
circularQ = &pm8001_ha->inbnd_q_tbl[0];
|
|
circularQ = &pm8001_ha->inbnd_q_tbl[0];
|
|
- payload.tag = 1;
|
|
|
|
|
|
+ payload.tag = cpu_to_le32(1);
|
|
payload.phyop_phyid =
|
|
payload.phyop_phyid =
|
|
cpu_to_le32(((phy_op & 0xff) << 8) | (phyId & 0x0F));
|
|
cpu_to_le32(((phy_op & 0xff) << 8) | (phyId & 0x0F));
|
|
ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload);
|
|
ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload);
|
|
@@ -4092,12 +4299,9 @@ static u32 pm8001_chip_is_our_interupt(struct pm8001_hba_info *pm8001_ha)
|
|
static irqreturn_t
|
|
static irqreturn_t
|
|
pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha)
|
|
pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha)
|
|
{
|
|
{
|
|
- unsigned long flags;
|
|
|
|
- spin_lock_irqsave(&pm8001_ha->lock, flags);
|
|
|
|
pm8001_chip_interrupt_disable(pm8001_ha);
|
|
pm8001_chip_interrupt_disable(pm8001_ha);
|
|
process_oq(pm8001_ha);
|
|
process_oq(pm8001_ha);
|
|
pm8001_chip_interrupt_enable(pm8001_ha);
|
|
pm8001_chip_interrupt_enable(pm8001_ha);
|
|
- spin_unlock_irqrestore(&pm8001_ha->lock, flags);
|
|
|
|
return IRQ_HANDLED;
|
|
return IRQ_HANDLED;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -4360,8 +4564,10 @@ pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha,
|
|
payload.cur_image_offset = cpu_to_le32(info->cur_image_offset);
|
|
payload.cur_image_offset = cpu_to_le32(info->cur_image_offset);
|
|
payload.total_image_len = cpu_to_le32(info->total_image_len);
|
|
payload.total_image_len = cpu_to_le32(info->total_image_len);
|
|
payload.len = info->sgl.im_len.len ;
|
|
payload.len = info->sgl.im_len.len ;
|
|
- payload.sgl_addr_lo = lower_32_bits(info->sgl.addr);
|
|
|
|
- payload.sgl_addr_hi = upper_32_bits(info->sgl.addr);
|
|
|
|
|
|
+ payload.sgl_addr_lo =
|
|
|
|
+ cpu_to_le32(lower_32_bits(le64_to_cpu(info->sgl.addr)));
|
|
|
|
+ payload.sgl_addr_hi =
|
|
|
|
+ cpu_to_le32(upper_32_bits(le64_to_cpu(info->sgl.addr)));
|
|
ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload);
|
|
ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|