diff options
author | Xiangliang Yu <yuxiangl@marvell.com> | 2011-05-24 10:36:02 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-07-26 02:36:11 -0400 |
commit | a4632aae8b662b1f32fe3fc558a813cd5c3daae6 (patch) | |
tree | a88ee045018877314d76b9cb99e3e837b78d5565 /drivers/scsi/mvsas/mv_94xx.c | |
parent | b89e8f539ff8bcf2a1464578fa91cb96cc433fc3 (diff) |
[SCSI] mvsas: Add new macros and functions
Add new macros: MVS_SOFT_RESET, MVS_HARD_RESET, MVS_PHY_TUNE,
MVS_COMMAND_ACTIVE, EXP_BRCT_CHG, MVS_MAX_SG
Add new member sg_width in struct mvs_chip_info
Use macros rather than magic number
Add new functions: mvs_fill_ssp_resp_iu, mvs_set_sense,
mvs_94xx_clear_srs_irq, mvs_94xx_phy_set_link_rate
Signed-off-by: Xiangliang Yu <yuxiangl@marvell.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/mvsas/mv_94xx.c')
-rw-r--r-- | drivers/scsi/mvsas/mv_94xx.c | 80 |
1 files changed, 59 insertions, 21 deletions
diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c index 5b25f1b7fa52..a0ec4aaa24a2 100644 --- a/drivers/scsi/mvsas/mv_94xx.c +++ b/drivers/scsi/mvsas/mv_94xx.c | |||
@@ -389,7 +389,7 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi) | |||
389 | mvs_phy_hacks(mvi); | 389 | mvs_phy_hacks(mvi); |
390 | 390 | ||
391 | /* set LED blink when IO*/ | 391 | /* set LED blink when IO*/ |
392 | mw32(MVS_PA_VSR_ADDR, 0x00000030); | 392 | mw32(MVS_PA_VSR_ADDR, VSR_PHY_ACT_LED); |
393 | tmp = mr32(MVS_PA_VSR_PORT); | 393 | tmp = mr32(MVS_PA_VSR_PORT); |
394 | tmp &= 0xFFFF00FF; | 394 | tmp &= 0xFFFF00FF; |
395 | tmp |= 0x00003300; | 395 | tmp |= 0x00003300; |
@@ -419,7 +419,7 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi) | |||
419 | mvs_94xx_config_reg_from_hba(mvi, i); | 419 | mvs_94xx_config_reg_from_hba(mvi, i); |
420 | mvs_94xx_phy_enable(mvi, i); | 420 | mvs_94xx_phy_enable(mvi, i); |
421 | 421 | ||
422 | mvs_94xx_phy_reset(mvi, i, 1); | 422 | mvs_94xx_phy_reset(mvi, i, PHY_RST_HARD); |
423 | msleep(500); | 423 | msleep(500); |
424 | mvs_94xx_detect_porttype(mvi, i); | 424 | mvs_94xx_detect_porttype(mvi, i); |
425 | } | 425 | } |
@@ -585,10 +585,48 @@ static irqreturn_t mvs_94xx_isr(struct mvs_info *mvi, int irq, u32 stat) | |||
585 | static void mvs_94xx_command_active(struct mvs_info *mvi, u32 slot_idx) | 585 | static void mvs_94xx_command_active(struct mvs_info *mvi, u32 slot_idx) |
586 | { | 586 | { |
587 | u32 tmp; | 587 | u32 tmp; |
588 | mvs_cw32(mvi, 0x300 + (slot_idx >> 3), 1 << (slot_idx % 32)); | 588 | tmp = mvs_cr32(mvi, MVS_COMMAND_ACTIVE+(slot_idx >> 3)); |
589 | do { | 589 | if (tmp && 1 << (slot_idx % 32)) { |
590 | tmp = mvs_cr32(mvi, 0x300 + (slot_idx >> 3)); | 590 | mv_printk("command active %08X, slot [%x].\n", tmp, slot_idx); |
591 | } while (tmp & 1 << (slot_idx % 32)); | 591 | mvs_cw32(mvi, MVS_COMMAND_ACTIVE + (slot_idx >> 3), |
592 | 1 << (slot_idx % 32)); | ||
593 | do { | ||
594 | tmp = mvs_cr32(mvi, | ||
595 | MVS_COMMAND_ACTIVE + (slot_idx >> 3)); | ||
596 | } while (tmp & 1 << (slot_idx % 32)); | ||
597 | } | ||
598 | } | ||
599 | |||
600 | void mvs_94xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set, u8 clear_all) | ||
601 | { | ||
602 | void __iomem *regs = mvi->regs; | ||
603 | u32 tmp; | ||
604 | |||
605 | if (clear_all) { | ||
606 | tmp = mr32(MVS_INT_STAT_SRS_0); | ||
607 | if (tmp) { | ||
608 | mv_dprintk("check SRS 0 %08X.\n", tmp); | ||
609 | mw32(MVS_INT_STAT_SRS_0, tmp); | ||
610 | } | ||
611 | tmp = mr32(MVS_INT_STAT_SRS_1); | ||
612 | if (tmp) { | ||
613 | mv_dprintk("check SRS 1 %08X.\n", tmp); | ||
614 | mw32(MVS_INT_STAT_SRS_1, tmp); | ||
615 | } | ||
616 | } else { | ||
617 | if (reg_set > 31) | ||
618 | tmp = mr32(MVS_INT_STAT_SRS_1); | ||
619 | else | ||
620 | tmp = mr32(MVS_INT_STAT_SRS_0); | ||
621 | |||
622 | if (tmp & (1 << (reg_set % 32))) { | ||
623 | mv_dprintk("register set 0x%x was stopped.\n", reg_set); | ||
624 | if (reg_set > 31) | ||
625 | mw32(MVS_INT_STAT_SRS_1, 1 << (reg_set % 32)); | ||
626 | else | ||
627 | mw32(MVS_INT_STAT_SRS_0, 1 << (reg_set % 32)); | ||
628 | } | ||
629 | } | ||
592 | } | 630 | } |
593 | 631 | ||
594 | static void mvs_94xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type, | 632 | static void mvs_94xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type, |
@@ -596,12 +634,10 @@ static void mvs_94xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type, | |||
596 | { | 634 | { |
597 | void __iomem *regs = mvi->regs; | 635 | void __iomem *regs = mvi->regs; |
598 | u32 tmp; | 636 | u32 tmp; |
637 | mvs_94xx_clear_srs_irq(mvi, 0, 1); | ||
599 | 638 | ||
600 | if (type == PORT_TYPE_SATA) { | 639 | tmp = mr32(MVS_INT_STAT); |
601 | tmp = mr32(MVS_INT_STAT_SRS_0) | (1U << tfs); | 640 | mw32(MVS_INT_STAT, tmp | CINT_CI_STOP); |
602 | mw32(MVS_INT_STAT_SRS_0, tmp); | ||
603 | } | ||
604 | mw32(MVS_INT_STAT, CINT_CI_STOP); | ||
605 | tmp = mr32(MVS_PCS) | 0xFF00; | 641 | tmp = mr32(MVS_PCS) | 0xFF00; |
606 | mw32(MVS_PCS, tmp); | 642 | mw32(MVS_PCS, tmp); |
607 | } | 643 | } |
@@ -794,7 +830,18 @@ static void mvs_94xx_fix_phy_info(struct mvs_info *mvi, int i, | |||
794 | void mvs_94xx_phy_set_link_rate(struct mvs_info *mvi, u32 phy_id, | 830 | void mvs_94xx_phy_set_link_rate(struct mvs_info *mvi, u32 phy_id, |
795 | struct sas_phy_linkrates *rates) | 831 | struct sas_phy_linkrates *rates) |
796 | { | 832 | { |
797 | /* TODO */ | 833 | u32 lrmax = 0; |
834 | u32 tmp; | ||
835 | |||
836 | tmp = mvs_read_phy_ctl(mvi, phy_id); | ||
837 | lrmax = (rates->maximum_linkrate - SAS_LINK_RATE_1_5_GBPS) << 12; | ||
838 | |||
839 | if (lrmax) { | ||
840 | tmp &= ~(0x3 << 12); | ||
841 | tmp |= lrmax; | ||
842 | } | ||
843 | mvs_write_phy_ctl(mvi, phy_id, tmp); | ||
844 | mvs_94xx_phy_reset(mvi, phy_id, PHY_RST_HARD); | ||
798 | } | 845 | } |
799 | 846 | ||
800 | static void mvs_94xx_clear_active_cmds(struct mvs_info *mvi) | 847 | static void mvs_94xx_clear_active_cmds(struct mvs_info *mvi) |
@@ -893,15 +940,6 @@ void mvs_94xx_fix_dma(struct mvs_info *mvi, u32 phy_mask, | |||
893 | } | 940 | } |
894 | } | 941 | } |
895 | 942 | ||
896 | /* | ||
897 | * FIXME JEJB: temporary nop clear_srs_irq to make 94xx still work | ||
898 | * with 64xx fixes | ||
899 | */ | ||
900 | static void mvs_94xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set, | ||
901 | u8 clear_all) | ||
902 | { | ||
903 | } | ||
904 | |||
905 | static void mvs_94xx_tune_interrupt(struct mvs_info *mvi, u32 time) | 943 | static void mvs_94xx_tune_interrupt(struct mvs_info *mvi, u32 time) |
906 | { | 944 | { |
907 | void __iomem *regs = mvi->regs; | 945 | void __iomem *regs = mvi->regs; |