diff options
Diffstat (limited to 'drivers/scsi/mvsas.c')
-rw-r--r-- | drivers/scsi/mvsas.c | 88 |
1 files changed, 42 insertions, 46 deletions
diff --git a/drivers/scsi/mvsas.c b/drivers/scsi/mvsas.c index 761beebcb871..b5de3d0d3f31 100644 --- a/drivers/scsi/mvsas.c +++ b/drivers/scsi/mvsas.c | |||
@@ -2743,7 +2743,7 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i, | |||
2743 | { | 2743 | { |
2744 | struct mvs_phy *phy = &mvi->phy[i]; | 2744 | struct mvs_phy *phy = &mvi->phy[i]; |
2745 | struct pci_dev *pdev = mvi->pdev; | 2745 | struct pci_dev *pdev = mvi->pdev; |
2746 | u32 tmp, j; | 2746 | u32 tmp; |
2747 | u64 tmp64; | 2747 | u64 tmp64; |
2748 | 2748 | ||
2749 | mvs_write_port_cfg_addr(mvi, i, PHYR_IDENTIFY); | 2749 | mvs_write_port_cfg_addr(mvi, i, PHYR_IDENTIFY); |
@@ -2770,46 +2770,20 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i, | |||
2770 | sas_phy->linkrate = | 2770 | sas_phy->linkrate = |
2771 | (phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >> | 2771 | (phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >> |
2772 | PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET; | 2772 | PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET; |
2773 | 2773 | phy->minimum_linkrate = | |
2774 | /* Updated attached_sas_addr */ | 2774 | (phy->phy_status & |
2775 | mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_HI); | 2775 | PHY_MIN_SPP_PHYS_LINK_RATE_MASK) >> 8; |
2776 | phy->att_dev_sas_addr = | 2776 | phy->maximum_linkrate = |
2777 | (u64) mvs_read_port_cfg_data(mvi, i) << 32; | 2777 | (phy->phy_status & |
2778 | 2778 | PHY_MAX_SPP_PHYS_LINK_RATE_MASK) >> 12; | |
2779 | mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_LO); | ||
2780 | phy->att_dev_sas_addr |= mvs_read_port_cfg_data(mvi, i); | ||
2781 | |||
2782 | dev_printk(KERN_DEBUG, &pdev->dev, | ||
2783 | "phy[%d] Get Attached Address 0x%llX ," | ||
2784 | " SAS Address 0x%llX\n", | ||
2785 | i, phy->att_dev_sas_addr, phy->dev_sas_addr); | ||
2786 | dev_printk(KERN_DEBUG, &pdev->dev, | ||
2787 | "Rate = %x , type = %d\n", | ||
2788 | sas_phy->linkrate, phy->phy_type); | ||
2789 | |||
2790 | #if 1 | ||
2791 | /* | ||
2792 | * If the device is capable of supporting a wide port | ||
2793 | * on its phys, it may configure the phys as a wide port. | ||
2794 | */ | ||
2795 | if (phy->phy_type & PORT_TYPE_SAS) | ||
2796 | for (j = 0; j < mvi->chip->n_phy && j != i; ++j) { | ||
2797 | if ((mvi->phy[j].phy_attached) && | ||
2798 | (mvi->phy[j].phy_type & PORT_TYPE_SAS)) | ||
2799 | if (phy->att_dev_sas_addr == | ||
2800 | mvi->phy[j].att_dev_sas_addr - 1) { | ||
2801 | phy->att_dev_sas_addr = | ||
2802 | mvi->phy[j].att_dev_sas_addr; | ||
2803 | break; | ||
2804 | } | ||
2805 | } | ||
2806 | |||
2807 | #endif | ||
2808 | |||
2809 | tmp64 = cpu_to_be64(phy->att_dev_sas_addr); | ||
2810 | memcpy(sas_phy->attached_sas_addr, &tmp64, SAS_ADDR_SIZE); | ||
2811 | 2779 | ||
2812 | if (phy->phy_type & PORT_TYPE_SAS) { | 2780 | if (phy->phy_type & PORT_TYPE_SAS) { |
2781 | /* Updated attached_sas_addr */ | ||
2782 | mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_HI); | ||
2783 | phy->att_dev_sas_addr = | ||
2784 | (u64) mvs_read_port_cfg_data(mvi, i) << 32; | ||
2785 | mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_LO); | ||
2786 | phy->att_dev_sas_addr |= mvs_read_port_cfg_data(mvi, i); | ||
2813 | mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_DEV_INFO); | 2787 | mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_DEV_INFO); |
2814 | phy->att_dev_info = mvs_read_port_cfg_data(mvi, i); | 2788 | phy->att_dev_info = mvs_read_port_cfg_data(mvi, i); |
2815 | phy->identify.device_type = | 2789 | phy->identify.device_type = |
@@ -2828,6 +2802,7 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i, | |||
2828 | } else if (phy->phy_type & PORT_TYPE_SATA) { | 2802 | } else if (phy->phy_type & PORT_TYPE_SATA) { |
2829 | phy->identify.target_port_protocols = SAS_PROTOCOL_STP; | 2803 | phy->identify.target_port_protocols = SAS_PROTOCOL_STP; |
2830 | if (mvs_is_sig_fis_received(phy->irq_status)) { | 2804 | if (mvs_is_sig_fis_received(phy->irq_status)) { |
2805 | phy->att_dev_sas_addr = i; /* temp */ | ||
2831 | if (phy_st & PHY_OOB_DTCTD) | 2806 | if (phy_st & PHY_OOB_DTCTD) |
2832 | sas_phy->oob_mode = SATA_OOB_MODE; | 2807 | sas_phy->oob_mode = SATA_OOB_MODE; |
2833 | phy->frame_rcvd_size = | 2808 | phy->frame_rcvd_size = |
@@ -2837,20 +2812,34 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i, | |||
2837 | } else { | 2812 | } else { |
2838 | dev_printk(KERN_DEBUG, &pdev->dev, | 2813 | dev_printk(KERN_DEBUG, &pdev->dev, |
2839 | "No sig fis\n"); | 2814 | "No sig fis\n"); |
2815 | phy->phy_type &= ~(PORT_TYPE_SATA); | ||
2816 | goto out_done; | ||
2840 | } | 2817 | } |
2841 | } | 2818 | } |
2819 | tmp64 = cpu_to_be64(phy->att_dev_sas_addr); | ||
2820 | memcpy(sas_phy->attached_sas_addr, &tmp64, SAS_ADDR_SIZE); | ||
2821 | |||
2822 | dev_printk(KERN_DEBUG, &pdev->dev, | ||
2823 | "phy[%d] Get Attached Address 0x%llX ," | ||
2824 | " SAS Address 0x%llX\n", | ||
2825 | i, phy->att_dev_sas_addr, phy->dev_sas_addr); | ||
2826 | dev_printk(KERN_DEBUG, &pdev->dev, | ||
2827 | "Rate = %x , type = %d\n", | ||
2828 | sas_phy->linkrate, phy->phy_type); | ||
2829 | |||
2842 | /* workaround for HW phy decoding error on 1.5g disk drive */ | 2830 | /* workaround for HW phy decoding error on 1.5g disk drive */ |
2843 | mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE6); | 2831 | mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE6); |
2844 | tmp = mvs_read_port_vsr_data(mvi, i); | 2832 | tmp = mvs_read_port_vsr_data(mvi, i); |
2845 | if (((phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >> | 2833 | if (((phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >> |
2846 | PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET) == | 2834 | PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET) == |
2847 | SAS_LINK_RATE_1_5_GBPS) | 2835 | SAS_LINK_RATE_1_5_GBPS) |
2848 | tmp &= ~PHY_MODE6_DTL_SPEED; | 2836 | tmp &= ~PHY_MODE6_LATECLK; |
2849 | else | 2837 | else |
2850 | tmp |= PHY_MODE6_DTL_SPEED; | 2838 | tmp |= PHY_MODE6_LATECLK; |
2851 | mvs_write_port_vsr_data(mvi, i, tmp); | 2839 | mvs_write_port_vsr_data(mvi, i, tmp); |
2852 | 2840 | ||
2853 | } | 2841 | } |
2842 | out_done: | ||
2854 | if (get_st) | 2843 | if (get_st) |
2855 | mvs_write_port_irq_stat(mvi, i, phy->irq_status); | 2844 | mvs_write_port_irq_stat(mvi, i, phy->irq_status); |
2856 | } | 2845 | } |
@@ -2875,6 +2864,11 @@ static void mvs_port_formed(struct asd_sas_phy *sas_phy) | |||
2875 | spin_unlock_irqrestore(&mvi->lock, flags); | 2864 | spin_unlock_irqrestore(&mvi->lock, flags); |
2876 | } | 2865 | } |
2877 | 2866 | ||
2867 | static int mvs_I_T_nexus_reset(struct domain_device *dev) | ||
2868 | { | ||
2869 | return TMF_RESP_FUNC_FAILED; | ||
2870 | } | ||
2871 | |||
2878 | static int __devinit mvs_hw_init(struct mvs_info *mvi) | 2872 | static int __devinit mvs_hw_init(struct mvs_info *mvi) |
2879 | { | 2873 | { |
2880 | void __iomem *regs = mvi->regs; | 2874 | void __iomem *regs = mvi->regs; |
@@ -3036,13 +3030,12 @@ static int __devinit mvs_hw_init(struct mvs_info *mvi) | |||
3036 | /* enable CMD/CMPL_Q/RESP mode */ | 3030 | /* enable CMD/CMPL_Q/RESP mode */ |
3037 | mw32(PCS, PCS_SATA_RETRY | PCS_FIS_RX_EN | PCS_CMD_EN); | 3031 | mw32(PCS, PCS_SATA_RETRY | PCS_FIS_RX_EN | PCS_CMD_EN); |
3038 | 3032 | ||
3039 | /* re-enable interrupts globally */ | ||
3040 | mvs_hba_interrupt_enable(mvi); | ||
3041 | |||
3042 | /* enable completion queue interrupt */ | 3033 | /* enable completion queue interrupt */ |
3043 | tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM); | 3034 | tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS); |
3044 | mw32(INT_MASK, tmp); | 3035 | mw32(INT_MASK, tmp); |
3045 | 3036 | ||
3037 | /* Enable SRS interrupt */ | ||
3038 | mw32(INT_MASK_SRS, 0xFF); | ||
3046 | return 0; | 3039 | return 0; |
3047 | } | 3040 | } |
3048 | 3041 | ||
@@ -3116,6 +3109,8 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev, | |||
3116 | 3109 | ||
3117 | mvs_print_info(mvi); | 3110 | mvs_print_info(mvi); |
3118 | 3111 | ||
3112 | mvs_hba_interrupt_enable(mvi); | ||
3113 | |||
3119 | scsi_scan_host(mvi->shost); | 3114 | scsi_scan_host(mvi->shost); |
3120 | 3115 | ||
3121 | return 0; | 3116 | return 0; |
@@ -3161,7 +3156,8 @@ static struct sas_domain_function_template mvs_transport_ops = { | |||
3161 | .lldd_execute_task = mvs_task_exec, | 3156 | .lldd_execute_task = mvs_task_exec, |
3162 | .lldd_control_phy = mvs_phy_control, | 3157 | .lldd_control_phy = mvs_phy_control, |
3163 | .lldd_abort_task = mvs_task_abort, | 3158 | .lldd_abort_task = mvs_task_abort, |
3164 | .lldd_port_formed = mvs_port_formed | 3159 | .lldd_port_formed = mvs_port_formed, |
3160 | .lldd_I_T_nexus_reset = mvs_I_T_nexus_reset, | ||
3165 | }; | 3161 | }; |
3166 | 3162 | ||
3167 | static struct pci_device_id __devinitdata mvs_pci_table[] = { | 3163 | static struct pci_device_id __devinitdata mvs_pci_table[] = { |