diff options
author | Xiangliang Yu <yuxiangl@marvell.com> | 2011-05-24 10:37:25 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-07-26 02:38:01 -0400 |
commit | 84fbd0cea11b80d7b7097343d5262004d42b8a9a (patch) | |
tree | a59d58e1ce8558f02dba14e0cb335ee8bb666306 /drivers/scsi/mvsas | |
parent | a4632aae8b662b1f32fe3fc558a813cd5c3daae6 (diff) |
[SCSI] mvsas: misc improvements
Change code to match HBA datasheet.
Change code to make it readable.
Add support big endian for mvs_prd_imt.
Add cpu_to_le32 and cpu_to_le64 to use on addr.
Add scan_finished for structure mvs_prv_info.
Signed-off-by: Xiangliang Yu <yuxiangl@marvell.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/mvsas')
-rw-r--r-- | drivers/scsi/mvsas/mv_64xx.c | 28 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_94xx.c | 72 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_94xx.h | 13 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_chips.h | 12 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_init.c | 3 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_sas.c | 109 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_sas.h | 3 |
7 files changed, 127 insertions, 113 deletions
diff --git a/drivers/scsi/mvsas/mv_64xx.c b/drivers/scsi/mvsas/mv_64xx.c index 702c767ee46f..bc75ba7488d8 100644 --- a/drivers/scsi/mvsas/mv_64xx.c +++ b/drivers/scsi/mvsas/mv_64xx.c | |||
@@ -58,24 +58,17 @@ static void __devinit mvs_64xx_enable_xmt(struct mvs_info *mvi, int phy_id) | |||
58 | static void __devinit mvs_64xx_phy_hacks(struct mvs_info *mvi) | 58 | static void __devinit mvs_64xx_phy_hacks(struct mvs_info *mvi) |
59 | { | 59 | { |
60 | void __iomem *regs = mvi->regs; | 60 | void __iomem *regs = mvi->regs; |
61 | int i; | ||
61 | 62 | ||
62 | mvs_phy_hacks(mvi); | 63 | mvs_phy_hacks(mvi); |
63 | 64 | ||
64 | if (!(mvi->flags & MVF_FLAG_SOC)) { | 65 | if (!(mvi->flags & MVF_FLAG_SOC)) { |
65 | /* TEST - for phy decoding error, adjust voltage levels */ | 66 | /* TEST - for phy decoding error, adjust voltage levels */ |
66 | mw32(MVS_P0_VSR_ADDR + 0, 0x8); | 67 | for (i = 0; i < MVS_SOC_PORTS; i++) { |
67 | mw32(MVS_P0_VSR_DATA + 0, 0x2F0); | 68 | mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE8); |
68 | 69 | mvs_write_port_vsr_data(mvi, i, 0x2F0); | |
69 | mw32(MVS_P0_VSR_ADDR + 8, 0x8); | 70 | } |
70 | mw32(MVS_P0_VSR_DATA + 8, 0x2F0); | ||
71 | |||
72 | mw32(MVS_P0_VSR_ADDR + 16, 0x8); | ||
73 | mw32(MVS_P0_VSR_DATA + 16, 0x2F0); | ||
74 | |||
75 | mw32(MVS_P0_VSR_ADDR + 24, 0x8); | ||
76 | mw32(MVS_P0_VSR_DATA + 24, 0x2F0); | ||
77 | } else { | 71 | } else { |
78 | int i; | ||
79 | /* disable auto port detection */ | 72 | /* disable auto port detection */ |
80 | mw32(MVS_GBL_PORT_TYPE, 0); | 73 | mw32(MVS_GBL_PORT_TYPE, 0); |
81 | for (i = 0; i < mvi->chip->n_phy; i++) { | 74 | for (i = 0; i < mvi->chip->n_phy; i++) { |
@@ -321,6 +314,11 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi) | |||
321 | /* init phys */ | 314 | /* init phys */ |
322 | mvs_64xx_phy_hacks(mvi); | 315 | mvs_64xx_phy_hacks(mvi); |
323 | 316 | ||
317 | tmp = mvs_cr32(mvi, CMD_PHY_MODE_21); | ||
318 | tmp &= 0x0000ffff; | ||
319 | tmp |= 0x00fa0000; | ||
320 | mvs_cw32(mvi, CMD_PHY_MODE_21, tmp); | ||
321 | |||
324 | /* enable auto port detection */ | 322 | /* enable auto port detection */ |
325 | mw32(MVS_GBL_PORT_TYPE, MODE_AUTO_DET_EN); | 323 | mw32(MVS_GBL_PORT_TYPE, MODE_AUTO_DET_EN); |
326 | 324 | ||
@@ -394,13 +392,17 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi) | |||
394 | /* reset CMD queue */ | 392 | /* reset CMD queue */ |
395 | tmp = mr32(MVS_PCS); | 393 | tmp = mr32(MVS_PCS); |
396 | tmp |= PCS_CMD_RST; | 394 | tmp |= PCS_CMD_RST; |
395 | tmp &= ~PCS_SELF_CLEAR; | ||
397 | mw32(MVS_PCS, tmp); | 396 | mw32(MVS_PCS, tmp); |
398 | /* interrupt coalescing may cause missing HW interrput in some case, | 397 | /* interrupt coalescing may cause missing HW interrput in some case, |
399 | * and the max count is 0x1ff, while our max slot is 0x200, | 398 | * and the max count is 0x1ff, while our max slot is 0x200, |
400 | * it will make count 0. | 399 | * it will make count 0. |
401 | */ | 400 | */ |
402 | tmp = 0; | 401 | tmp = 0; |
403 | mw32(MVS_INT_COAL, tmp); | 402 | if (MVS_CHIP_SLOT_SZ > 0x1ff) |
403 | mw32(MVS_INT_COAL, 0x1ff | COAL_EN); | ||
404 | else | ||
405 | mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ | COAL_EN); | ||
404 | 406 | ||
405 | tmp = 0x10000 | interrupt_coalescing; | 407 | tmp = 0x10000 | interrupt_coalescing; |
406 | mw32(MVS_INT_COAL_TMOUT, tmp); | 408 | mw32(MVS_INT_COAL_TMOUT, tmp); |
diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c index a0ec4aaa24a2..1276e494b868 100644 --- a/drivers/scsi/mvsas/mv_94xx.c +++ b/drivers/scsi/mvsas/mv_94xx.c | |||
@@ -271,7 +271,14 @@ static void __devinit mvs_94xx_enable_xmt(struct mvs_info *mvi, int phy_id) | |||
271 | static void mvs_94xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard) | 271 | static void mvs_94xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard) |
272 | { | 272 | { |
273 | u32 tmp; | 273 | u32 tmp; |
274 | 274 | u32 delay = 5000; | |
275 | if (hard == MVS_PHY_TUNE) { | ||
276 | mvs_write_port_cfg_addr(mvi, phy_id, PHYR_SATA_CTL); | ||
277 | tmp = mvs_read_port_cfg_data(mvi, phy_id); | ||
278 | mvs_write_port_cfg_data(mvi, phy_id, tmp|0x20000000); | ||
279 | mvs_write_port_cfg_data(mvi, phy_id, tmp|0x100000); | ||
280 | return; | ||
281 | } | ||
275 | tmp = mvs_read_port_irq_stat(mvi, phy_id); | 282 | tmp = mvs_read_port_irq_stat(mvi, phy_id); |
276 | tmp &= ~PHYEV_RDY_CH; | 283 | tmp &= ~PHYEV_RDY_CH; |
277 | mvs_write_port_irq_stat(mvi, phy_id, tmp); | 284 | mvs_write_port_irq_stat(mvi, phy_id, tmp); |
@@ -281,12 +288,15 @@ static void mvs_94xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard) | |||
281 | mvs_write_phy_ctl(mvi, phy_id, tmp); | 288 | mvs_write_phy_ctl(mvi, phy_id, tmp); |
282 | do { | 289 | do { |
283 | tmp = mvs_read_phy_ctl(mvi, phy_id); | 290 | tmp = mvs_read_phy_ctl(mvi, phy_id); |
284 | } while (tmp & PHY_RST_HARD); | 291 | udelay(10); |
292 | delay--; | ||
293 | } while ((tmp & PHY_RST_HARD) && delay); | ||
294 | if (!delay) | ||
295 | mv_dprintk("phy hard reset failed.\n"); | ||
285 | } else { | 296 | } else { |
286 | mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_STAT); | 297 | tmp = mvs_read_phy_ctl(mvi, phy_id); |
287 | tmp = mvs_read_port_vsr_data(mvi, phy_id); | ||
288 | tmp |= PHY_RST; | 298 | tmp |= PHY_RST; |
289 | mvs_write_port_vsr_data(mvi, phy_id, tmp); | 299 | mvs_write_phy_ctl(mvi, phy_id, tmp); |
290 | } | 300 | } |
291 | } | 301 | } |
292 | 302 | ||
@@ -413,7 +423,7 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi) | |||
413 | mvs_94xx_phy_disable(mvi, i); | 423 | mvs_94xx_phy_disable(mvi, i); |
414 | /* set phy local SAS address */ | 424 | /* set phy local SAS address */ |
415 | mvs_set_sas_addr(mvi, i, CONFIG_ID_FRAME3, CONFIG_ID_FRAME4, | 425 | mvs_set_sas_addr(mvi, i, CONFIG_ID_FRAME3, CONFIG_ID_FRAME4, |
416 | (mvi->phy[i].dev_sas_addr)); | 426 | cpu_to_le64(mvi->phy[i].dev_sas_addr)); |
417 | 427 | ||
418 | mvs_94xx_enable_xmt(mvi, i); | 428 | mvs_94xx_enable_xmt(mvi, i); |
419 | mvs_94xx_config_reg_from_hba(mvi, i); | 429 | mvs_94xx_config_reg_from_hba(mvi, i); |
@@ -459,7 +469,6 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi) | |||
459 | */ | 469 | */ |
460 | cctl = mr32(MVS_CTL); | 470 | cctl = mr32(MVS_CTL); |
461 | cctl |= CCTL_ENDIAN_CMD; | 471 | cctl |= CCTL_ENDIAN_CMD; |
462 | cctl |= CCTL_ENDIAN_DATA; | ||
463 | cctl &= ~CCTL_ENDIAN_OPEN; | 472 | cctl &= ~CCTL_ENDIAN_OPEN; |
464 | cctl |= CCTL_ENDIAN_RSP; | 473 | cctl |= CCTL_ENDIAN_RSP; |
465 | mw32_f(MVS_CTL, cctl); | 474 | mw32_f(MVS_CTL, cctl); |
@@ -467,13 +476,17 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi) | |||
467 | /* reset CMD queue */ | 476 | /* reset CMD queue */ |
468 | tmp = mr32(MVS_PCS); | 477 | tmp = mr32(MVS_PCS); |
469 | tmp |= PCS_CMD_RST; | 478 | tmp |= PCS_CMD_RST; |
479 | tmp &= ~PCS_SELF_CLEAR; | ||
470 | mw32(MVS_PCS, tmp); | 480 | mw32(MVS_PCS, tmp); |
471 | /* interrupt coalescing may cause missing HW interrput in some case, | 481 | /* interrupt coalescing may cause missing HW interrput in some case, |
472 | * and the max count is 0x1ff, while our max slot is 0x200, | 482 | * and the max count is 0x1ff, while our max slot is 0x200, |
473 | * it will make count 0. | 483 | * it will make count 0. |
474 | */ | 484 | */ |
475 | tmp = 0; | 485 | tmp = 0; |
476 | mw32(MVS_INT_COAL, tmp); | 486 | if (MVS_CHIP_SLOT_SZ > 0x1ff) |
487 | mw32(MVS_INT_COAL, 0x1ff | COAL_EN); | ||
488 | else | ||
489 | mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ | COAL_EN); | ||
477 | 490 | ||
478 | tmp = 0x10000 | interrupt_coalescing; | 491 | tmp = 0x10000 | interrupt_coalescing; |
479 | mw32(MVS_INT_COAL_TMOUT, tmp); | 492 | mw32(MVS_INT_COAL_TMOUT, tmp); |
@@ -674,24 +687,16 @@ static void mvs_94xx_non_spec_ncq_error(struct mvs_info *mvi) | |||
674 | static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs) | 687 | static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs) |
675 | { | 688 | { |
676 | void __iomem *regs = mvi->regs; | 689 | void __iomem *regs = mvi->regs; |
677 | u32 tmp; | ||
678 | u8 reg_set = *tfs; | 690 | u8 reg_set = *tfs; |
679 | 691 | ||
680 | if (*tfs == MVS_ID_NOT_MAPPED) | 692 | if (*tfs == MVS_ID_NOT_MAPPED) |
681 | return; | 693 | return; |
682 | 694 | ||
683 | mvi->sata_reg_set &= ~bit(reg_set); | 695 | mvi->sata_reg_set &= ~bit(reg_set); |
684 | if (reg_set < 32) { | 696 | if (reg_set < 32) |
685 | w_reg_set_enable(reg_set, (u32)mvi->sata_reg_set); | 697 | w_reg_set_enable(reg_set, (u32)mvi->sata_reg_set); |
686 | tmp = mr32(MVS_INT_STAT_SRS_0) & (u32)mvi->sata_reg_set; | 698 | else |
687 | if (tmp) | 699 | w_reg_set_enable(reg_set, (u32)(mvi->sata_reg_set >> 32)); |
688 | mw32(MVS_INT_STAT_SRS_0, tmp); | ||
689 | } else { | ||
690 | w_reg_set_enable(reg_set, mvi->sata_reg_set); | ||
691 | tmp = mr32(MVS_INT_STAT_SRS_1) & mvi->sata_reg_set; | ||
692 | if (tmp) | ||
693 | mw32(MVS_INT_STAT_SRS_1, tmp); | ||
694 | } | ||
695 | 700 | ||
696 | *tfs = MVS_ID_NOT_MAPPED; | 701 | *tfs = MVS_ID_NOT_MAPPED; |
697 | 702 | ||
@@ -707,7 +712,7 @@ static u8 mvs_94xx_assign_reg_set(struct mvs_info *mvi, u8 *tfs) | |||
707 | return 0; | 712 | return 0; |
708 | 713 | ||
709 | i = mv_ffc64(mvi->sata_reg_set); | 714 | i = mv_ffc64(mvi->sata_reg_set); |
710 | if (i > 32) { | 715 | if (i >= 32) { |
711 | mvi->sata_reg_set |= bit(i); | 716 | mvi->sata_reg_set |= bit(i); |
712 | w_reg_set_enable(i, (u32)(mvi->sata_reg_set >> 32)); | 717 | w_reg_set_enable(i, (u32)(mvi->sata_reg_set >> 32)); |
713 | *tfs = i; | 718 | *tfs = i; |
@@ -726,9 +731,12 @@ static void mvs_94xx_make_prd(struct scatterlist *scatter, int nr, void *prd) | |||
726 | int i; | 731 | int i; |
727 | struct scatterlist *sg; | 732 | struct scatterlist *sg; |
728 | struct mvs_prd *buf_prd = prd; | 733 | struct mvs_prd *buf_prd = prd; |
734 | struct mvs_prd_imt im_len; | ||
735 | *(u32 *)&im_len = 0; | ||
729 | for_each_sg(scatter, sg, nr, i) { | 736 | for_each_sg(scatter, sg, nr, i) { |
730 | buf_prd->addr = cpu_to_le64(sg_dma_address(sg)); | 737 | buf_prd->addr = cpu_to_le64(sg_dma_address(sg)); |
731 | buf_prd->im_len.len = cpu_to_le32(sg_dma_len(sg)); | 738 | im_len.len = sg_dma_len(sg); |
739 | buf_prd->im_len = cpu_to_le32(*(u32 *)&im_len); | ||
732 | buf_prd++; | 740 | buf_prd++; |
733 | } | 741 | } |
734 | } | 742 | } |
@@ -751,7 +759,7 @@ static void mvs_94xx_get_dev_identify_frame(struct mvs_info *mvi, int port_id, | |||
751 | for (i = 0; i < 7; i++) { | 759 | for (i = 0; i < 7; i++) { |
752 | mvs_write_port_cfg_addr(mvi, port_id, | 760 | mvs_write_port_cfg_addr(mvi, port_id, |
753 | CONFIG_ID_FRAME0 + i * 4); | 761 | CONFIG_ID_FRAME0 + i * 4); |
754 | id_frame[i] = mvs_read_port_cfg_data(mvi, port_id); | 762 | id_frame[i] = cpu_to_le32(mvs_read_port_cfg_data(mvi, port_id)); |
755 | } | 763 | } |
756 | memcpy(id, id_frame, 28); | 764 | memcpy(id, id_frame, 28); |
757 | } | 765 | } |
@@ -766,7 +774,7 @@ static void mvs_94xx_get_att_identify_frame(struct mvs_info *mvi, int port_id, | |||
766 | for (i = 0; i < 7; i++) { | 774 | for (i = 0; i < 7; i++) { |
767 | mvs_write_port_cfg_addr(mvi, port_id, | 775 | mvs_write_port_cfg_addr(mvi, port_id, |
768 | CONFIG_ATT_ID_FRAME0 + i * 4); | 776 | CONFIG_ATT_ID_FRAME0 + i * 4); |
769 | id_frame[i] = mvs_read_port_cfg_data(mvi, port_id); | 777 | id_frame[i] = cpu_to_le32(mvs_read_port_cfg_data(mvi, port_id)); |
770 | mv_dprintk("94xx phy %d atta frame %d %x.\n", | 778 | mv_dprintk("94xx phy %d atta frame %d %x.\n", |
771 | port_id + mvi->id * mvi->chip->n_phy, i, id_frame[i]); | 779 | port_id + mvi->id * mvi->chip->n_phy, i, id_frame[i]); |
772 | } | 780 | } |
@@ -924,8 +932,12 @@ void mvs_94xx_fix_dma(struct mvs_info *mvi, u32 phy_mask, | |||
924 | int i; | 932 | int i; |
925 | struct mvs_prd *buf_prd = prd; | 933 | struct mvs_prd *buf_prd = prd; |
926 | dma_addr_t buf_dma; | 934 | dma_addr_t buf_dma; |
935 | struct mvs_prd_imt im_len; | ||
936 | |||
937 | *(u32 *)&im_len = 0; | ||
927 | buf_prd += from; | 938 | buf_prd += from; |
928 | 939 | ||
940 | #define PRD_CHAINED_ENTRY 0x01 | ||
929 | if ((mvi->pdev->revision == VANIR_A0_REV) || | 941 | if ((mvi->pdev->revision == VANIR_A0_REV) || |
930 | (mvi->pdev->revision == VANIR_B0_REV)) | 942 | (mvi->pdev->revision == VANIR_B0_REV)) |
931 | buf_dma = (phy_mask <= 0x08) ? | 943 | buf_dma = (phy_mask <= 0x08) ? |
@@ -933,10 +945,16 @@ void mvs_94xx_fix_dma(struct mvs_info *mvi, u32 phy_mask, | |||
933 | else | 945 | else |
934 | return; | 946 | return; |
935 | 947 | ||
936 | for (i = 0; i < MAX_SG_ENTRY - from; i++) { | 948 | for (i = from; i < MAX_SG_ENTRY; i++, ++buf_prd) { |
937 | buf_prd->addr = cpu_to_le64(buf_dma); | 949 | if (i == MAX_SG_ENTRY - 1) { |
938 | buf_prd->im_len.len = cpu_to_le32(buf_len); | 950 | buf_prd->addr = cpu_to_le64(virt_to_phys(buf_prd - 1)); |
939 | ++buf_prd; | 951 | im_len.len = 2; |
952 | im_len.misc_ctl = PRD_CHAINED_ENTRY; | ||
953 | } else { | ||
954 | buf_prd->addr = cpu_to_le64(buf_dma); | ||
955 | im_len.len = buf_len; | ||
956 | } | ||
957 | buf_prd->im_len = cpu_to_le32(*(u32 *)&im_len); | ||
940 | } | 958 | } |
941 | } | 959 | } |
942 | 960 | ||
diff --git a/drivers/scsi/mvsas/mv_94xx.h b/drivers/scsi/mvsas/mv_94xx.h index 6fc2c105c9d7..d8c12e057ae8 100644 --- a/drivers/scsi/mvsas/mv_94xx.h +++ b/drivers/scsi/mvsas/mv_94xx.h | |||
@@ -142,8 +142,8 @@ enum sas_sata_vsp_regs { | |||
142 | 142 | ||
143 | enum chip_register_bits { | 143 | enum chip_register_bits { |
144 | PHY_MIN_SPP_PHYS_LINK_RATE_MASK = (0x7 << 8), | 144 | PHY_MIN_SPP_PHYS_LINK_RATE_MASK = (0x7 << 8), |
145 | PHY_MAX_SPP_PHYS_LINK_RATE_MASK = (0x7 << 8), | 145 | PHY_MAX_SPP_PHYS_LINK_RATE_MASK = (0x7 << 12), |
146 | PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET = (12), | 146 | PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET = (16), |
147 | PHY_NEG_SPP_PHYS_LINK_RATE_MASK = | 147 | PHY_NEG_SPP_PHYS_LINK_RATE_MASK = |
148 | (0x3 << PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET), | 148 | (0x3 << PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET), |
149 | }; | 149 | }; |
@@ -219,17 +219,24 @@ union reg_phy_cfg { | |||
219 | #define MAX_SG_ENTRY 255 | 219 | #define MAX_SG_ENTRY 255 |
220 | 220 | ||
221 | struct mvs_prd_imt { | 221 | struct mvs_prd_imt { |
222 | #ifndef __BIG_ENDIAN | ||
222 | __le32 len:22; | 223 | __le32 len:22; |
223 | u8 _r_a:2; | 224 | u8 _r_a:2; |
224 | u8 misc_ctl:4; | 225 | u8 misc_ctl:4; |
225 | u8 inter_sel:4; | 226 | u8 inter_sel:4; |
227 | #else | ||
228 | u32 inter_sel:4; | ||
229 | u32 misc_ctl:4; | ||
230 | u32 _r_a:2; | ||
231 | u32 len:22; | ||
232 | #endif | ||
226 | }; | 233 | }; |
227 | 234 | ||
228 | struct mvs_prd { | 235 | struct mvs_prd { |
229 | /* 64-bit buffer address */ | 236 | /* 64-bit buffer address */ |
230 | __le64 addr; | 237 | __le64 addr; |
231 | /* 22-bit length */ | 238 | /* 22-bit length */ |
232 | struct mvs_prd_imt im_len; | 239 | __le32 im_len; |
233 | } __attribute__ ((packed)); | 240 | } __attribute__ ((packed)); |
234 | 241 | ||
235 | /* | 242 | /* |
diff --git a/drivers/scsi/mvsas/mv_chips.h b/drivers/scsi/mvsas/mv_chips.h index 4519f809a8df..0a11bc7174ac 100644 --- a/drivers/scsi/mvsas/mv_chips.h +++ b/drivers/scsi/mvsas/mv_chips.h | |||
@@ -184,18 +184,6 @@ static inline void __devinit mvs_phy_hacks(struct mvs_info *mvi) | |||
184 | 184 | ||
185 | /* not to halt for different port op during wideport link change */ | 185 | /* not to halt for different port op during wideport link change */ |
186 | mvs_cw32(mvi, CMD_APP_ERR_CONFIG, 0xffefbf7d); | 186 | mvs_cw32(mvi, CMD_APP_ERR_CONFIG, 0xffefbf7d); |
187 | |||
188 | /* workaround for Seagate disk not-found OOB sequence, recv | ||
189 | * COMINIT before sending out COMWAKE */ | ||
190 | tmp = mvs_cr32(mvi, CMD_PHY_MODE_21); | ||
191 | tmp &= 0x0000ffff; | ||
192 | tmp |= 0x00fa0000; | ||
193 | mvs_cw32(mvi, CMD_PHY_MODE_21, tmp); | ||
194 | |||
195 | tmp = mvs_cr32(mvi, CMD_PHY_TIMER); | ||
196 | tmp &= 0x1fffffff; | ||
197 | tmp |= (2U << 29); /* 8 ms retry */ | ||
198 | mvs_cw32(mvi, CMD_PHY_TIMER, tmp); | ||
199 | } | 187 | } |
200 | 188 | ||
201 | static inline void mvs_int_sata(struct mvs_info *mvi) | 189 | static inline void mvs_int_sata(struct mvs_info *mvi) |
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index bf7d90cfbcfc..b28ee5bd7eeb 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c | |||
@@ -104,6 +104,7 @@ static void __devinit mvs_phy_init(struct mvs_info *mvi, int phy_id) | |||
104 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | 104 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
105 | 105 | ||
106 | phy->mvi = mvi; | 106 | phy->mvi = mvi; |
107 | phy->port = NULL; | ||
107 | init_timer(&phy->timer); | 108 | init_timer(&phy->timer); |
108 | sas_phy->enabled = (phy_id < mvi->chip->n_phy) ? 1 : 0; | 109 | sas_phy->enabled = (phy_id < mvi->chip->n_phy) ? 1 : 0; |
109 | sas_phy->class = SAS; | 110 | sas_phy->class = SAS; |
@@ -366,7 +367,7 @@ static struct mvs_info *__devinit mvs_pci_alloc(struct pci_dev *pdev, | |||
366 | const struct pci_device_id *ent, | 367 | const struct pci_device_id *ent, |
367 | struct Scsi_Host *shost, unsigned int id) | 368 | struct Scsi_Host *shost, unsigned int id) |
368 | { | 369 | { |
369 | struct mvs_info *mvi; | 370 | struct mvs_info *mvi = NULL; |
370 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); | 371 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); |
371 | 372 | ||
372 | mvi = kzalloc(sizeof(*mvi) + | 373 | mvi = kzalloc(sizeof(*mvi) + |
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index 38b47918c047..31ca8fe25cae 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c | |||
@@ -300,7 +300,10 @@ int mvs_slave_configure(struct scsi_device *sdev) | |||
300 | 300 | ||
301 | if (ret) | 301 | if (ret) |
302 | return ret; | 302 | return ret; |
303 | if (dev_is_sata(dev)) { | 303 | if (!dev_is_sata(dev)) { |
304 | sas_change_queue_depth(sdev, | ||
305 | MVS_QUEUE_SIZE, | ||
306 | SCSI_QDEPTH_DEFAULT); | ||
304 | } | 307 | } |
305 | return 0; | 308 | return 0; |
306 | } | 309 | } |
@@ -311,6 +314,7 @@ void mvs_scan_start(struct Scsi_Host *shost) | |||
311 | unsigned short core_nr; | 314 | unsigned short core_nr; |
312 | struct mvs_info *mvi; | 315 | struct mvs_info *mvi; |
313 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); | 316 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); |
317 | struct mvs_prv_info *mvs_prv = sha->lldd_ha; | ||
314 | 318 | ||
315 | core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; | 319 | core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; |
316 | 320 | ||
@@ -319,15 +323,17 @@ void mvs_scan_start(struct Scsi_Host *shost) | |||
319 | for (i = 0; i < mvi->chip->n_phy; ++i) | 323 | for (i = 0; i < mvi->chip->n_phy; ++i) |
320 | mvs_bytes_dmaed(mvi, i); | 324 | mvs_bytes_dmaed(mvi, i); |
321 | } | 325 | } |
326 | mvs_prv->scan_finished = 1; | ||
322 | } | 327 | } |
323 | 328 | ||
324 | int mvs_scan_finished(struct Scsi_Host *shost, unsigned long time) | 329 | int mvs_scan_finished(struct Scsi_Host *shost, unsigned long time) |
325 | { | 330 | { |
326 | /* give the phy enabling interrupt event time to come in (1s | 331 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); |
327 | * is empirically about all it takes) */ | 332 | struct mvs_prv_info *mvs_prv = sha->lldd_ha; |
328 | if (time < HZ) | 333 | |
334 | if (mvs_prv->scan_finished == 0) | ||
329 | return 0; | 335 | return 0; |
330 | /* Wait for discovery to finish */ | 336 | |
331 | scsi_flush_work(shost); | 337 | scsi_flush_work(shost); |
332 | return 1; | 338 | return 1; |
333 | } | 339 | } |
@@ -625,6 +631,9 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, | |||
625 | } | 631 | } |
626 | if (is_tmf) | 632 | if (is_tmf) |
627 | flags |= (MCH_SSP_FR_TASK << MCH_SSP_FR_TYPE_SHIFT); | 633 | flags |= (MCH_SSP_FR_TASK << MCH_SSP_FR_TYPE_SHIFT); |
634 | else | ||
635 | flags |= (MCH_SSP_FR_CMD << MCH_SSP_FR_TYPE_SHIFT); | ||
636 | |||
628 | hdr->flags = cpu_to_le32(flags | (tei->n_elem << MCH_PRD_LEN_SHIFT)); | 637 | hdr->flags = cpu_to_le32(flags | (tei->n_elem << MCH_PRD_LEN_SHIFT)); |
629 | hdr->tags = cpu_to_le32(tag); | 638 | hdr->tags = cpu_to_le32(tag); |
630 | hdr->data_len = cpu_to_le32(task->total_xfer_len); | 639 | hdr->data_len = cpu_to_le32(task->total_xfer_len); |
@@ -1049,9 +1058,9 @@ static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task, | |||
1049 | mvs_slot_free(mvi, slot_idx); | 1058 | mvs_slot_free(mvi, slot_idx); |
1050 | } | 1059 | } |
1051 | 1060 | ||
1052 | static void mvs_update_wideport(struct mvs_info *mvi, int i) | 1061 | static void mvs_update_wideport(struct mvs_info *mvi, int phy_no) |
1053 | { | 1062 | { |
1054 | struct mvs_phy *phy = &mvi->phy[i]; | 1063 | struct mvs_phy *phy = &mvi->phy[phy_no]; |
1055 | struct mvs_port *port = phy->port; | 1064 | struct mvs_port *port = phy->port; |
1056 | int j, no; | 1065 | int j, no; |
1057 | 1066 | ||
@@ -1106,16 +1115,16 @@ static void *mvs_get_d2h_reg(struct mvs_info *mvi, int i, void *buf) | |||
1106 | return NULL; | 1115 | return NULL; |
1107 | 1116 | ||
1108 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG3); | 1117 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG3); |
1109 | s[3] = MVS_CHIP_DISP->read_port_cfg_data(mvi, i); | 1118 | s[3] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i)); |
1110 | 1119 | ||
1111 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG2); | 1120 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG2); |
1112 | s[2] = MVS_CHIP_DISP->read_port_cfg_data(mvi, i); | 1121 | s[2] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i)); |
1113 | 1122 | ||
1114 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG1); | 1123 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG1); |
1115 | s[1] = MVS_CHIP_DISP->read_port_cfg_data(mvi, i); | 1124 | s[1] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i)); |
1116 | 1125 | ||
1117 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG0); | 1126 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG0); |
1118 | s[0] = MVS_CHIP_DISP->read_port_cfg_data(mvi, i); | 1127 | s[0] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i)); |
1119 | 1128 | ||
1120 | /* Workaround: take some ATAPI devices for ATA */ | 1129 | /* Workaround: take some ATAPI devices for ATA */ |
1121 | if (((s[1] & 0x00FFFFFF) == 0x00EB1401) && (*(u8 *)&s[3] == 0x01)) | 1130 | if (((s[1] & 0x00FFFFFF) == 0x00EB1401) && (*(u8 *)&s[3] == 0x01)) |
@@ -1201,9 +1210,9 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) | |||
1201 | if (MVS_CHIP_DISP->phy_work_around) | 1210 | if (MVS_CHIP_DISP->phy_work_around) |
1202 | MVS_CHIP_DISP->phy_work_around(mvi, i); | 1211 | MVS_CHIP_DISP->phy_work_around(mvi, i); |
1203 | } | 1212 | } |
1204 | mv_dprintk("port %d attach dev info is %x\n", | 1213 | mv_dprintk("phy %d attach dev info is %x\n", |
1205 | i + mvi->id * mvi->chip->n_phy, phy->att_dev_info); | 1214 | i + mvi->id * mvi->chip->n_phy, phy->att_dev_info); |
1206 | mv_dprintk("port %d attach sas addr is %llx\n", | 1215 | mv_dprintk("phy %d attach sas addr is %llx\n", |
1207 | i + mvi->id * mvi->chip->n_phy, phy->att_dev_sas_addr); | 1216 | i + mvi->id * mvi->chip->n_phy, phy->att_dev_sas_addr); |
1208 | out_done: | 1217 | out_done: |
1209 | if (get_st) | 1218 | if (get_st) |
@@ -1228,10 +1237,10 @@ static void mvs_port_notify_formed(struct asd_sas_phy *sas_phy, int lock) | |||
1228 | } | 1237 | } |
1229 | hi = i/((struct mvs_prv_info *)sas_ha->lldd_ha)->n_phy; | 1238 | hi = i/((struct mvs_prv_info *)sas_ha->lldd_ha)->n_phy; |
1230 | mvi = ((struct mvs_prv_info *)sas_ha->lldd_ha)->mvi[hi]; | 1239 | mvi = ((struct mvs_prv_info *)sas_ha->lldd_ha)->mvi[hi]; |
1231 | if (sas_port->id >= mvi->chip->n_phy) | 1240 | if (i >= mvi->chip->n_phy) |
1232 | port = &mvi->port[sas_port->id - mvi->chip->n_phy]; | 1241 | port = &mvi->port[i - mvi->chip->n_phy]; |
1233 | else | 1242 | else |
1234 | port = &mvi->port[sas_port->id]; | 1243 | port = &mvi->port[i]; |
1235 | if (lock) | 1244 | if (lock) |
1236 | spin_lock_irqsave(&mvi->lock, flags); | 1245 | spin_lock_irqsave(&mvi->lock, flags); |
1237 | port->port_attached = 1; | 1246 | port->port_attached = 1; |
@@ -1260,7 +1269,7 @@ static void mvs_port_notify_deformed(struct asd_sas_phy *sas_phy, int lock) | |||
1260 | return; | 1269 | return; |
1261 | } | 1270 | } |
1262 | list_for_each_entry(dev, &port->dev_list, dev_list_node) | 1271 | list_for_each_entry(dev, &port->dev_list, dev_list_node) |
1263 | mvs_do_release_task(phy->mvi, phy_no, NULL); | 1272 | mvs_do_release_task(phy->mvi, phy_no, dev); |
1264 | 1273 | ||
1265 | } | 1274 | } |
1266 | 1275 | ||
@@ -1324,6 +1333,7 @@ int mvs_dev_found_notify(struct domain_device *dev, int lock) | |||
1324 | mvi_device->dev_status = MVS_DEV_NORMAL; | 1333 | mvi_device->dev_status = MVS_DEV_NORMAL; |
1325 | mvi_device->dev_type = dev->dev_type; | 1334 | mvi_device->dev_type = dev->dev_type; |
1326 | mvi_device->mvi_info = mvi; | 1335 | mvi_device->mvi_info = mvi; |
1336 | mvi_device->sas_device = dev; | ||
1327 | if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) { | 1337 | if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) { |
1328 | int phy_id; | 1338 | int phy_id; |
1329 | u8 phy_num = parent_dev->ex_dev.num_phys; | 1339 | u8 phy_num = parent_dev->ex_dev.num_phys; |
@@ -1375,6 +1385,7 @@ void mvs_dev_gone_notify(struct domain_device *dev) | |||
1375 | mv_dprintk("found dev has gone.\n"); | 1385 | mv_dprintk("found dev has gone.\n"); |
1376 | } | 1386 | } |
1377 | dev->lldd_dev = NULL; | 1387 | dev->lldd_dev = NULL; |
1388 | mvi_dev->sas_device = NULL; | ||
1378 | 1389 | ||
1379 | spin_unlock_irqrestore(&mvi->lock, flags); | 1390 | spin_unlock_irqrestore(&mvi->lock, flags); |
1380 | } | 1391 | } |
@@ -1455,7 +1466,7 @@ static int mvs_exec_internal_tmf_task(struct domain_device *dev, | |||
1455 | } | 1466 | } |
1456 | 1467 | ||
1457 | wait_for_completion(&task->completion); | 1468 | wait_for_completion(&task->completion); |
1458 | res = -TMF_RESP_FUNC_FAILED; | 1469 | res = TMF_RESP_FUNC_FAILED; |
1459 | /* Even TMF timed out, return direct. */ | 1470 | /* Even TMF timed out, return direct. */ |
1460 | if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { | 1471 | if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { |
1461 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { | 1472 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { |
@@ -1505,11 +1516,10 @@ static int mvs_debug_issue_ssp_tmf(struct domain_device *dev, | |||
1505 | u8 *lun, struct mvs_tmf_task *tmf) | 1516 | u8 *lun, struct mvs_tmf_task *tmf) |
1506 | { | 1517 | { |
1507 | struct sas_ssp_task ssp_task; | 1518 | struct sas_ssp_task ssp_task; |
1508 | DECLARE_COMPLETION_ONSTACK(completion); | ||
1509 | if (!(dev->tproto & SAS_PROTOCOL_SSP)) | 1519 | if (!(dev->tproto & SAS_PROTOCOL_SSP)) |
1510 | return TMF_RESP_FUNC_ESUPP; | 1520 | return TMF_RESP_FUNC_ESUPP; |
1511 | 1521 | ||
1512 | strncpy((u8 *)&ssp_task.LUN, lun, 8); | 1522 | memcpy(ssp_task.LUN, lun, 8); |
1513 | 1523 | ||
1514 | return mvs_exec_internal_tmf_task(dev, &ssp_task, | 1524 | return mvs_exec_internal_tmf_task(dev, &ssp_task, |
1515 | sizeof(ssp_task), tmf); | 1525 | sizeof(ssp_task), tmf); |
@@ -1533,7 +1543,7 @@ static int mvs_debug_I_T_nexus_reset(struct domain_device *dev) | |||
1533 | int mvs_lu_reset(struct domain_device *dev, u8 *lun) | 1543 | int mvs_lu_reset(struct domain_device *dev, u8 *lun) |
1534 | { | 1544 | { |
1535 | unsigned long flags; | 1545 | unsigned long flags; |
1536 | int i, phyno[WIDE_PORT_MAX_PHY], num , rc = TMF_RESP_FUNC_FAILED; | 1546 | int rc = TMF_RESP_FUNC_FAILED; |
1537 | struct mvs_tmf_task tmf_task; | 1547 | struct mvs_tmf_task tmf_task; |
1538 | struct mvs_device * mvi_dev = dev->lldd_dev; | 1548 | struct mvs_device * mvi_dev = dev->lldd_dev; |
1539 | struct mvs_info *mvi = mvi_dev->mvi_info; | 1549 | struct mvs_info *mvi = mvi_dev->mvi_info; |
@@ -1542,10 +1552,8 @@ int mvs_lu_reset(struct domain_device *dev, u8 *lun) | |||
1542 | mvi_dev->dev_status = MVS_DEV_EH; | 1552 | mvi_dev->dev_status = MVS_DEV_EH; |
1543 | rc = mvs_debug_issue_ssp_tmf(dev, lun, &tmf_task); | 1553 | rc = mvs_debug_issue_ssp_tmf(dev, lun, &tmf_task); |
1544 | if (rc == TMF_RESP_FUNC_COMPLETE) { | 1554 | if (rc == TMF_RESP_FUNC_COMPLETE) { |
1545 | num = mvs_find_dev_phyno(dev, phyno); | ||
1546 | spin_lock_irqsave(&mvi->lock, flags); | 1555 | spin_lock_irqsave(&mvi->lock, flags); |
1547 | for (i = 0; i < num; i++) | 1556 | mvs_release_task(mvi, dev); |
1548 | mvs_release_task(mvi, dev); | ||
1549 | spin_unlock_irqrestore(&mvi->lock, flags); | 1557 | spin_unlock_irqrestore(&mvi->lock, flags); |
1550 | } | 1558 | } |
1551 | /* If failed, fall-through I_T_Nexus reset */ | 1559 | /* If failed, fall-through I_T_Nexus reset */ |
@@ -1563,6 +1571,8 @@ int mvs_I_T_nexus_reset(struct domain_device *dev) | |||
1563 | 1571 | ||
1564 | if (mvi_dev->dev_status != MVS_DEV_EH) | 1572 | if (mvi_dev->dev_status != MVS_DEV_EH) |
1565 | return TMF_RESP_FUNC_COMPLETE; | 1573 | return TMF_RESP_FUNC_COMPLETE; |
1574 | else | ||
1575 | mvi_dev->dev_status = MVS_DEV_NORMAL; | ||
1566 | rc = mvs_debug_I_T_nexus_reset(dev); | 1576 | rc = mvs_debug_I_T_nexus_reset(dev); |
1567 | mv_printk("%s for device[%x]:rc= %d\n", | 1577 | mv_printk("%s for device[%x]:rc= %d\n", |
1568 | __func__, mvi_dev->device_id, rc); | 1578 | __func__, mvi_dev->device_id, rc); |
@@ -1606,9 +1616,6 @@ int mvs_query_task(struct sas_task *task) | |||
1606 | case TMF_RESP_FUNC_FAILED: | 1616 | case TMF_RESP_FUNC_FAILED: |
1607 | case TMF_RESP_FUNC_COMPLETE: | 1617 | case TMF_RESP_FUNC_COMPLETE: |
1608 | break; | 1618 | break; |
1609 | default: | ||
1610 | rc = TMF_RESP_FUNC_COMPLETE; | ||
1611 | break; | ||
1612 | } | 1619 | } |
1613 | } | 1620 | } |
1614 | mv_printk("%s:rc= %d\n", __func__, rc); | 1621 | mv_printk("%s:rc= %d\n", __func__, rc); |
@@ -1628,8 +1635,8 @@ int mvs_abort_task(struct sas_task *task) | |||
1628 | u32 tag; | 1635 | u32 tag; |
1629 | 1636 | ||
1630 | if (!mvi_dev) { | 1637 | if (!mvi_dev) { |
1631 | mv_printk("%s:%d TMF_RESP_FUNC_FAILED\n", __func__, __LINE__); | 1638 | mv_printk("Device has removed\n"); |
1632 | rc = TMF_RESP_FUNC_FAILED; | 1639 | return TMF_RESP_FUNC_FAILED; |
1633 | } | 1640 | } |
1634 | 1641 | ||
1635 | mvi = mvi_dev->mvi_info; | 1642 | mvi = mvi_dev->mvi_info; |
@@ -1677,22 +1684,15 @@ int mvs_abort_task(struct sas_task *task) | |||
1677 | /* to do free register_set */ | 1684 | /* to do free register_set */ |
1678 | if (SATA_DEV == dev->dev_type) { | 1685 | if (SATA_DEV == dev->dev_type) { |
1679 | struct mvs_slot_info *slot = task->lldd_task; | 1686 | struct mvs_slot_info *slot = task->lldd_task; |
1680 | struct task_status_struct *tstat; | ||
1681 | u32 slot_idx = (u32)(slot - mvi->slot_info); | 1687 | u32 slot_idx = (u32)(slot - mvi->slot_info); |
1682 | tstat = &task->task_status; | 1688 | mv_dprintk("mvs_abort_task() mvi=%p task=%p " |
1683 | mv_dprintk(KERN_DEBUG "mv_abort_task() mvi=%p task=%p " | ||
1684 | "slot=%p slot_idx=x%x\n", | 1689 | "slot=%p slot_idx=x%x\n", |
1685 | mvi, task, slot, slot_idx); | 1690 | mvi, task, slot, slot_idx); |
1686 | tstat->stat = SAS_ABORTED_TASK; | 1691 | mvs_tmf_timedout((unsigned long)task); |
1687 | if (mvi_dev && mvi_dev->running_req) | ||
1688 | mvi_dev->running_req--; | ||
1689 | if (sas_protocol_ata(task->task_proto)) | ||
1690 | mvs_free_reg_set(mvi, mvi_dev); | ||
1691 | mvs_slot_task_free(mvi, task, slot, slot_idx); | 1692 | mvs_slot_task_free(mvi, task, slot, slot_idx); |
1692 | return -1; | 1693 | rc = TMF_RESP_FUNC_COMPLETE; |
1694 | goto out; | ||
1693 | } | 1695 | } |
1694 | } else { | ||
1695 | /* SMP */ | ||
1696 | 1696 | ||
1697 | } | 1697 | } |
1698 | out: | 1698 | out: |
@@ -1813,7 +1813,7 @@ static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task, | |||
1813 | { | 1813 | { |
1814 | struct mvs_slot_info *slot = &mvi->slot_info[slot_idx]; | 1814 | struct mvs_slot_info *slot = &mvi->slot_info[slot_idx]; |
1815 | int stat; | 1815 | int stat; |
1816 | u32 err_dw0 = le32_to_cpu(*(u32 *) (slot->response)); | 1816 | u32 err_dw0 = le32_to_cpu(*(u32 *)slot->response); |
1817 | u32 err_dw1 = le32_to_cpu(*((u32 *)slot->response + 1)); | 1817 | u32 err_dw1 = le32_to_cpu(*((u32 *)slot->response + 1)); |
1818 | u32 tfs = 0; | 1818 | u32 tfs = 0; |
1819 | enum mvs_port_type type = PORT_TYPE_SAS; | 1819 | enum mvs_port_type type = PORT_TYPE_SAS; |
@@ -1847,10 +1847,8 @@ static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task, | |||
1847 | case SAS_PROTOCOL_STP: | 1847 | case SAS_PROTOCOL_STP: |
1848 | case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: | 1848 | case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: |
1849 | { | 1849 | { |
1850 | if (err_dw0 == 0x80400002) | ||
1851 | mv_printk("find reserved error, why?\n"); | ||
1852 | |||
1853 | task->ata_task.use_ncq = 0; | 1850 | task->ata_task.use_ncq = 0; |
1851 | stat = SAS_PROTO_RESPONSE; | ||
1854 | mvs_sata_done(mvi, task, slot_idx, err_dw0); | 1852 | mvs_sata_done(mvi, task, slot_idx, err_dw0); |
1855 | } | 1853 | } |
1856 | break; | 1854 | break; |
@@ -1912,6 +1910,9 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) | |||
1912 | 1910 | ||
1913 | /* error info record present */ | 1911 | /* error info record present */ |
1914 | if (unlikely((rx_desc & RXQ_ERR) && (*(u64 *) slot->response))) { | 1912 | if (unlikely((rx_desc & RXQ_ERR) && (*(u64 *) slot->response))) { |
1913 | mv_dprintk("port %d slot %d rx_desc %X has error info" | ||
1914 | "%016llX.\n", slot->port->sas_port.id, slot_idx, | ||
1915 | rx_desc, (u64)(*(u64 *)slot->response)); | ||
1915 | tstat->stat = mvs_slot_err(mvi, task, slot_idx); | 1916 | tstat->stat = mvs_slot_err(mvi, task, slot_idx); |
1916 | tstat->resp = SAS_TASK_COMPLETE; | 1917 | tstat->resp = SAS_TASK_COMPLETE; |
1917 | goto out; | 1918 | goto out; |
@@ -1973,8 +1974,7 @@ out: | |||
1973 | spin_unlock(&mvi->lock); | 1974 | spin_unlock(&mvi->lock); |
1974 | if (task->task_done) | 1975 | if (task->task_done) |
1975 | task->task_done(task); | 1976 | task->task_done(task); |
1976 | else | 1977 | |
1977 | mv_dprintk("why has not task_done.\n"); | ||
1978 | spin_lock(&mvi->lock); | 1978 | spin_lock(&mvi->lock); |
1979 | 1979 | ||
1980 | return sts; | 1980 | return sts; |
@@ -2115,9 +2115,10 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | |||
2115 | struct mvs_phy *phy = &mvi->phy[phy_no]; | 2115 | struct mvs_phy *phy = &mvi->phy[phy_no]; |
2116 | 2116 | ||
2117 | phy->irq_status = MVS_CHIP_DISP->read_port_irq_stat(mvi, phy_no); | 2117 | phy->irq_status = MVS_CHIP_DISP->read_port_irq_stat(mvi, phy_no); |
2118 | mv_dprintk("port %d ctrl sts=0x%X.\n", phy_no+mvi->id*mvi->chip->n_phy, | 2118 | MVS_CHIP_DISP->write_port_irq_stat(mvi, phy_no, phy->irq_status); |
2119 | mv_dprintk("phy %d ctrl sts=0x%08X.\n", phy_no+mvi->id*mvi->chip->n_phy, | ||
2119 | MVS_CHIP_DISP->read_phy_ctl(mvi, phy_no)); | 2120 | MVS_CHIP_DISP->read_phy_ctl(mvi, phy_no)); |
2120 | mv_dprintk("Port %d irq sts = 0x%X\n", phy_no+mvi->id*mvi->chip->n_phy, | 2121 | mv_dprintk("phy %d irq sts = 0x%08X\n", phy_no+mvi->id*mvi->chip->n_phy, |
2121 | phy->irq_status); | 2122 | phy->irq_status); |
2122 | 2123 | ||
2123 | /* | 2124 | /* |
@@ -2126,11 +2127,12 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | |||
2126 | */ | 2127 | */ |
2127 | 2128 | ||
2128 | if (phy->irq_status & PHYEV_DCDR_ERR) { | 2129 | if (phy->irq_status & PHYEV_DCDR_ERR) { |
2129 | mv_dprintk("port %d STP decoding error.\n", | 2130 | mv_dprintk("phy %d STP decoding error.\n", |
2130 | phy_no + mvi->id*mvi->chip->n_phy); | 2131 | phy_no + mvi->id*mvi->chip->n_phy); |
2131 | } | 2132 | } |
2132 | 2133 | ||
2133 | if (phy->irq_status & PHYEV_POOF) { | 2134 | if (phy->irq_status & PHYEV_POOF) { |
2135 | mdelay(500); | ||
2134 | if (!(phy->phy_event & PHY_PLUG_OUT)) { | 2136 | if (!(phy->phy_event & PHY_PLUG_OUT)) { |
2135 | int dev_sata = phy->phy_type & PORT_TYPE_SATA; | 2137 | int dev_sata = phy->phy_type & PORT_TYPE_SATA; |
2136 | int ready; | 2138 | int ready; |
@@ -2141,10 +2143,6 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | |||
2141 | (void *)(unsigned long)phy_no, | 2143 | (void *)(unsigned long)phy_no, |
2142 | PHY_PLUG_EVENT); | 2144 | PHY_PLUG_EVENT); |
2143 | ready = mvs_is_phy_ready(mvi, phy_no); | 2145 | ready = mvs_is_phy_ready(mvi, phy_no); |
2144 | if (!ready) | ||
2145 | mv_dprintk("phy%d Unplug Notice\n", | ||
2146 | phy_no + | ||
2147 | mvi->id * mvi->chip->n_phy); | ||
2148 | if (ready || dev_sata) { | 2146 | if (ready || dev_sata) { |
2149 | if (MVS_CHIP_DISP->stp_reset) | 2147 | if (MVS_CHIP_DISP->stp_reset) |
2150 | MVS_CHIP_DISP->stp_reset(mvi, | 2148 | MVS_CHIP_DISP->stp_reset(mvi, |
@@ -2164,7 +2162,7 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | |||
2164 | if (phy->timer.function == NULL) { | 2162 | if (phy->timer.function == NULL) { |
2165 | phy->timer.data = (unsigned long)phy; | 2163 | phy->timer.data = (unsigned long)phy; |
2166 | phy->timer.function = mvs_sig_time_out; | 2164 | phy->timer.function = mvs_sig_time_out; |
2167 | phy->timer.expires = jiffies + 10*HZ; | 2165 | phy->timer.expires = jiffies + 5*HZ; |
2168 | add_timer(&phy->timer); | 2166 | add_timer(&phy->timer); |
2169 | } | 2167 | } |
2170 | } | 2168 | } |
@@ -2198,12 +2196,11 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | |||
2198 | phy_no + mvi->id*mvi->chip->n_phy); | 2196 | phy_no + mvi->id*mvi->chip->n_phy); |
2199 | } | 2197 | } |
2200 | } else if (phy->irq_status & PHYEV_BROAD_CH) { | 2198 | } else if (phy->irq_status & PHYEV_BROAD_CH) { |
2201 | mv_dprintk("port %d broadcast change.\n", | 2199 | mv_dprintk("phy %d broadcast change.\n", |
2202 | phy_no + mvi->id*mvi->chip->n_phy); | 2200 | phy_no + mvi->id*mvi->chip->n_phy); |
2203 | mvs_handle_event(mvi, (void *)(unsigned long)phy_no, | 2201 | mvs_handle_event(mvi, (void *)(unsigned long)phy_no, |
2204 | EXP_BRCT_CHG); | 2202 | EXP_BRCT_CHG); |
2205 | } | 2203 | } |
2206 | MVS_CHIP_DISP->write_port_irq_stat(mvi, phy_no, phy->irq_status); | ||
2207 | } | 2204 | } |
2208 | 2205 | ||
2209 | int mvs_int_rx(struct mvs_info *mvi, bool self_clear) | 2206 | int mvs_int_rx(struct mvs_info *mvi, bool self_clear) |
diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h index 428b00a36482..25fae4f6aff2 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h | |||
@@ -417,7 +417,8 @@ struct mvs_info { | |||
417 | struct mvs_prv_info{ | 417 | struct mvs_prv_info{ |
418 | u8 n_host; | 418 | u8 n_host; |
419 | u8 n_phy; | 419 | u8 n_phy; |
420 | u16 reserve; | 420 | u8 scan_finished; |
421 | u8 reserve; | ||
421 | struct mvs_info *mvi[2]; | 422 | struct mvs_info *mvi[2]; |
422 | }; | 423 | }; |
423 | 424 | ||