aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mvsas.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mvsas.c')
-rw-r--r--drivers/scsi/mvsas.c88
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 }
2842out_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
2867static int mvs_I_T_nexus_reset(struct domain_device *dev)
2868{
2869 return TMF_RESP_FUNC_FAILED;
2870}
2871
2878static int __devinit mvs_hw_init(struct mvs_info *mvi) 2872static 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
3167static struct pci_device_id __devinitdata mvs_pci_table[] = { 3163static struct pci_device_id __devinitdata mvs_pci_table[] = {