aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pm8001
diff options
context:
space:
mode:
authorMark Salyzyn <mark_salyzyn@xyratex.com>2012-01-17 09:18:57 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 09:08:51 -0500
commitd95d00016f8f51dc502cadb263d861bd8c0212bb (patch)
treeaa60333c6d9aa97f3dc1f32f0fce3f3f08baa939 /drivers/scsi/pm8001
parent5c4fb76af31e9dabcd132a0e69ed3799df1304c3 (diff)
[SCSI] pm8001: Add FUNC_GET_EVENTS
Jack noticed I dropped a patch fragment associated with a flags automatic variable in mpi_set_phys_g3_with_ssc (ooops) and that the pre-emptive locking that piggy-backed this patch was not in-fact necessary because of underlying atomic accesses to the hardware. Here is the updated patch fixing these two issues. The pm8001 driver is missing the FUNC_GET_EVENTS handler in the phy control function. Since the pm8001_bar4_shift function was not designed to be called at runtime, added locking surrounding the adjustment for all accesses. Signed-off-by: Mark Salyzyn <mark_salyzyn@xyratex.com> Acked-by: Jack Wang <jack_wang@usish.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/pm8001')
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c85
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.c24
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.h1
3 files changed, 83 insertions, 27 deletions
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index b7b92f7be2aa..f3c44b96c1c9 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -338,26 +338,25 @@ update_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha, int number)
338} 338}
339 339
340/** 340/**
341 * bar4_shift - function is called to shift BAR base address 341 * pm8001_bar4_shift - function is called to shift BAR base address
342 * @pm8001_ha : our hba card information 342 * @pm8001_ha : our hba card infomation
343 * @shiftValue : shifting value in memory bar. 343 * @shiftValue : shifting value in memory bar.
344 */ 344 */
345static int bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue) 345int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue)
346{ 346{
347 u32 regVal; 347 u32 regVal;
348 u32 max_wait_count; 348 unsigned long start;
349 349
350 /* program the inbound AXI translation Lower Address */ 350 /* program the inbound AXI translation Lower Address */
351 pm8001_cw32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW, shiftValue); 351 pm8001_cw32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW, shiftValue);
352 352
353 /* confirm the setting is written */ 353 /* confirm the setting is written */
354 max_wait_count = 1 * 1000 * 1000; /* 1 sec */ 354 start = jiffies + HZ; /* 1 sec */
355 do { 355 do {
356 udelay(1);
357 regVal = pm8001_cr32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW); 356 regVal = pm8001_cr32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW);
358 } while ((regVal != shiftValue) && (--max_wait_count)); 357 } while ((regVal != shiftValue) && time_before(jiffies, start));
359 358
360 if (!max_wait_count) { 359 if (regVal != shiftValue) {
361 PM8001_INIT_DBG(pm8001_ha, 360 PM8001_INIT_DBG(pm8001_ha,
362 pm8001_printk("TIMEOUT:SPC_IBW_AXI_TRANSLATION_LOW" 361 pm8001_printk("TIMEOUT:SPC_IBW_AXI_TRANSLATION_LOW"
363 " = 0x%x\n", regVal)); 362 " = 0x%x\n", regVal));
@@ -375,6 +374,7 @@ static void __devinit
375mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit) 374mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit)
376{ 375{
377 u32 value, offset, i; 376 u32 value, offset, i;
377 unsigned long flags;
378 378
379#define SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR 0x00030000 379#define SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR 0x00030000
380#define SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR 0x00040000 380#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)
388 * Using shifted destination address 0x3_0000:0x1074 + 0x4000*N (N=0:3) 388 * Using shifted destination address 0x3_0000:0x1074 + 0x4000*N (N=0:3)
389 * Using shifted destination address 0x4_0000:0x1074 + 0x4000*(N-4) (N=4:7) 389 * Using shifted destination address 0x4_0000:0x1074 + 0x4000*(N-4) (N=4:7)
390 */ 390 */
391 if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR)) 391 spin_lock_irqsave(&pm8001_ha->lock, flags);
392 if (-1 == pm8001_bar4_shift(pm8001_ha,
393 SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR)) {
394 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
392 return; 395 return;
396 }
393 397
394 for (i = 0; i < 4; i++) { 398 for (i = 0; i < 4; i++) {
395 offset = SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET + 0x4000 * i; 399 offset = SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET + 0x4000 * i;
396 pm8001_cw32(pm8001_ha, 2, offset, 0x80001501); 400 pm8001_cw32(pm8001_ha, 2, offset, 0x80001501);
397 } 401 }
398 /* shift membase 3 for SAS2_SETTINGS_LOCAL_PHY 4 - 7 */ 402 /* shift membase 3 for SAS2_SETTINGS_LOCAL_PHY 4 - 7 */
399 if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR)) 403 if (-1 == pm8001_bar4_shift(pm8001_ha,
404 SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR)) {
405 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
400 return; 406 return;
407 }
401 for (i = 4; i < 8; i++) { 408 for (i = 4; i < 8; i++) {
402 offset = SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET + 0x4000 * (i-4); 409 offset = SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET + 0x4000 * (i-4);
403 pm8001_cw32(pm8001_ha, 2, offset, 0x80001501); 410 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)
421 pm8001_cw32(pm8001_ha, 2, 0xd8, 0x8000C016); 428 pm8001_cw32(pm8001_ha, 2, 0xd8, 0x8000C016);
422 429
423 /*set the shifted destination address to 0x0 to avoid error operation */ 430 /*set the shifted destination address to 0x0 to avoid error operation */
424 bar4_shift(pm8001_ha, 0x0); 431 pm8001_bar4_shift(pm8001_ha, 0x0);
432 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
425 return; 433 return;
426} 434}
427 435
@@ -437,6 +445,7 @@ mpi_set_open_retry_interval_reg(struct pm8001_hba_info *pm8001_ha,
437 u32 offset; 445 u32 offset;
438 u32 value; 446 u32 value;
439 u32 i; 447 u32 i;
448 unsigned long flags;
440 449
441#define OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR 0x00030000 450#define OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR 0x00030000
442#define OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR 0x00040000 451#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,
445#define OPEN_RETRY_INTERVAL_REG_MASK 0x0000FFFF 454#define OPEN_RETRY_INTERVAL_REG_MASK 0x0000FFFF
446 455
447 value = interval & OPEN_RETRY_INTERVAL_REG_MASK; 456 value = interval & OPEN_RETRY_INTERVAL_REG_MASK;
457 spin_lock_irqsave(&pm8001_ha->lock, flags);
448 /* shift bar and set the OPEN_REJECT(RETRY) interval time of PHY 0 -3.*/ 458 /* shift bar and set the OPEN_REJECT(RETRY) interval time of PHY 0 -3.*/
449 if (-1 == bar4_shift(pm8001_ha, 459 if (-1 == pm8001_bar4_shift(pm8001_ha,
450 OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR)) 460 OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR)) {
461 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
451 return; 462 return;
463 }
452 for (i = 0; i < 4; i++) { 464 for (i = 0; i < 4; i++) {
453 offset = OPEN_RETRY_INTERVAL_PHY_0_3_OFFSET + 0x4000 * i; 465 offset = OPEN_RETRY_INTERVAL_PHY_0_3_OFFSET + 0x4000 * i;
454 pm8001_cw32(pm8001_ha, 2, offset, value); 466 pm8001_cw32(pm8001_ha, 2, offset, value);
455 } 467 }
456 468
457 if (-1 == bar4_shift(pm8001_ha, 469 if (-1 == pm8001_bar4_shift(pm8001_ha,
458 OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR)) 470 OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR)) {
471 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
459 return; 472 return;
473 }
460 for (i = 4; i < 8; i++) { 474 for (i = 4; i < 8; i++) {
461 offset = OPEN_RETRY_INTERVAL_PHY_4_7_OFFSET + 0x4000 * (i-4); 475 offset = OPEN_RETRY_INTERVAL_PHY_4_7_OFFSET + 0x4000 * (i-4);
462 pm8001_cw32(pm8001_ha, 2, offset, value); 476 pm8001_cw32(pm8001_ha, 2, offset, value);
463 } 477 }
464 /*set the shifted destination address to 0x0 to avoid error operation */ 478 /*set the shifted destination address to 0x0 to avoid error operation */
465 bar4_shift(pm8001_ha, 0x0); 479 pm8001_bar4_shift(pm8001_ha, 0x0);
480 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
466 return; 481 return;
467} 482}
468 483
@@ -688,8 +703,11 @@ static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha)
688 PM8001_INIT_DBG(pm8001_ha, 703 PM8001_INIT_DBG(pm8001_ha,
689 pm8001_printk("Firmware is ready for reset .\n")); 704 pm8001_printk("Firmware is ready for reset .\n"));
690 } else { 705 } else {
691 /* Trigger NMI twice via RB6 */ 706 unsigned long flags;
692 if (-1 == bar4_shift(pm8001_ha, RB6_ACCESS_REG)) { 707 /* Trigger NMI twice via RB6 */
708 spin_lock_irqsave(&pm8001_ha->lock, flags);
709 if (-1 == pm8001_bar4_shift(pm8001_ha, RB6_ACCESS_REG)) {
710 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
693 PM8001_FAIL_DBG(pm8001_ha, 711 PM8001_FAIL_DBG(pm8001_ha,
694 pm8001_printk("Shift Bar4 to 0x%x failed\n", 712 pm8001_printk("Shift Bar4 to 0x%x failed\n",
695 RB6_ACCESS_REG)); 713 RB6_ACCESS_REG));
@@ -715,8 +733,10 @@ static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha)
715 PM8001_FAIL_DBG(pm8001_ha, 733 PM8001_FAIL_DBG(pm8001_ha,
716 pm8001_printk("SCRATCH_PAD3 value = 0x%x\n", 734 pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
717 pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3))); 735 pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3)));
736 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
718 return -1; 737 return -1;
719 } 738 }
739 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
720 } 740 }
721 return 0; 741 return 0;
722} 742}
@@ -733,6 +753,7 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
733 u32 regVal, toggleVal; 753 u32 regVal, toggleVal;
734 u32 max_wait_count; 754 u32 max_wait_count;
735 u32 regVal1, regVal2, regVal3; 755 u32 regVal1, regVal2, regVal3;
756 unsigned long flags;
736 757
737 /* step1: Check FW is ready for soft reset */ 758 /* step1: Check FW is ready for soft reset */
738 if (soft_reset_ready_check(pm8001_ha) != 0) { 759 if (soft_reset_ready_check(pm8001_ha) != 0) {
@@ -743,7 +764,9 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
743 /* step 2: clear NMI status register on AAP1 and IOP, write the same 764 /* step 2: clear NMI status register on AAP1 and IOP, write the same
744 value to clear */ 765 value to clear */
745 /* map 0x60000 to BAR4(0x20), BAR2(win) */ 766 /* map 0x60000 to BAR4(0x20), BAR2(win) */
746 if (-1 == bar4_shift(pm8001_ha, MBIC_AAP1_ADDR_BASE)) { 767 spin_lock_irqsave(&pm8001_ha->lock, flags);
768 if (-1 == pm8001_bar4_shift(pm8001_ha, MBIC_AAP1_ADDR_BASE)) {
769 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
747 PM8001_FAIL_DBG(pm8001_ha, 770 PM8001_FAIL_DBG(pm8001_ha,
748 pm8001_printk("Shift Bar4 to 0x%x failed\n", 771 pm8001_printk("Shift Bar4 to 0x%x failed\n",
749 MBIC_AAP1_ADDR_BASE)); 772 MBIC_AAP1_ADDR_BASE));
@@ -754,7 +777,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
754 pm8001_printk("MBIC - NMI Enable VPE0 (IOP)= 0x%x\n", regVal)); 777 pm8001_printk("MBIC - NMI Enable VPE0 (IOP)= 0x%x\n", regVal));
755 pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP, 0x0); 778 pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP, 0x0);
756 /* map 0x70000 to BAR4(0x20), BAR2(win) */ 779 /* map 0x70000 to BAR4(0x20), BAR2(win) */
757 if (-1 == bar4_shift(pm8001_ha, MBIC_IOP_ADDR_BASE)) { 780 if (-1 == pm8001_bar4_shift(pm8001_ha, MBIC_IOP_ADDR_BASE)) {
781 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
758 PM8001_FAIL_DBG(pm8001_ha, 782 PM8001_FAIL_DBG(pm8001_ha,
759 pm8001_printk("Shift Bar4 to 0x%x failed\n", 783 pm8001_printk("Shift Bar4 to 0x%x failed\n",
760 MBIC_IOP_ADDR_BASE)); 784 MBIC_IOP_ADDR_BASE));
@@ -796,7 +820,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
796 820
797 /* read required registers for confirmming */ 821 /* read required registers for confirmming */
798 /* map 0x0700000 to BAR4(0x20), BAR2(win) */ 822 /* map 0x0700000 to BAR4(0x20), BAR2(win) */
799 if (-1 == bar4_shift(pm8001_ha, GSM_ADDR_BASE)) { 823 if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {
824 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
800 PM8001_FAIL_DBG(pm8001_ha, 825 PM8001_FAIL_DBG(pm8001_ha,
801 pm8001_printk("Shift Bar4 to 0x%x failed\n", 826 pm8001_printk("Shift Bar4 to 0x%x failed\n",
802 GSM_ADDR_BASE)); 827 GSM_ADDR_BASE));
@@ -862,7 +887,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
862 /* step 5: delay 10 usec */ 887 /* step 5: delay 10 usec */
863 udelay(10); 888 udelay(10);
864 /* step 5-b: set GPIO-0 output control to tristate anyway */ 889 /* step 5-b: set GPIO-0 output control to tristate anyway */
865 if (-1 == bar4_shift(pm8001_ha, GPIO_ADDR_BASE)) { 890 if (-1 == pm8001_bar4_shift(pm8001_ha, GPIO_ADDR_BASE)) {
891 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
866 PM8001_INIT_DBG(pm8001_ha, 892 PM8001_INIT_DBG(pm8001_ha,
867 pm8001_printk("Shift Bar4 to 0x%x failed\n", 893 pm8001_printk("Shift Bar4 to 0x%x failed\n",
868 GPIO_ADDR_BASE)); 894 GPIO_ADDR_BASE));
@@ -878,7 +904,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
878 904
879 /* Step 6: Reset the IOP and AAP1 */ 905 /* Step 6: Reset the IOP and AAP1 */
880 /* map 0x00000 to BAR4(0x20), BAR2(win) */ 906 /* map 0x00000 to BAR4(0x20), BAR2(win) */
881 if (-1 == bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) { 907 if (-1 == pm8001_bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {
908 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
882 PM8001_FAIL_DBG(pm8001_ha, 909 PM8001_FAIL_DBG(pm8001_ha,
883 pm8001_printk("SPC Shift Bar4 to 0x%x failed\n", 910 pm8001_printk("SPC Shift Bar4 to 0x%x failed\n",
884 SPC_TOP_LEVEL_ADDR_BASE)); 911 SPC_TOP_LEVEL_ADDR_BASE));
@@ -915,7 +942,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
915 942
916 /* step 11: reads and sets the GSM Configuration and Reset Register */ 943 /* step 11: reads and sets the GSM Configuration and Reset Register */
917 /* map 0x0700000 to BAR4(0x20), BAR2(win) */ 944 /* map 0x0700000 to BAR4(0x20), BAR2(win) */
918 if (-1 == bar4_shift(pm8001_ha, GSM_ADDR_BASE)) { 945 if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {
946 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
919 PM8001_FAIL_DBG(pm8001_ha, 947 PM8001_FAIL_DBG(pm8001_ha,
920 pm8001_printk("SPC Shift Bar4 to 0x%x failed\n", 948 pm8001_printk("SPC Shift Bar4 to 0x%x failed\n",
921 GSM_ADDR_BASE)); 949 GSM_ADDR_BASE));
@@ -968,7 +996,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
968 996
969 /* step 13: bring the IOP and AAP1 out of reset */ 997 /* step 13: bring the IOP and AAP1 out of reset */
970 /* map 0x00000 to BAR4(0x20), BAR2(win) */ 998 /* map 0x00000 to BAR4(0x20), BAR2(win) */
971 if (-1 == bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) { 999 if (-1 == pm8001_bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {
1000 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
972 PM8001_FAIL_DBG(pm8001_ha, 1001 PM8001_FAIL_DBG(pm8001_ha,
973 pm8001_printk("Shift Bar4 to 0x%x failed\n", 1002 pm8001_printk("Shift Bar4 to 0x%x failed\n",
974 SPC_TOP_LEVEL_ADDR_BASE)); 1003 SPC_TOP_LEVEL_ADDR_BASE));
@@ -1010,6 +1039,7 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
1010 pm8001_printk("SCRATCH_PAD3 value = 0x%x\n", 1039 pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
1011 pm8001_cr32(pm8001_ha, 0, 1040 pm8001_cr32(pm8001_ha, 0,
1012 MSGU_SCRATCH_PAD_3))); 1041 MSGU_SCRATCH_PAD_3)));
1042 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
1013 return -1; 1043 return -1;
1014 } 1044 }
1015 1045
@@ -1039,9 +1069,12 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
1039 pm8001_printk("SCRATCH_PAD3 value = 0x%x\n", 1069 pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
1040 pm8001_cr32(pm8001_ha, 0, 1070 pm8001_cr32(pm8001_ha, 0,
1041 MSGU_SCRATCH_PAD_3))); 1071 MSGU_SCRATCH_PAD_3)));
1072 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
1042 return -1; 1073 return -1;
1043 } 1074 }
1044 } 1075 }
1076 pm8001_bar4_shift(pm8001_ha, 0);
1077 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
1045 1078
1046 PM8001_INIT_DBG(pm8001_ha, 1079 PM8001_INIT_DBG(pm8001_ha,
1047 pm8001_printk("SPC soft reset Complete\n")); 1080 pm8001_printk("SPC soft reset Complete\n"));
@@ -1157,8 +1190,8 @@ pm8001_chip_msix_interrupt_disable(struct pm8001_hba_info *pm8001_ha,
1157 msi_index = int_vec_idx * MSIX_TABLE_ELEMENT_SIZE; 1190 msi_index = int_vec_idx * MSIX_TABLE_ELEMENT_SIZE;
1158 msi_index += MSIX_TABLE_BASE; 1191 msi_index += MSIX_TABLE_BASE;
1159 pm8001_cw32(pm8001_ha, 0, msi_index, MSIX_INTERRUPT_DISABLE); 1192 pm8001_cw32(pm8001_ha, 0, msi_index, MSIX_INTERRUPT_DISABLE);
1160
1161} 1193}
1194
1162/** 1195/**
1163 * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt 1196 * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt
1164 * @pm8001_ha: our hba card information 1197 * @pm8001_ha: our hba card information
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 7ae22a67bd31..ab0704e39040 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -166,6 +166,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
166 struct pm8001_hba_info *pm8001_ha = NULL; 166 struct pm8001_hba_info *pm8001_ha = NULL;
167 struct sas_phy_linkrates *rates; 167 struct sas_phy_linkrates *rates;
168 DECLARE_COMPLETION_ONSTACK(completion); 168 DECLARE_COMPLETION_ONSTACK(completion);
169 unsigned long flags;
169 pm8001_ha = sas_phy->ha->lldd_ha; 170 pm8001_ha = sas_phy->ha->lldd_ha;
170 pm8001_ha->phy[phy_id].enable_completion = &completion; 171 pm8001_ha->phy[phy_id].enable_completion = &completion;
171 switch (func) { 172 switch (func) {
@@ -209,8 +210,29 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
209 case PHY_FUNC_DISABLE: 210 case PHY_FUNC_DISABLE:
210 PM8001_CHIP_DISP->phy_stop_req(pm8001_ha, phy_id); 211 PM8001_CHIP_DISP->phy_stop_req(pm8001_ha, phy_id);
211 break; 212 break;
213 case PHY_FUNC_GET_EVENTS:
214 spin_lock_irqsave(&pm8001_ha->lock, flags);
215 if (-1 == pm8001_bar4_shift(pm8001_ha,
216 (phy_id < 4) ? 0x30000 : 0x40000)) {
217 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
218 return -EINVAL;
219 }
220 {
221 struct sas_phy *phy = sas_phy->phy;
222 uint32_t *qp = (uint32_t *)(((char *)
223 pm8001_ha->io_mem[2].memvirtaddr)
224 + 0x1034 + (0x4000 * (phy_id & 3)));
225
226 phy->invalid_dword_count = qp[0];
227 phy->running_disparity_error_count = qp[1];
228 phy->loss_of_dword_sync_count = qp[3];
229 phy->phy_reset_problem_count = qp[4];
230 }
231 pm8001_bar4_shift(pm8001_ha, 0);
232 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
233 return 0;
212 default: 234 default:
213 rc = -ENOSYS; 235 rc = -EOPNOTSUPP;
214 } 236 }
215 msleep(300); 237 msleep(300);
216 return rc; 238 return rc;
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 93959febe205..83a48f3247b8 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -488,6 +488,7 @@ int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr,
488 dma_addr_t *pphys_addr, u32 *pphys_addr_hi, u32 *pphys_addr_lo, 488 dma_addr_t *pphys_addr, u32 *pphys_addr_hi, u32 *pphys_addr_lo,
489 u32 mem_size, u32 align); 489 u32 mem_size, u32 align);
490 490
491int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue);
491 492
492/* ctl shared API */ 493/* ctl shared API */
493extern struct device_attribute *pm8001_host_attrs[]; 494extern struct device_attribute *pm8001_host_attrs[];