diff options
Diffstat (limited to 'drivers/scsi/pm8001/pm8001_hwi.c')
-rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.c | 434 |
1 files changed, 320 insertions, 114 deletions
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index e12c4f632a6..3619f6eeeed 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 | */ |
345 | static int bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue) | 345 | int 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 | |||
375 | mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit) | 374 | mpi_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 | ||
@@ -607,7 +622,8 @@ static int __devinit pm8001_chip_init(struct pm8001_hba_info *pm8001_ha) | |||
607 | update_inbnd_queue_table(pm8001_ha, 0); | 622 | update_inbnd_queue_table(pm8001_ha, 0); |
608 | update_outbnd_queue_table(pm8001_ha, 0); | 623 | update_outbnd_queue_table(pm8001_ha, 0); |
609 | mpi_set_phys_g3_with_ssc(pm8001_ha, 0); | 624 | mpi_set_phys_g3_with_ssc(pm8001_ha, 0); |
610 | mpi_set_open_retry_interval_reg(pm8001_ha, 7); | 625 | /* 7->130ms, 34->500ms, 119->1.5s */ |
626 | mpi_set_open_retry_interval_reg(pm8001_ha, 119); | ||
611 | /* notify firmware update finished and check initialization status */ | 627 | /* notify firmware update finished and check initialization status */ |
612 | if (0 == mpi_init_check(pm8001_ha)) { | 628 | if (0 == mpi_init_check(pm8001_ha)) { |
613 | PM8001_INIT_DBG(pm8001_ha, | 629 | PM8001_INIT_DBG(pm8001_ha, |
@@ -688,8 +704,11 @@ static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha) | |||
688 | PM8001_INIT_DBG(pm8001_ha, | 704 | PM8001_INIT_DBG(pm8001_ha, |
689 | pm8001_printk("Firmware is ready for reset .\n")); | 705 | pm8001_printk("Firmware is ready for reset .\n")); |
690 | } else { | 706 | } else { |
691 | /* Trigger NMI twice via RB6 */ | 707 | unsigned long flags; |
692 | if (-1 == bar4_shift(pm8001_ha, RB6_ACCESS_REG)) { | 708 | /* Trigger NMI twice via RB6 */ |
709 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
710 | if (-1 == pm8001_bar4_shift(pm8001_ha, RB6_ACCESS_REG)) { | ||
711 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
693 | PM8001_FAIL_DBG(pm8001_ha, | 712 | PM8001_FAIL_DBG(pm8001_ha, |
694 | pm8001_printk("Shift Bar4 to 0x%x failed\n", | 713 | pm8001_printk("Shift Bar4 to 0x%x failed\n", |
695 | RB6_ACCESS_REG)); | 714 | RB6_ACCESS_REG)); |
@@ -715,8 +734,10 @@ static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha) | |||
715 | PM8001_FAIL_DBG(pm8001_ha, | 734 | PM8001_FAIL_DBG(pm8001_ha, |
716 | pm8001_printk("SCRATCH_PAD3 value = 0x%x\n", | 735 | pm8001_printk("SCRATCH_PAD3 value = 0x%x\n", |
717 | pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3))); | 736 | pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3))); |
737 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
718 | return -1; | 738 | return -1; |
719 | } | 739 | } |
740 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
720 | } | 741 | } |
721 | return 0; | 742 | return 0; |
722 | } | 743 | } |
@@ -733,6 +754,7 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature) | |||
733 | u32 regVal, toggleVal; | 754 | u32 regVal, toggleVal; |
734 | u32 max_wait_count; | 755 | u32 max_wait_count; |
735 | u32 regVal1, regVal2, regVal3; | 756 | u32 regVal1, regVal2, regVal3; |
757 | unsigned long flags; | ||
736 | 758 | ||
737 | /* step1: Check FW is ready for soft reset */ | 759 | /* step1: Check FW is ready for soft reset */ |
738 | if (soft_reset_ready_check(pm8001_ha) != 0) { | 760 | if (soft_reset_ready_check(pm8001_ha) != 0) { |
@@ -743,7 +765,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 | 765 | /* step 2: clear NMI status register on AAP1 and IOP, write the same |
744 | value to clear */ | 766 | value to clear */ |
745 | /* map 0x60000 to BAR4(0x20), BAR2(win) */ | 767 | /* map 0x60000 to BAR4(0x20), BAR2(win) */ |
746 | if (-1 == bar4_shift(pm8001_ha, MBIC_AAP1_ADDR_BASE)) { | 768 | spin_lock_irqsave(&pm8001_ha->lock, flags); |
769 | if (-1 == pm8001_bar4_shift(pm8001_ha, MBIC_AAP1_ADDR_BASE)) { | ||
770 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
747 | PM8001_FAIL_DBG(pm8001_ha, | 771 | PM8001_FAIL_DBG(pm8001_ha, |
748 | pm8001_printk("Shift Bar4 to 0x%x failed\n", | 772 | pm8001_printk("Shift Bar4 to 0x%x failed\n", |
749 | MBIC_AAP1_ADDR_BASE)); | 773 | MBIC_AAP1_ADDR_BASE)); |
@@ -754,7 +778,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)); | 778 | pm8001_printk("MBIC - NMI Enable VPE0 (IOP)= 0x%x\n", regVal)); |
755 | pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP, 0x0); | 779 | pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP, 0x0); |
756 | /* map 0x70000 to BAR4(0x20), BAR2(win) */ | 780 | /* map 0x70000 to BAR4(0x20), BAR2(win) */ |
757 | if (-1 == bar4_shift(pm8001_ha, MBIC_IOP_ADDR_BASE)) { | 781 | if (-1 == pm8001_bar4_shift(pm8001_ha, MBIC_IOP_ADDR_BASE)) { |
782 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
758 | PM8001_FAIL_DBG(pm8001_ha, | 783 | PM8001_FAIL_DBG(pm8001_ha, |
759 | pm8001_printk("Shift Bar4 to 0x%x failed\n", | 784 | pm8001_printk("Shift Bar4 to 0x%x failed\n", |
760 | MBIC_IOP_ADDR_BASE)); | 785 | MBIC_IOP_ADDR_BASE)); |
@@ -796,7 +821,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature) | |||
796 | 821 | ||
797 | /* read required registers for confirmming */ | 822 | /* read required registers for confirmming */ |
798 | /* map 0x0700000 to BAR4(0x20), BAR2(win) */ | 823 | /* map 0x0700000 to BAR4(0x20), BAR2(win) */ |
799 | if (-1 == bar4_shift(pm8001_ha, GSM_ADDR_BASE)) { | 824 | if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_ADDR_BASE)) { |
825 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
800 | PM8001_FAIL_DBG(pm8001_ha, | 826 | PM8001_FAIL_DBG(pm8001_ha, |
801 | pm8001_printk("Shift Bar4 to 0x%x failed\n", | 827 | pm8001_printk("Shift Bar4 to 0x%x failed\n", |
802 | GSM_ADDR_BASE)); | 828 | GSM_ADDR_BASE)); |
@@ -862,7 +888,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature) | |||
862 | /* step 5: delay 10 usec */ | 888 | /* step 5: delay 10 usec */ |
863 | udelay(10); | 889 | udelay(10); |
864 | /* step 5-b: set GPIO-0 output control to tristate anyway */ | 890 | /* step 5-b: set GPIO-0 output control to tristate anyway */ |
865 | if (-1 == bar4_shift(pm8001_ha, GPIO_ADDR_BASE)) { | 891 | if (-1 == pm8001_bar4_shift(pm8001_ha, GPIO_ADDR_BASE)) { |
892 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
866 | PM8001_INIT_DBG(pm8001_ha, | 893 | PM8001_INIT_DBG(pm8001_ha, |
867 | pm8001_printk("Shift Bar4 to 0x%x failed\n", | 894 | pm8001_printk("Shift Bar4 to 0x%x failed\n", |
868 | GPIO_ADDR_BASE)); | 895 | GPIO_ADDR_BASE)); |
@@ -878,7 +905,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature) | |||
878 | 905 | ||
879 | /* Step 6: Reset the IOP and AAP1 */ | 906 | /* Step 6: Reset the IOP and AAP1 */ |
880 | /* map 0x00000 to BAR4(0x20), BAR2(win) */ | 907 | /* map 0x00000 to BAR4(0x20), BAR2(win) */ |
881 | if (-1 == bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) { | 908 | if (-1 == pm8001_bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) { |
909 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
882 | PM8001_FAIL_DBG(pm8001_ha, | 910 | PM8001_FAIL_DBG(pm8001_ha, |
883 | pm8001_printk("SPC Shift Bar4 to 0x%x failed\n", | 911 | pm8001_printk("SPC Shift Bar4 to 0x%x failed\n", |
884 | SPC_TOP_LEVEL_ADDR_BASE)); | 912 | SPC_TOP_LEVEL_ADDR_BASE)); |
@@ -915,7 +943,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature) | |||
915 | 943 | ||
916 | /* step 11: reads and sets the GSM Configuration and Reset Register */ | 944 | /* step 11: reads and sets the GSM Configuration and Reset Register */ |
917 | /* map 0x0700000 to BAR4(0x20), BAR2(win) */ | 945 | /* map 0x0700000 to BAR4(0x20), BAR2(win) */ |
918 | if (-1 == bar4_shift(pm8001_ha, GSM_ADDR_BASE)) { | 946 | if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_ADDR_BASE)) { |
947 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
919 | PM8001_FAIL_DBG(pm8001_ha, | 948 | PM8001_FAIL_DBG(pm8001_ha, |
920 | pm8001_printk("SPC Shift Bar4 to 0x%x failed\n", | 949 | pm8001_printk("SPC Shift Bar4 to 0x%x failed\n", |
921 | GSM_ADDR_BASE)); | 950 | GSM_ADDR_BASE)); |
@@ -968,7 +997,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature) | |||
968 | 997 | ||
969 | /* step 13: bring the IOP and AAP1 out of reset */ | 998 | /* step 13: bring the IOP and AAP1 out of reset */ |
970 | /* map 0x00000 to BAR4(0x20), BAR2(win) */ | 999 | /* map 0x00000 to BAR4(0x20), BAR2(win) */ |
971 | if (-1 == bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) { | 1000 | if (-1 == pm8001_bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) { |
1001 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
972 | PM8001_FAIL_DBG(pm8001_ha, | 1002 | PM8001_FAIL_DBG(pm8001_ha, |
973 | pm8001_printk("Shift Bar4 to 0x%x failed\n", | 1003 | pm8001_printk("Shift Bar4 to 0x%x failed\n", |
974 | SPC_TOP_LEVEL_ADDR_BASE)); | 1004 | SPC_TOP_LEVEL_ADDR_BASE)); |
@@ -1010,6 +1040,7 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature) | |||
1010 | pm8001_printk("SCRATCH_PAD3 value = 0x%x\n", | 1040 | pm8001_printk("SCRATCH_PAD3 value = 0x%x\n", |
1011 | pm8001_cr32(pm8001_ha, 0, | 1041 | pm8001_cr32(pm8001_ha, 0, |
1012 | MSGU_SCRATCH_PAD_3))); | 1042 | MSGU_SCRATCH_PAD_3))); |
1043 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
1013 | return -1; | 1044 | return -1; |
1014 | } | 1045 | } |
1015 | 1046 | ||
@@ -1039,9 +1070,12 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature) | |||
1039 | pm8001_printk("SCRATCH_PAD3 value = 0x%x\n", | 1070 | pm8001_printk("SCRATCH_PAD3 value = 0x%x\n", |
1040 | pm8001_cr32(pm8001_ha, 0, | 1071 | pm8001_cr32(pm8001_ha, 0, |
1041 | MSGU_SCRATCH_PAD_3))); | 1072 | MSGU_SCRATCH_PAD_3))); |
1073 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
1042 | return -1; | 1074 | return -1; |
1043 | } | 1075 | } |
1044 | } | 1076 | } |
1077 | pm8001_bar4_shift(pm8001_ha, 0); | ||
1078 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
1045 | 1079 | ||
1046 | PM8001_INIT_DBG(pm8001_ha, | 1080 | PM8001_INIT_DBG(pm8001_ha, |
1047 | pm8001_printk("SPC soft reset Complete\n")); | 1081 | pm8001_printk("SPC soft reset Complete\n")); |
@@ -1157,8 +1191,8 @@ pm8001_chip_msix_interrupt_disable(struct pm8001_hba_info *pm8001_ha, | |||
1157 | msi_index = int_vec_idx * MSIX_TABLE_ELEMENT_SIZE; | 1191 | msi_index = int_vec_idx * MSIX_TABLE_ELEMENT_SIZE; |
1158 | msi_index += MSIX_TABLE_BASE; | 1192 | msi_index += MSIX_TABLE_BASE; |
1159 | pm8001_cw32(pm8001_ha, 0, msi_index, MSIX_INTERRUPT_DISABLE); | 1193 | pm8001_cw32(pm8001_ha, 0, msi_index, MSIX_INTERRUPT_DISABLE); |
1160 | |||
1161 | } | 1194 | } |
1195 | |||
1162 | /** | 1196 | /** |
1163 | * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt | 1197 | * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt |
1164 | * @pm8001_ha: our hba card information | 1198 | * @pm8001_ha: our hba card information |
@@ -1212,7 +1246,7 @@ static int mpi_msg_free_get(struct inbound_queue_table *circularQ, | |||
1212 | consumer_index = pm8001_read_32(circularQ->ci_virt); | 1246 | consumer_index = pm8001_read_32(circularQ->ci_virt); |
1213 | circularQ->consumer_index = cpu_to_le32(consumer_index); | 1247 | circularQ->consumer_index = cpu_to_le32(consumer_index); |
1214 | if (((circularQ->producer_idx + bcCount) % 256) == | 1248 | if (((circularQ->producer_idx + bcCount) % 256) == |
1215 | circularQ->consumer_index) { | 1249 | le32_to_cpu(circularQ->consumer_index)) { |
1216 | *messagePtr = NULL; | 1250 | *messagePtr = NULL; |
1217 | return -1; | 1251 | return -1; |
1218 | } | 1252 | } |
@@ -1321,7 +1355,8 @@ static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, | |||
1321 | u32 header_tmp; | 1355 | u32 header_tmp; |
1322 | do { | 1356 | do { |
1323 | /* If there are not-yet-delivered messages ... */ | 1357 | /* If there are not-yet-delivered messages ... */ |
1324 | if (circularQ->producer_index != circularQ->consumer_idx) { | 1358 | if (le32_to_cpu(circularQ->producer_index) |
1359 | != circularQ->consumer_idx) { | ||
1325 | /*Get the pointer to the circular queue buffer element*/ | 1360 | /*Get the pointer to the circular queue buffer element*/ |
1326 | msgHeader = (struct mpi_msg_hdr *) | 1361 | msgHeader = (struct mpi_msg_hdr *) |
1327 | (circularQ->base_virt + | 1362 | (circularQ->base_virt + |
@@ -1329,14 +1364,14 @@ static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, | |||
1329 | /* read header */ | 1364 | /* read header */ |
1330 | header_tmp = pm8001_read_32(msgHeader); | 1365 | header_tmp = pm8001_read_32(msgHeader); |
1331 | msgHeader_tmp = cpu_to_le32(header_tmp); | 1366 | msgHeader_tmp = cpu_to_le32(header_tmp); |
1332 | if (0 != (msgHeader_tmp & 0x80000000)) { | 1367 | if (0 != (le32_to_cpu(msgHeader_tmp) & 0x80000000)) { |
1333 | if (OPC_OUB_SKIP_ENTRY != | 1368 | if (OPC_OUB_SKIP_ENTRY != |
1334 | (msgHeader_tmp & 0xfff)) { | 1369 | (le32_to_cpu(msgHeader_tmp) & 0xfff)) { |
1335 | *messagePtr1 = | 1370 | *messagePtr1 = |
1336 | ((u8 *)msgHeader) + | 1371 | ((u8 *)msgHeader) + |
1337 | sizeof(struct mpi_msg_hdr); | 1372 | sizeof(struct mpi_msg_hdr); |
1338 | *pBC = (u8)((msgHeader_tmp >> 24) & | 1373 | *pBC = (u8)((le32_to_cpu(msgHeader_tmp) |
1339 | 0x1f); | 1374 | >> 24) & 0x1f); |
1340 | PM8001_IO_DBG(pm8001_ha, | 1375 | PM8001_IO_DBG(pm8001_ha, |
1341 | pm8001_printk(": CI=%d PI=%d " | 1376 | pm8001_printk(": CI=%d PI=%d " |
1342 | "msgHeader=%x\n", | 1377 | "msgHeader=%x\n", |
@@ -1347,8 +1382,8 @@ static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, | |||
1347 | } else { | 1382 | } else { |
1348 | circularQ->consumer_idx = | 1383 | circularQ->consumer_idx = |
1349 | (circularQ->consumer_idx + | 1384 | (circularQ->consumer_idx + |
1350 | ((msgHeader_tmp >> 24) & 0x1f)) | 1385 | ((le32_to_cpu(msgHeader_tmp) |
1351 | % 256; | 1386 | >> 24) & 0x1f)) % 256; |
1352 | msgHeader_tmp = 0; | 1387 | msgHeader_tmp = 0; |
1353 | pm8001_write_32(msgHeader, 0, 0); | 1388 | pm8001_write_32(msgHeader, 0, 0); |
1354 | /* update the CI of outbound queue */ | 1389 | /* update the CI of outbound queue */ |
@@ -1360,7 +1395,8 @@ static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, | |||
1360 | } else { | 1395 | } else { |
1361 | circularQ->consumer_idx = | 1396 | circularQ->consumer_idx = |
1362 | (circularQ->consumer_idx + | 1397 | (circularQ->consumer_idx + |
1363 | ((msgHeader_tmp >> 24) & 0x1f)) % 256; | 1398 | ((le32_to_cpu(msgHeader_tmp) >> 24) & |
1399 | 0x1f)) % 256; | ||
1364 | msgHeader_tmp = 0; | 1400 | msgHeader_tmp = 0; |
1365 | pm8001_write_32(msgHeader, 0, 0); | 1401 | pm8001_write_32(msgHeader, 0, 0); |
1366 | /* update the CI of outbound queue */ | 1402 | /* update the CI of outbound queue */ |
@@ -1376,7 +1412,8 @@ static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, | |||
1376 | producer_index = pm8001_read_32(pi_virt); | 1412 | producer_index = pm8001_read_32(pi_virt); |
1377 | circularQ->producer_index = cpu_to_le32(producer_index); | 1413 | circularQ->producer_index = cpu_to_le32(producer_index); |
1378 | } | 1414 | } |
1379 | } while (circularQ->producer_index != circularQ->consumer_idx); | 1415 | } while (le32_to_cpu(circularQ->producer_index) != |
1416 | circularQ->consumer_idx); | ||
1380 | /* while we don't have any more not-yet-delivered message */ | 1417 | /* while we don't have any more not-yet-delivered message */ |
1381 | /* report empty */ | 1418 | /* report empty */ |
1382 | return MPI_IO_STATUS_BUSY; | 1419 | return MPI_IO_STATUS_BUSY; |
@@ -1388,24 +1425,191 @@ static void pm8001_work_fn(struct work_struct *work) | |||
1388 | struct pm8001_device *pm8001_dev; | 1425 | struct pm8001_device *pm8001_dev; |
1389 | struct domain_device *dev; | 1426 | struct domain_device *dev; |
1390 | 1427 | ||
1428 | /* | ||
1429 | * So far, all users of this stash an associated structure here. | ||
1430 | * If we get here, and this pointer is null, then the action | ||
1431 | * was cancelled. This nullification happens when the device | ||
1432 | * goes away. | ||
1433 | */ | ||
1434 | pm8001_dev = pw->data; /* Most stash device structure */ | ||
1435 | if ((pm8001_dev == NULL) | ||
1436 | || ((pw->handler != IO_XFER_ERROR_BREAK) | ||
1437 | && (pm8001_dev->dev_type == NO_DEVICE))) { | ||
1438 | kfree(pw); | ||
1439 | return; | ||
1440 | } | ||
1441 | |||
1391 | switch (pw->handler) { | 1442 | switch (pw->handler) { |
1443 | case IO_XFER_ERROR_BREAK: | ||
1444 | { /* This one stashes the sas_task instead */ | ||
1445 | struct sas_task *t = (struct sas_task *)pm8001_dev; | ||
1446 | u32 tag; | ||
1447 | struct pm8001_ccb_info *ccb; | ||
1448 | struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha; | ||
1449 | unsigned long flags, flags1; | ||
1450 | struct task_status_struct *ts; | ||
1451 | int i; | ||
1452 | |||
1453 | if (pm8001_query_task(t) == TMF_RESP_FUNC_SUCC) | ||
1454 | break; /* Task still on lu */ | ||
1455 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
1456 | |||
1457 | spin_lock_irqsave(&t->task_state_lock, flags1); | ||
1458 | if (unlikely((t->task_state_flags & SAS_TASK_STATE_DONE))) { | ||
1459 | spin_unlock_irqrestore(&t->task_state_lock, flags1); | ||
1460 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
1461 | break; /* Task got completed by another */ | ||
1462 | } | ||
1463 | spin_unlock_irqrestore(&t->task_state_lock, flags1); | ||
1464 | |||
1465 | /* Search for a possible ccb that matches the task */ | ||
1466 | for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) { | ||
1467 | ccb = &pm8001_ha->ccb_info[i]; | ||
1468 | tag = ccb->ccb_tag; | ||
1469 | if ((tag != 0xFFFFFFFF) && (ccb->task == t)) | ||
1470 | break; | ||
1471 | } | ||
1472 | if (!ccb) { | ||
1473 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
1474 | break; /* Task got freed by another */ | ||
1475 | } | ||
1476 | ts = &t->task_status; | ||
1477 | ts->resp = SAS_TASK_COMPLETE; | ||
1478 | /* Force the midlayer to retry */ | ||
1479 | ts->stat = SAS_QUEUE_FULL; | ||
1480 | pm8001_dev = ccb->device; | ||
1481 | if (pm8001_dev) | ||
1482 | pm8001_dev->running_req--; | ||
1483 | spin_lock_irqsave(&t->task_state_lock, flags1); | ||
1484 | t->task_state_flags &= ~SAS_TASK_STATE_PENDING; | ||
1485 | t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; | ||
1486 | t->task_state_flags |= SAS_TASK_STATE_DONE; | ||
1487 | if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { | ||
1488 | spin_unlock_irqrestore(&t->task_state_lock, flags1); | ||
1489 | PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("task 0x%p" | ||
1490 | " done with event 0x%x resp 0x%x stat 0x%x but" | ||
1491 | " aborted by upper layer!\n", | ||
1492 | t, pw->handler, ts->resp, ts->stat)); | ||
1493 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | ||
1494 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
1495 | } else { | ||
1496 | spin_unlock_irqrestore(&t->task_state_lock, flags1); | ||
1497 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | ||
1498 | mb();/* in order to force CPU ordering */ | ||
1499 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
1500 | t->task_done(t); | ||
1501 | } | ||
1502 | } break; | ||
1503 | case IO_XFER_OPEN_RETRY_TIMEOUT: | ||
1504 | { /* This one stashes the sas_task instead */ | ||
1505 | struct sas_task *t = (struct sas_task *)pm8001_dev; | ||
1506 | u32 tag; | ||
1507 | struct pm8001_ccb_info *ccb; | ||
1508 | struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha; | ||
1509 | unsigned long flags, flags1; | ||
1510 | int i, ret = 0; | ||
1511 | |||
1512 | PM8001_IO_DBG(pm8001_ha, | ||
1513 | pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); | ||
1514 | |||
1515 | ret = pm8001_query_task(t); | ||
1516 | |||
1517 | PM8001_IO_DBG(pm8001_ha, | ||
1518 | switch (ret) { | ||
1519 | case TMF_RESP_FUNC_SUCC: | ||
1520 | pm8001_printk("...Task on lu\n"); | ||
1521 | break; | ||
1522 | |||
1523 | case TMF_RESP_FUNC_COMPLETE: | ||
1524 | pm8001_printk("...Task NOT on lu\n"); | ||
1525 | break; | ||
1526 | |||
1527 | default: | ||
1528 | pm8001_printk("...query task failed!!!\n"); | ||
1529 | break; | ||
1530 | }); | ||
1531 | |||
1532 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
1533 | |||
1534 | spin_lock_irqsave(&t->task_state_lock, flags1); | ||
1535 | |||
1536 | if (unlikely((t->task_state_flags & SAS_TASK_STATE_DONE))) { | ||
1537 | spin_unlock_irqrestore(&t->task_state_lock, flags1); | ||
1538 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
1539 | if (ret == TMF_RESP_FUNC_SUCC) /* task on lu */ | ||
1540 | (void)pm8001_abort_task(t); | ||
1541 | break; /* Task got completed by another */ | ||
1542 | } | ||
1543 | |||
1544 | spin_unlock_irqrestore(&t->task_state_lock, flags1); | ||
1545 | |||
1546 | /* Search for a possible ccb that matches the task */ | ||
1547 | for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) { | ||
1548 | ccb = &pm8001_ha->ccb_info[i]; | ||
1549 | tag = ccb->ccb_tag; | ||
1550 | if ((tag != 0xFFFFFFFF) && (ccb->task == t)) | ||
1551 | break; | ||
1552 | } | ||
1553 | if (!ccb) { | ||
1554 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
1555 | if (ret == TMF_RESP_FUNC_SUCC) /* task on lu */ | ||
1556 | (void)pm8001_abort_task(t); | ||
1557 | break; /* Task got freed by another */ | ||
1558 | } | ||
1559 | |||
1560 | pm8001_dev = ccb->device; | ||
1561 | dev = pm8001_dev->sas_device; | ||
1562 | |||
1563 | switch (ret) { | ||
1564 | case TMF_RESP_FUNC_SUCC: /* task on lu */ | ||
1565 | ccb->open_retry = 1; /* Snub completion */ | ||
1566 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
1567 | ret = pm8001_abort_task(t); | ||
1568 | ccb->open_retry = 0; | ||
1569 | switch (ret) { | ||
1570 | case TMF_RESP_FUNC_SUCC: | ||
1571 | case TMF_RESP_FUNC_COMPLETE: | ||
1572 | break; | ||
1573 | default: /* device misbehavior */ | ||
1574 | ret = TMF_RESP_FUNC_FAILED; | ||
1575 | PM8001_IO_DBG(pm8001_ha, | ||
1576 | pm8001_printk("...Reset phy\n")); | ||
1577 | pm8001_I_T_nexus_reset(dev); | ||
1578 | break; | ||
1579 | } | ||
1580 | break; | ||
1581 | |||
1582 | case TMF_RESP_FUNC_COMPLETE: /* task not on lu */ | ||
1583 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
1584 | /* Do we need to abort the task locally? */ | ||
1585 | break; | ||
1586 | |||
1587 | default: /* device misbehavior */ | ||
1588 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
1589 | ret = TMF_RESP_FUNC_FAILED; | ||
1590 | PM8001_IO_DBG(pm8001_ha, | ||
1591 | pm8001_printk("...Reset phy\n")); | ||
1592 | pm8001_I_T_nexus_reset(dev); | ||
1593 | } | ||
1594 | |||
1595 | if (ret == TMF_RESP_FUNC_FAILED) | ||
1596 | t = NULL; | ||
1597 | pm8001_open_reject_retry(pm8001_ha, t, pm8001_dev); | ||
1598 | PM8001_IO_DBG(pm8001_ha, pm8001_printk("...Complete\n")); | ||
1599 | } break; | ||
1392 | case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: | 1600 | case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: |
1393 | pm8001_dev = pw->data; | ||
1394 | dev = pm8001_dev->sas_device; | 1601 | dev = pm8001_dev->sas_device; |
1395 | pm8001_I_T_nexus_reset(dev); | 1602 | pm8001_I_T_nexus_reset(dev); |
1396 | break; | 1603 | break; |
1397 | case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: | 1604 | case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: |
1398 | pm8001_dev = pw->data; | ||
1399 | dev = pm8001_dev->sas_device; | 1605 | dev = pm8001_dev->sas_device; |
1400 | pm8001_I_T_nexus_reset(dev); | 1606 | pm8001_I_T_nexus_reset(dev); |
1401 | break; | 1607 | break; |
1402 | case IO_DS_IN_ERROR: | 1608 | case IO_DS_IN_ERROR: |
1403 | pm8001_dev = pw->data; | ||
1404 | dev = pm8001_dev->sas_device; | 1609 | dev = pm8001_dev->sas_device; |
1405 | pm8001_I_T_nexus_reset(dev); | 1610 | pm8001_I_T_nexus_reset(dev); |
1406 | break; | 1611 | break; |
1407 | case IO_DS_NON_OPERATIONAL: | 1612 | case IO_DS_NON_OPERATIONAL: |
1408 | pm8001_dev = pw->data; | ||
1409 | dev = pm8001_dev->sas_device; | 1613 | dev = pm8001_dev->sas_device; |
1410 | pm8001_I_T_nexus_reset(dev); | 1614 | pm8001_I_T_nexus_reset(dev); |
1411 | break; | 1615 | break; |
@@ -1460,6 +1664,11 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) | |||
1460 | status = le32_to_cpu(psspPayload->status); | 1664 | status = le32_to_cpu(psspPayload->status); |
1461 | tag = le32_to_cpu(psspPayload->tag); | 1665 | tag = le32_to_cpu(psspPayload->tag); |
1462 | ccb = &pm8001_ha->ccb_info[tag]; | 1666 | ccb = &pm8001_ha->ccb_info[tag]; |
1667 | if ((status == IO_ABORTED) && ccb->open_retry) { | ||
1668 | /* Being completed by another */ | ||
1669 | ccb->open_retry = 0; | ||
1670 | return; | ||
1671 | } | ||
1463 | pm8001_dev = ccb->device; | 1672 | pm8001_dev = ccb->device; |
1464 | param = le32_to_cpu(psspPayload->param); | 1673 | param = le32_to_cpu(psspPayload->param); |
1465 | 1674 | ||
@@ -1515,6 +1724,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) | |||
1515 | pm8001_printk("IO_XFER_ERROR_BREAK\n")); | 1724 | pm8001_printk("IO_XFER_ERROR_BREAK\n")); |
1516 | ts->resp = SAS_TASK_COMPLETE; | 1725 | ts->resp = SAS_TASK_COMPLETE; |
1517 | ts->stat = SAS_OPEN_REJECT; | 1726 | ts->stat = SAS_OPEN_REJECT; |
1727 | /* Force the midlayer to retry */ | ||
1728 | ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; | ||
1518 | break; | 1729 | break; |
1519 | case IO_XFER_ERROR_PHY_NOT_READY: | 1730 | case IO_XFER_ERROR_PHY_NOT_READY: |
1520 | PM8001_IO_DBG(pm8001_ha, | 1731 | PM8001_IO_DBG(pm8001_ha, |
@@ -1719,9 +1930,8 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) | |||
1719 | case IO_XFER_ERROR_BREAK: | 1930 | case IO_XFER_ERROR_BREAK: |
1720 | PM8001_IO_DBG(pm8001_ha, | 1931 | PM8001_IO_DBG(pm8001_ha, |
1721 | pm8001_printk("IO_XFER_ERROR_BREAK\n")); | 1932 | pm8001_printk("IO_XFER_ERROR_BREAK\n")); |
1722 | ts->resp = SAS_TASK_COMPLETE; | 1933 | pm8001_handle_event(pm8001_ha, t, IO_XFER_ERROR_BREAK); |
1723 | ts->stat = SAS_INTERRUPTED; | 1934 | return; |
1724 | break; | ||
1725 | case IO_XFER_ERROR_PHY_NOT_READY: | 1935 | case IO_XFER_ERROR_PHY_NOT_READY: |
1726 | PM8001_IO_DBG(pm8001_ha, | 1936 | PM8001_IO_DBG(pm8001_ha, |
1727 | pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); | 1937 | 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) | |||
1800 | case IO_XFER_OPEN_RETRY_TIMEOUT: | 2010 | case IO_XFER_OPEN_RETRY_TIMEOUT: |
1801 | PM8001_IO_DBG(pm8001_ha, | 2011 | PM8001_IO_DBG(pm8001_ha, |
1802 | pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); | 2012 | pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); |
1803 | ts->resp = SAS_TASK_COMPLETE; | 2013 | pm8001_handle_event(pm8001_ha, t, IO_XFER_OPEN_RETRY_TIMEOUT); |
1804 | ts->stat = SAS_OPEN_REJECT; | 2014 | return; |
1805 | ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; | ||
1806 | break; | ||
1807 | case IO_XFER_ERROR_UNEXPECTED_PHASE: | 2015 | case IO_XFER_ERROR_UNEXPECTED_PHASE: |
1808 | PM8001_IO_DBG(pm8001_ha, | 2016 | PM8001_IO_DBG(pm8001_ha, |
1809 | pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n")); | 2017 | pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n")); |
@@ -1877,7 +2085,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
1877 | { | 2085 | { |
1878 | struct sas_task *t; | 2086 | struct sas_task *t; |
1879 | struct pm8001_ccb_info *ccb; | 2087 | struct pm8001_ccb_info *ccb; |
1880 | unsigned long flags = 0; | ||
1881 | u32 param; | 2088 | u32 param; |
1882 | u32 status; | 2089 | u32 status; |
1883 | u32 tag; | 2090 | u32 tag; |
@@ -2016,9 +2223,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2016 | ts->stat = SAS_QUEUE_FULL; | 2223 | ts->stat = SAS_QUEUE_FULL; |
2017 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2224 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
2018 | mb();/*in order to force CPU ordering*/ | 2225 | mb();/*in order to force CPU ordering*/ |
2019 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | 2226 | spin_unlock_irq(&pm8001_ha->lock); |
2020 | t->task_done(t); | 2227 | t->task_done(t); |
2021 | spin_lock_irqsave(&pm8001_ha->lock, flags); | 2228 | spin_lock_irq(&pm8001_ha->lock); |
2022 | return; | 2229 | return; |
2023 | } | 2230 | } |
2024 | break; | 2231 | break; |
@@ -2036,9 +2243,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2036 | ts->stat = SAS_QUEUE_FULL; | 2243 | ts->stat = SAS_QUEUE_FULL; |
2037 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2244 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
2038 | mb();/*ditto*/ | 2245 | mb();/*ditto*/ |
2039 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | 2246 | spin_unlock_irq(&pm8001_ha->lock); |
2040 | t->task_done(t); | 2247 | t->task_done(t); |
2041 | spin_lock_irqsave(&pm8001_ha->lock, flags); | 2248 | spin_lock_irq(&pm8001_ha->lock); |
2042 | return; | 2249 | return; |
2043 | } | 2250 | } |
2044 | break; | 2251 | break; |
@@ -2064,9 +2271,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2064 | ts->stat = SAS_QUEUE_FULL; | 2271 | ts->stat = SAS_QUEUE_FULL; |
2065 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2272 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
2066 | mb();/* ditto*/ | 2273 | mb();/* ditto*/ |
2067 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | 2274 | spin_unlock_irq(&pm8001_ha->lock); |
2068 | t->task_done(t); | 2275 | t->task_done(t); |
2069 | spin_lock_irqsave(&pm8001_ha->lock, flags); | 2276 | spin_lock_irq(&pm8001_ha->lock); |
2070 | return; | 2277 | return; |
2071 | } | 2278 | } |
2072 | break; | 2279 | break; |
@@ -2131,9 +2338,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2131 | ts->stat = SAS_QUEUE_FULL; | 2338 | ts->stat = SAS_QUEUE_FULL; |
2132 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2339 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
2133 | mb();/*ditto*/ | 2340 | mb();/*ditto*/ |
2134 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | 2341 | spin_unlock_irq(&pm8001_ha->lock); |
2135 | t->task_done(t); | 2342 | t->task_done(t); |
2136 | spin_lock_irqsave(&pm8001_ha->lock, flags); | 2343 | spin_lock_irq(&pm8001_ha->lock); |
2137 | return; | 2344 | return; |
2138 | } | 2345 | } |
2139 | break; | 2346 | break; |
@@ -2155,9 +2362,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2155 | ts->stat = SAS_QUEUE_FULL; | 2362 | ts->stat = SAS_QUEUE_FULL; |
2156 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2363 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
2157 | mb();/*ditto*/ | 2364 | mb();/*ditto*/ |
2158 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | 2365 | spin_unlock_irq(&pm8001_ha->lock); |
2159 | t->task_done(t); | 2366 | t->task_done(t); |
2160 | spin_lock_irqsave(&pm8001_ha->lock, flags); | 2367 | spin_lock_irq(&pm8001_ha->lock); |
2161 | return; | 2368 | return; |
2162 | } | 2369 | } |
2163 | break; | 2370 | break; |
@@ -2175,31 +2382,31 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2175 | ts->stat = SAS_DEV_NO_RESPONSE; | 2382 | ts->stat = SAS_DEV_NO_RESPONSE; |
2176 | break; | 2383 | break; |
2177 | } | 2384 | } |
2178 | spin_lock_irqsave(&t->task_state_lock, flags); | 2385 | spin_lock_irq(&t->task_state_lock); |
2179 | t->task_state_flags &= ~SAS_TASK_STATE_PENDING; | 2386 | t->task_state_flags &= ~SAS_TASK_STATE_PENDING; |
2180 | t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; | 2387 | t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; |
2181 | t->task_state_flags |= SAS_TASK_STATE_DONE; | 2388 | t->task_state_flags |= SAS_TASK_STATE_DONE; |
2182 | if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { | 2389 | if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { |
2183 | spin_unlock_irqrestore(&t->task_state_lock, flags); | 2390 | spin_unlock_irq(&t->task_state_lock); |
2184 | PM8001_FAIL_DBG(pm8001_ha, | 2391 | PM8001_FAIL_DBG(pm8001_ha, |
2185 | pm8001_printk("task 0x%p done with io_status 0x%x" | 2392 | pm8001_printk("task 0x%p done with io_status 0x%x" |
2186 | " resp 0x%x stat 0x%x but aborted by upper layer!\n", | 2393 | " resp 0x%x stat 0x%x but aborted by upper layer!\n", |
2187 | t, status, ts->resp, ts->stat)); | 2394 | t, status, ts->resp, ts->stat)); |
2188 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2395 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
2189 | } else if (t->uldd_task) { | 2396 | } else if (t->uldd_task) { |
2190 | spin_unlock_irqrestore(&t->task_state_lock, flags); | 2397 | spin_unlock_irq(&t->task_state_lock); |
2191 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2398 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
2192 | mb();/* ditto */ | 2399 | mb();/* ditto */ |
2193 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | 2400 | spin_unlock_irq(&pm8001_ha->lock); |
2194 | t->task_done(t); | 2401 | t->task_done(t); |
2195 | spin_lock_irqsave(&pm8001_ha->lock, flags); | 2402 | spin_lock_irq(&pm8001_ha->lock); |
2196 | } else if (!t->uldd_task) { | 2403 | } else if (!t->uldd_task) { |
2197 | spin_unlock_irqrestore(&t->task_state_lock, flags); | 2404 | spin_unlock_irq(&t->task_state_lock); |
2198 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2405 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
2199 | mb();/*ditto*/ | 2406 | mb();/*ditto*/ |
2200 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | 2407 | spin_unlock_irq(&pm8001_ha->lock); |
2201 | t->task_done(t); | 2408 | t->task_done(t); |
2202 | spin_lock_irqsave(&pm8001_ha->lock, flags); | 2409 | spin_lock_irq(&pm8001_ha->lock); |
2203 | } | 2410 | } |
2204 | } | 2411 | } |
2205 | 2412 | ||
@@ -2207,7 +2414,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2207 | static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) | 2414 | static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) |
2208 | { | 2415 | { |
2209 | struct sas_task *t; | 2416 | struct sas_task *t; |
2210 | unsigned long flags = 0; | ||
2211 | struct task_status_struct *ts; | 2417 | struct task_status_struct *ts; |
2212 | struct pm8001_ccb_info *ccb; | 2418 | struct pm8001_ccb_info *ccb; |
2213 | struct pm8001_device *pm8001_dev; | 2419 | struct pm8001_device *pm8001_dev; |
@@ -2287,9 +2493,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) | |||
2287 | ts->stat = SAS_QUEUE_FULL; | 2493 | ts->stat = SAS_QUEUE_FULL; |
2288 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2494 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
2289 | mb();/*ditto*/ | 2495 | mb();/*ditto*/ |
2290 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | 2496 | spin_unlock_irq(&pm8001_ha->lock); |
2291 | t->task_done(t); | 2497 | t->task_done(t); |
2292 | spin_lock_irqsave(&pm8001_ha->lock, flags); | 2498 | spin_lock_irq(&pm8001_ha->lock); |
2293 | return; | 2499 | return; |
2294 | } | 2500 | } |
2295 | break; | 2501 | break; |
@@ -2387,31 +2593,31 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) | |||
2387 | ts->stat = SAS_OPEN_TO; | 2593 | ts->stat = SAS_OPEN_TO; |
2388 | break; | 2594 | break; |
2389 | } | 2595 | } |
2390 | spin_lock_irqsave(&t->task_state_lock, flags); | 2596 | spin_lock_irq(&t->task_state_lock); |
2391 | t->task_state_flags &= ~SAS_TASK_STATE_PENDING; | 2597 | t->task_state_flags &= ~SAS_TASK_STATE_PENDING; |
2392 | t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; | 2598 | t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; |
2393 | t->task_state_flags |= SAS_TASK_STATE_DONE; | 2599 | t->task_state_flags |= SAS_TASK_STATE_DONE; |
2394 | if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { | 2600 | if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { |
2395 | spin_unlock_irqrestore(&t->task_state_lock, flags); | 2601 | spin_unlock_irq(&t->task_state_lock); |
2396 | PM8001_FAIL_DBG(pm8001_ha, | 2602 | PM8001_FAIL_DBG(pm8001_ha, |
2397 | pm8001_printk("task 0x%p done with io_status 0x%x" | 2603 | pm8001_printk("task 0x%p done with io_status 0x%x" |
2398 | " resp 0x%x stat 0x%x but aborted by upper layer!\n", | 2604 | " resp 0x%x stat 0x%x but aborted by upper layer!\n", |
2399 | t, event, ts->resp, ts->stat)); | 2605 | t, event, ts->resp, ts->stat)); |
2400 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2606 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
2401 | } else if (t->uldd_task) { | 2607 | } else if (t->uldd_task) { |
2402 | spin_unlock_irqrestore(&t->task_state_lock, flags); | 2608 | spin_unlock_irq(&t->task_state_lock); |
2403 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2609 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
2404 | mb();/* ditto */ | 2610 | mb();/* ditto */ |
2405 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | 2611 | spin_unlock_irq(&pm8001_ha->lock); |
2406 | t->task_done(t); | 2612 | t->task_done(t); |
2407 | spin_lock_irqsave(&pm8001_ha->lock, flags); | 2613 | spin_lock_irq(&pm8001_ha->lock); |
2408 | } else if (!t->uldd_task) { | 2614 | } else if (!t->uldd_task) { |
2409 | spin_unlock_irqrestore(&t->task_state_lock, flags); | 2615 | spin_unlock_irq(&t->task_state_lock); |
2410 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2616 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
2411 | mb();/*ditto*/ | 2617 | mb();/*ditto*/ |
2412 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | 2618 | spin_unlock_irq(&pm8001_ha->lock); |
2413 | t->task_done(t); | 2619 | t->task_done(t); |
2414 | spin_lock_irqsave(&pm8001_ha->lock, flags); | 2620 | spin_lock_irq(&pm8001_ha->lock); |
2415 | } | 2621 | } |
2416 | } | 2622 | } |
2417 | 2623 | ||
@@ -2857,7 +3063,7 @@ static void pm8001_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha, | |||
2857 | 3063 | ||
2858 | memset((u8 *)&payload, 0, sizeof(payload)); | 3064 | memset((u8 *)&payload, 0, sizeof(payload)); |
2859 | circularQ = &pm8001_ha->inbnd_q_tbl[Qnum]; | 3065 | circularQ = &pm8001_ha->inbnd_q_tbl[Qnum]; |
2860 | payload.tag = 1; | 3066 | payload.tag = cpu_to_le32(1); |
2861 | payload.sea_phyid_portid = cpu_to_le32(((SEA & 0xFFFF) << 8) | | 3067 | payload.sea_phyid_portid = cpu_to_le32(((SEA & 0xFFFF) << 8) | |
2862 | ((phyId & 0x0F) << 4) | (port_id & 0x0F)); | 3068 | ((phyId & 0x0F) << 4) | (port_id & 0x0F)); |
2863 | payload.param0 = cpu_to_le32(param0); | 3069 | payload.param0 = cpu_to_le32(param0); |
@@ -2929,9 +3135,9 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2929 | phy->phy_type |= PORT_TYPE_SAS; | 3135 | phy->phy_type |= PORT_TYPE_SAS; |
2930 | phy->identify.device_type = deviceType; | 3136 | phy->identify.device_type = deviceType; |
2931 | phy->phy_attached = 1; | 3137 | phy->phy_attached = 1; |
2932 | if (phy->identify.device_type == SAS_END_DEV) | 3138 | if (phy->identify.device_type == SAS_END_DEVICE) |
2933 | phy->identify.target_port_protocols = SAS_PROTOCOL_SSP; | 3139 | phy->identify.target_port_protocols = SAS_PROTOCOL_SSP; |
2934 | else if (phy->identify.device_type != NO_DEVICE) | 3140 | else if (phy->identify.device_type != SAS_PHY_UNUSED) |
2935 | phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; | 3141 | phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; |
2936 | phy->sas_phy.oob_mode = SAS_OOB_MODE; | 3142 | phy->sas_phy.oob_mode = SAS_OOB_MODE; |
2937 | sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); | 3143 | 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) | |||
3075 | (struct dev_reg_resp *)(piomb + 4); | 3281 | (struct dev_reg_resp *)(piomb + 4); |
3076 | 3282 | ||
3077 | htag = le32_to_cpu(registerRespPayload->tag); | 3283 | htag = le32_to_cpu(registerRespPayload->tag); |
3078 | ccb = &pm8001_ha->ccb_info[registerRespPayload->tag]; | 3284 | ccb = &pm8001_ha->ccb_info[htag]; |
3079 | pm8001_dev = ccb->device; | 3285 | pm8001_dev = ccb->device; |
3080 | status = le32_to_cpu(registerRespPayload->status); | 3286 | status = le32_to_cpu(registerRespPayload->status); |
3081 | device_id = le32_to_cpu(registerRespPayload->device_id); | 3287 | 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) | |||
3149 | struct fw_control_ex fw_control_context; | 3355 | struct fw_control_ex fw_control_context; |
3150 | struct fw_flash_Update_resp *ppayload = | 3356 | struct fw_flash_Update_resp *ppayload = |
3151 | (struct fw_flash_Update_resp *)(piomb + 4); | 3357 | (struct fw_flash_Update_resp *)(piomb + 4); |
3152 | u32 tag = le32_to_cpu(ppayload->tag); | 3358 | u32 tag = ppayload->tag; |
3153 | struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag]; | 3359 | struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag]; |
3154 | status = le32_to_cpu(ppayload->status); | 3360 | status = le32_to_cpu(ppayload->status); |
3155 | memcpy(&fw_control_context, | 3361 | memcpy(&fw_control_context, |
@@ -3238,13 +3444,12 @@ mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
3238 | 3444 | ||
3239 | struct task_abort_resp *pPayload = | 3445 | struct task_abort_resp *pPayload = |
3240 | (struct task_abort_resp *)(piomb + 4); | 3446 | (struct task_abort_resp *)(piomb + 4); |
3241 | ccb = &pm8001_ha->ccb_info[pPayload->tag]; | ||
3242 | t = ccb->task; | ||
3243 | |||
3244 | 3447 | ||
3245 | status = le32_to_cpu(pPayload->status); | 3448 | status = le32_to_cpu(pPayload->status); |
3246 | tag = le32_to_cpu(pPayload->tag); | 3449 | tag = le32_to_cpu(pPayload->tag); |
3247 | scp = le32_to_cpu(pPayload->scp); | 3450 | scp = le32_to_cpu(pPayload->scp); |
3451 | ccb = &pm8001_ha->ccb_info[tag]; | ||
3452 | t = ccb->task; | ||
3248 | PM8001_IO_DBG(pm8001_ha, | 3453 | PM8001_IO_DBG(pm8001_ha, |
3249 | pm8001_printk(" status = 0x%x\n", status)); | 3454 | pm8001_printk(" status = 0x%x\n", status)); |
3250 | if (t == NULL) | 3455 | if (t == NULL) |
@@ -3270,7 +3475,7 @@ mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
3270 | t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; | 3475 | t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; |
3271 | t->task_state_flags |= SAS_TASK_STATE_DONE; | 3476 | t->task_state_flags |= SAS_TASK_STATE_DONE; |
3272 | spin_unlock_irqrestore(&t->task_state_lock, flags); | 3477 | spin_unlock_irqrestore(&t->task_state_lock, flags); |
3273 | pm8001_ccb_task_free(pm8001_ha, t, ccb, pPayload->tag); | 3478 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
3274 | mb(); | 3479 | mb(); |
3275 | t->task_done(t); | 3480 | t->task_done(t); |
3276 | return 0; | 3481 | return 0; |
@@ -3497,7 +3702,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) | |||
3497 | static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) | 3702 | static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) |
3498 | { | 3703 | { |
3499 | u32 pHeader = (u32)*(u32 *)piomb; | 3704 | u32 pHeader = (u32)*(u32 *)piomb; |
3500 | u8 opc = (u8)((le32_to_cpu(pHeader)) & 0xFFF); | 3705 | u8 opc = (u8)(pHeader & 0xFFF); |
3501 | 3706 | ||
3502 | PM8001_MSG_DBG(pm8001_ha, pm8001_printk("process_one_iomb:")); | 3707 | PM8001_MSG_DBG(pm8001_ha, pm8001_printk("process_one_iomb:")); |
3503 | 3708 | ||
@@ -3664,9 +3869,11 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha) | |||
3664 | { | 3869 | { |
3665 | struct outbound_queue_table *circularQ; | 3870 | struct outbound_queue_table *circularQ; |
3666 | void *pMsg1 = NULL; | 3871 | void *pMsg1 = NULL; |
3667 | u8 bc = 0; | 3872 | u8 uninitialized_var(bc); |
3668 | u32 ret = MPI_IO_STATUS_FAIL; | 3873 | u32 ret = MPI_IO_STATUS_FAIL; |
3874 | unsigned long flags; | ||
3669 | 3875 | ||
3876 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
3670 | circularQ = &pm8001_ha->outbnd_q_tbl[0]; | 3877 | circularQ = &pm8001_ha->outbnd_q_tbl[0]; |
3671 | do { | 3878 | do { |
3672 | ret = mpi_msg_consume(pm8001_ha, circularQ, &pMsg1, &bc); | 3879 | ret = mpi_msg_consume(pm8001_ha, circularQ, &pMsg1, &bc); |
@@ -3677,16 +3884,16 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha) | |||
3677 | mpi_msg_free_set(pm8001_ha, pMsg1, circularQ, bc); | 3884 | mpi_msg_free_set(pm8001_ha, pMsg1, circularQ, bc); |
3678 | } | 3885 | } |
3679 | if (MPI_IO_STATUS_BUSY == ret) { | 3886 | if (MPI_IO_STATUS_BUSY == ret) { |
3680 | u32 producer_idx; | ||
3681 | /* Update the producer index from SPC */ | 3887 | /* Update the producer index from SPC */ |
3682 | producer_idx = pm8001_read_32(circularQ->pi_virt); | 3888 | circularQ->producer_index = |
3683 | circularQ->producer_index = cpu_to_le32(producer_idx); | 3889 | cpu_to_le32(pm8001_read_32(circularQ->pi_virt)); |
3684 | if (circularQ->producer_index == | 3890 | if (le32_to_cpu(circularQ->producer_index) == |
3685 | circularQ->consumer_idx) | 3891 | circularQ->consumer_idx) |
3686 | /* OQ is empty */ | 3892 | /* OQ is empty */ |
3687 | break; | 3893 | break; |
3688 | } | 3894 | } |
3689 | } while (1); | 3895 | } while (1); |
3896 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
3690 | return ret; | 3897 | return ret; |
3691 | } | 3898 | } |
3692 | 3899 | ||
@@ -3712,9 +3919,9 @@ pm8001_chip_make_sg(struct scatterlist *scatter, int nr, void *prd) | |||
3712 | } | 3919 | } |
3713 | } | 3920 | } |
3714 | 3921 | ||
3715 | static void build_smp_cmd(u32 deviceID, u32 hTag, struct smp_req *psmp_cmd) | 3922 | static void build_smp_cmd(u32 deviceID, __le32 hTag, struct smp_req *psmp_cmd) |
3716 | { | 3923 | { |
3717 | psmp_cmd->tag = cpu_to_le32(hTag); | 3924 | psmp_cmd->tag = hTag; |
3718 | psmp_cmd->device_id = cpu_to_le32(deviceID); | 3925 | psmp_cmd->device_id = cpu_to_le32(deviceID); |
3719 | psmp_cmd->len_ip_ir = cpu_to_le32(1|(1 << 1)); | 3926 | psmp_cmd->len_ip_ir = cpu_to_le32(1|(1 << 1)); |
3720 | } | 3927 | } |
@@ -3798,7 +4005,7 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, | |||
3798 | struct ssp_ini_io_start_req ssp_cmd; | 4005 | struct ssp_ini_io_start_req ssp_cmd; |
3799 | u32 tag = ccb->ccb_tag; | 4006 | u32 tag = ccb->ccb_tag; |
3800 | int ret; | 4007 | int ret; |
3801 | __le64 phys_addr; | 4008 | u64 phys_addr; |
3802 | struct inbound_queue_table *circularQ; | 4009 | struct inbound_queue_table *circularQ; |
3803 | u32 opc = OPC_INB_SSPINIIOSTART; | 4010 | u32 opc = OPC_INB_SSPINIIOSTART; |
3804 | memset(&ssp_cmd, 0, sizeof(ssp_cmd)); | 4011 | memset(&ssp_cmd, 0, sizeof(ssp_cmd)); |
@@ -3819,15 +4026,15 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, | |||
3819 | /* fill in PRD (scatter/gather) table, if any */ | 4026 | /* fill in PRD (scatter/gather) table, if any */ |
3820 | if (task->num_scatter > 1) { | 4027 | if (task->num_scatter > 1) { |
3821 | pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd); | 4028 | pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd); |
3822 | phys_addr = cpu_to_le64(ccb->ccb_dma_handle + | 4029 | phys_addr = ccb->ccb_dma_handle + |
3823 | offsetof(struct pm8001_ccb_info, buf_prd[0])); | 4030 | offsetof(struct pm8001_ccb_info, buf_prd[0]); |
3824 | ssp_cmd.addr_low = lower_32_bits(phys_addr); | 4031 | ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(phys_addr)); |
3825 | ssp_cmd.addr_high = upper_32_bits(phys_addr); | 4032 | ssp_cmd.addr_high = cpu_to_le32(upper_32_bits(phys_addr)); |
3826 | ssp_cmd.esgl = cpu_to_le32(1<<31); | 4033 | ssp_cmd.esgl = cpu_to_le32(1<<31); |
3827 | } else if (task->num_scatter == 1) { | 4034 | } else if (task->num_scatter == 1) { |
3828 | __le64 dma_addr = cpu_to_le64(sg_dma_address(task->scatter)); | 4035 | u64 dma_addr = sg_dma_address(task->scatter); |
3829 | ssp_cmd.addr_low = lower_32_bits(dma_addr); | 4036 | ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(dma_addr)); |
3830 | ssp_cmd.addr_high = upper_32_bits(dma_addr); | 4037 | ssp_cmd.addr_high = cpu_to_le32(upper_32_bits(dma_addr)); |
3831 | ssp_cmd.len = cpu_to_le32(task->total_xfer_len); | 4038 | ssp_cmd.len = cpu_to_le32(task->total_xfer_len); |
3832 | ssp_cmd.esgl = 0; | 4039 | ssp_cmd.esgl = 0; |
3833 | } else if (task->num_scatter == 0) { | 4040 | } else if (task->num_scatter == 0) { |
@@ -3850,7 +4057,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, | |||
3850 | int ret; | 4057 | int ret; |
3851 | struct sata_start_req sata_cmd; | 4058 | struct sata_start_req sata_cmd; |
3852 | u32 hdr_tag, ncg_tag = 0; | 4059 | u32 hdr_tag, ncg_tag = 0; |
3853 | __le64 phys_addr; | 4060 | u64 phys_addr; |
3854 | u32 ATAP = 0x0; | 4061 | u32 ATAP = 0x0; |
3855 | u32 dir; | 4062 | u32 dir; |
3856 | struct inbound_queue_table *circularQ; | 4063 | struct inbound_queue_table *circularQ; |
@@ -3889,13 +4096,13 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, | |||
3889 | /* fill in PRD (scatter/gather) table, if any */ | 4096 | /* fill in PRD (scatter/gather) table, if any */ |
3890 | if (task->num_scatter > 1) { | 4097 | if (task->num_scatter > 1) { |
3891 | pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd); | 4098 | pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd); |
3892 | phys_addr = cpu_to_le64(ccb->ccb_dma_handle + | 4099 | phys_addr = ccb->ccb_dma_handle + |
3893 | offsetof(struct pm8001_ccb_info, buf_prd[0])); | 4100 | offsetof(struct pm8001_ccb_info, buf_prd[0]); |
3894 | sata_cmd.addr_low = lower_32_bits(phys_addr); | 4101 | sata_cmd.addr_low = lower_32_bits(phys_addr); |
3895 | sata_cmd.addr_high = upper_32_bits(phys_addr); | 4102 | sata_cmd.addr_high = upper_32_bits(phys_addr); |
3896 | sata_cmd.esgl = cpu_to_le32(1 << 31); | 4103 | sata_cmd.esgl = cpu_to_le32(1 << 31); |
3897 | } else if (task->num_scatter == 1) { | 4104 | } else if (task->num_scatter == 1) { |
3898 | __le64 dma_addr = cpu_to_le64(sg_dma_address(task->scatter)); | 4105 | u64 dma_addr = sg_dma_address(task->scatter); |
3899 | sata_cmd.addr_low = lower_32_bits(dma_addr); | 4106 | sata_cmd.addr_low = lower_32_bits(dma_addr); |
3900 | sata_cmd.addr_high = upper_32_bits(dma_addr); | 4107 | sata_cmd.addr_high = upper_32_bits(dma_addr); |
3901 | sata_cmd.len = cpu_to_le32(task->total_xfer_len); | 4108 | 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, | |||
4039 | 4246 | ||
4040 | circularQ = &pm8001_ha->inbnd_q_tbl[0]; | 4247 | circularQ = &pm8001_ha->inbnd_q_tbl[0]; |
4041 | memset(&payload, 0, sizeof(payload)); | 4248 | memset(&payload, 0, sizeof(payload)); |
4042 | payload.tag = 1; | 4249 | payload.tag = cpu_to_le32(1); |
4043 | payload.device_id = cpu_to_le32(device_id); | 4250 | payload.device_id = cpu_to_le32(device_id); |
4044 | PM8001_MSG_DBG(pm8001_ha, | 4251 | PM8001_MSG_DBG(pm8001_ha, |
4045 | pm8001_printk("unregister device device_id = %d\n", device_id)); | 4252 | 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, | |||
4063 | u32 opc = OPC_INB_LOCAL_PHY_CONTROL; | 4270 | u32 opc = OPC_INB_LOCAL_PHY_CONTROL; |
4064 | memset(&payload, 0, sizeof(payload)); | 4271 | memset(&payload, 0, sizeof(payload)); |
4065 | circularQ = &pm8001_ha->inbnd_q_tbl[0]; | 4272 | circularQ = &pm8001_ha->inbnd_q_tbl[0]; |
4066 | payload.tag = 1; | 4273 | payload.tag = cpu_to_le32(1); |
4067 | payload.phyop_phyid = | 4274 | payload.phyop_phyid = |
4068 | cpu_to_le32(((phy_op & 0xff) << 8) | (phyId & 0x0F)); | 4275 | cpu_to_le32(((phy_op & 0xff) << 8) | (phyId & 0x0F)); |
4069 | ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); | 4276 | 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) | |||
4092 | static irqreturn_t | 4299 | static irqreturn_t |
4093 | pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha) | 4300 | pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha) |
4094 | { | 4301 | { |
4095 | unsigned long flags; | ||
4096 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
4097 | pm8001_chip_interrupt_disable(pm8001_ha); | 4302 | pm8001_chip_interrupt_disable(pm8001_ha); |
4098 | process_oq(pm8001_ha); | 4303 | process_oq(pm8001_ha); |
4099 | pm8001_chip_interrupt_enable(pm8001_ha); | 4304 | pm8001_chip_interrupt_enable(pm8001_ha); |
4100 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
4101 | return IRQ_HANDLED; | 4305 | return IRQ_HANDLED; |
4102 | } | 4306 | } |
4103 | 4307 | ||
@@ -4360,8 +4564,10 @@ pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha, | |||
4360 | payload.cur_image_offset = cpu_to_le32(info->cur_image_offset); | 4564 | payload.cur_image_offset = cpu_to_le32(info->cur_image_offset); |
4361 | payload.total_image_len = cpu_to_le32(info->total_image_len); | 4565 | payload.total_image_len = cpu_to_le32(info->total_image_len); |
4362 | payload.len = info->sgl.im_len.len ; | 4566 | payload.len = info->sgl.im_len.len ; |
4363 | payload.sgl_addr_lo = lower_32_bits(info->sgl.addr); | 4567 | payload.sgl_addr_lo = |
4364 | payload.sgl_addr_hi = upper_32_bits(info->sgl.addr); | 4568 | cpu_to_le32(lower_32_bits(le64_to_cpu(info->sgl.addr))); |
4569 | payload.sgl_addr_hi = | ||
4570 | cpu_to_le32(upper_32_bits(le64_to_cpu(info->sgl.addr))); | ||
4365 | ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); | 4571 | ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); |
4366 | return ret; | 4572 | return ret; |
4367 | } | 4573 | } |