diff options
author | Jiri Kosina <jkosina@suse.cz> | 2011-09-15 09:08:05 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-09-15 09:08:18 -0400 |
commit | e060c38434b2caa78efe7cedaff4191040b65a15 (patch) | |
tree | 407361230bf6733f63d8e788e4b5e6566ee04818 /drivers/scsi/mvsas | |
parent | 10e4ac572eeffe5317019bd7330b6058a400dfc2 (diff) | |
parent | cc39c6a9bbdebfcf1a7dee64d83bf302bc38d941 (diff) |
Merge branch 'master' into for-next
Fast-forward merge with Linus to be able to merge patches
based on more recent version of the tree.
Diffstat (limited to 'drivers/scsi/mvsas')
-rw-r--r-- | drivers/scsi/mvsas/Kconfig | 9 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_64xx.c | 101 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_94xx.c | 508 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_94xx.h | 99 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_chips.h | 17 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_defs.h | 11 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_init.c | 187 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_sas.c | 422 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_sas.h | 105 |
9 files changed, 975 insertions, 484 deletions
diff --git a/drivers/scsi/mvsas/Kconfig b/drivers/scsi/mvsas/Kconfig index c82b012aba37..78f7e20a0c1c 100644 --- a/drivers/scsi/mvsas/Kconfig +++ b/drivers/scsi/mvsas/Kconfig | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | # Copyright 2007 Red Hat, Inc. | 4 | # Copyright 2007 Red Hat, Inc. |
5 | # Copyright 2008 Marvell. <kewei@marvell.com> | 5 | # Copyright 2008 Marvell. <kewei@marvell.com> |
6 | # Copyright 2009-20011 Marvell. <yuxiangl@marvell.com> | 6 | # Copyright 2009-2011 Marvell. <yuxiangl@marvell.com> |
7 | # | 7 | # |
8 | # This file is licensed under GPLv2. | 8 | # This file is licensed under GPLv2. |
9 | # | 9 | # |
@@ -41,3 +41,10 @@ config SCSI_MVSAS_DEBUG | |||
41 | help | 41 | help |
42 | Compiles the 88SE64XX/88SE94XX driver in debug mode. In debug mode, | 42 | Compiles the 88SE64XX/88SE94XX driver in debug mode. In debug mode, |
43 | the driver prints some messages to the console. | 43 | the driver prints some messages to the console. |
44 | config SCSI_MVSAS_TASKLET | ||
45 | bool "Support for interrupt tasklet" | ||
46 | default n | ||
47 | depends on SCSI_MVSAS | ||
48 | help | ||
49 | Compiles the 88SE64xx/88SE94xx driver in interrupt tasklet mode.In this mode, | ||
50 | the interrupt will schedule a tasklet. | ||
diff --git a/drivers/scsi/mvsas/mv_64xx.c b/drivers/scsi/mvsas/mv_64xx.c index 13c960481391..8ba47229049f 100644 --- a/drivers/scsi/mvsas/mv_64xx.c +++ b/drivers/scsi/mvsas/mv_64xx.c | |||
@@ -33,7 +33,6 @@ static void mvs_64xx_detect_porttype(struct mvs_info *mvi, int i) | |||
33 | u32 reg; | 33 | u32 reg; |
34 | struct mvs_phy *phy = &mvi->phy[i]; | 34 | struct mvs_phy *phy = &mvi->phy[i]; |
35 | 35 | ||
36 | /* TODO check & save device type */ | ||
37 | reg = mr32(MVS_GBL_PORT_TYPE); | 36 | reg = mr32(MVS_GBL_PORT_TYPE); |
38 | phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA); | 37 | phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA); |
39 | if (reg & MODE_SAS_SATA & (1 << i)) | 38 | if (reg & MODE_SAS_SATA & (1 << i)) |
@@ -48,7 +47,7 @@ static void __devinit mvs_64xx_enable_xmt(struct mvs_info *mvi, int phy_id) | |||
48 | u32 tmp; | 47 | u32 tmp; |
49 | 48 | ||
50 | tmp = mr32(MVS_PCS); | 49 | tmp = mr32(MVS_PCS); |
51 | if (mvi->chip->n_phy <= 4) | 50 | if (mvi->chip->n_phy <= MVS_SOC_PORTS) |
52 | tmp |= 1 << (phy_id + PCS_EN_PORT_XMT_SHIFT); | 51 | tmp |= 1 << (phy_id + PCS_EN_PORT_XMT_SHIFT); |
53 | else | 52 | else |
54 | tmp |= 1 << (phy_id + PCS_EN_PORT_XMT_SHIFT2); | 53 | tmp |= 1 << (phy_id + PCS_EN_PORT_XMT_SHIFT2); |
@@ -58,24 +57,16 @@ 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) | 57 | static void __devinit mvs_64xx_phy_hacks(struct mvs_info *mvi) |
59 | { | 58 | { |
60 | void __iomem *regs = mvi->regs; | 59 | void __iomem *regs = mvi->regs; |
60 | int i; | ||
61 | 61 | ||
62 | mvs_phy_hacks(mvi); | 62 | mvs_phy_hacks(mvi); |
63 | 63 | ||
64 | if (!(mvi->flags & MVF_FLAG_SOC)) { | 64 | if (!(mvi->flags & MVF_FLAG_SOC)) { |
65 | /* TEST - for phy decoding error, adjust voltage levels */ | 65 | for (i = 0; i < MVS_SOC_PORTS; i++) { |
66 | mw32(MVS_P0_VSR_ADDR + 0, 0x8); | 66 | mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE8); |
67 | mw32(MVS_P0_VSR_DATA + 0, 0x2F0); | 67 | mvs_write_port_vsr_data(mvi, i, 0x2F0); |
68 | 68 | } | |
69 | mw32(MVS_P0_VSR_ADDR + 8, 0x8); | ||
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 { | 69 | } else { |
78 | int i; | ||
79 | /* disable auto port detection */ | 70 | /* disable auto port detection */ |
80 | mw32(MVS_GBL_PORT_TYPE, 0); | 71 | mw32(MVS_GBL_PORT_TYPE, 0); |
81 | for (i = 0; i < mvi->chip->n_phy; i++) { | 72 | for (i = 0; i < mvi->chip->n_phy; i++) { |
@@ -95,7 +86,7 @@ static void mvs_64xx_stp_reset(struct mvs_info *mvi, u32 phy_id) | |||
95 | u32 reg, tmp; | 86 | u32 reg, tmp; |
96 | 87 | ||
97 | if (!(mvi->flags & MVF_FLAG_SOC)) { | 88 | if (!(mvi->flags & MVF_FLAG_SOC)) { |
98 | if (phy_id < 4) | 89 | if (phy_id < MVS_SOC_PORTS) |
99 | pci_read_config_dword(mvi->pdev, PCR_PHY_CTL, ®); | 90 | pci_read_config_dword(mvi->pdev, PCR_PHY_CTL, ®); |
100 | else | 91 | else |
101 | pci_read_config_dword(mvi->pdev, PCR_PHY_CTL2, ®); | 92 | pci_read_config_dword(mvi->pdev, PCR_PHY_CTL2, ®); |
@@ -104,13 +95,13 @@ static void mvs_64xx_stp_reset(struct mvs_info *mvi, u32 phy_id) | |||
104 | reg = mr32(MVS_PHY_CTL); | 95 | reg = mr32(MVS_PHY_CTL); |
105 | 96 | ||
106 | tmp = reg; | 97 | tmp = reg; |
107 | if (phy_id < 4) | 98 | if (phy_id < MVS_SOC_PORTS) |
108 | tmp |= (1U << phy_id) << PCTL_LINK_OFFS; | 99 | tmp |= (1U << phy_id) << PCTL_LINK_OFFS; |
109 | else | 100 | else |
110 | tmp |= (1U << (phy_id - 4)) << PCTL_LINK_OFFS; | 101 | tmp |= (1U << (phy_id - MVS_SOC_PORTS)) << PCTL_LINK_OFFS; |
111 | 102 | ||
112 | if (!(mvi->flags & MVF_FLAG_SOC)) { | 103 | if (!(mvi->flags & MVF_FLAG_SOC)) { |
113 | if (phy_id < 4) { | 104 | if (phy_id < MVS_SOC_PORTS) { |
114 | pci_write_config_dword(mvi->pdev, PCR_PHY_CTL, tmp); | 105 | pci_write_config_dword(mvi->pdev, PCR_PHY_CTL, tmp); |
115 | mdelay(10); | 106 | mdelay(10); |
116 | pci_write_config_dword(mvi->pdev, PCR_PHY_CTL, reg); | 107 | pci_write_config_dword(mvi->pdev, PCR_PHY_CTL, reg); |
@@ -133,9 +124,9 @@ static void mvs_64xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard) | |||
133 | tmp &= ~PHYEV_RDY_CH; | 124 | tmp &= ~PHYEV_RDY_CH; |
134 | mvs_write_port_irq_stat(mvi, phy_id, tmp); | 125 | mvs_write_port_irq_stat(mvi, phy_id, tmp); |
135 | tmp = mvs_read_phy_ctl(mvi, phy_id); | 126 | tmp = mvs_read_phy_ctl(mvi, phy_id); |
136 | if (hard == 1) | 127 | if (hard == MVS_HARD_RESET) |
137 | tmp |= PHY_RST_HARD; | 128 | tmp |= PHY_RST_HARD; |
138 | else if (hard == 0) | 129 | else if (hard == MVS_SOFT_RESET) |
139 | tmp |= PHY_RST; | 130 | tmp |= PHY_RST; |
140 | mvs_write_phy_ctl(mvi, phy_id, tmp); | 131 | mvs_write_phy_ctl(mvi, phy_id, tmp); |
141 | if (hard) { | 132 | if (hard) { |
@@ -321,6 +312,11 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi) | |||
321 | /* init phys */ | 312 | /* init phys */ |
322 | mvs_64xx_phy_hacks(mvi); | 313 | mvs_64xx_phy_hacks(mvi); |
323 | 314 | ||
315 | tmp = mvs_cr32(mvi, CMD_PHY_MODE_21); | ||
316 | tmp &= 0x0000ffff; | ||
317 | tmp |= 0x00fa0000; | ||
318 | mvs_cw32(mvi, CMD_PHY_MODE_21, tmp); | ||
319 | |||
324 | /* enable auto port detection */ | 320 | /* enable auto port detection */ |
325 | mw32(MVS_GBL_PORT_TYPE, MODE_AUTO_DET_EN); | 321 | mw32(MVS_GBL_PORT_TYPE, MODE_AUTO_DET_EN); |
326 | 322 | ||
@@ -346,7 +342,7 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi) | |||
346 | 342 | ||
347 | mvs_64xx_enable_xmt(mvi, i); | 343 | mvs_64xx_enable_xmt(mvi, i); |
348 | 344 | ||
349 | mvs_64xx_phy_reset(mvi, i, 1); | 345 | mvs_64xx_phy_reset(mvi, i, MVS_HARD_RESET); |
350 | msleep(500); | 346 | msleep(500); |
351 | mvs_64xx_detect_porttype(mvi, i); | 347 | mvs_64xx_detect_porttype(mvi, i); |
352 | } | 348 | } |
@@ -377,13 +373,7 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi) | |||
377 | mvs_update_phyinfo(mvi, i, 1); | 373 | mvs_update_phyinfo(mvi, i, 1); |
378 | } | 374 | } |
379 | 375 | ||
380 | /* FIXME: update wide port bitmaps */ | ||
381 | |||
382 | /* little endian for open address and command table, etc. */ | 376 | /* little endian for open address and command table, etc. */ |
383 | /* | ||
384 | * it seems that ( from the spec ) turning on big-endian won't | ||
385 | * do us any good on big-endian machines, need further confirmation | ||
386 | */ | ||
387 | cctl = mr32(MVS_CTL); | 377 | cctl = mr32(MVS_CTL); |
388 | cctl |= CCTL_ENDIAN_CMD; | 378 | cctl |= CCTL_ENDIAN_CMD; |
389 | cctl |= CCTL_ENDIAN_DATA; | 379 | cctl |= CCTL_ENDIAN_DATA; |
@@ -394,15 +384,19 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi) | |||
394 | /* reset CMD queue */ | 384 | /* reset CMD queue */ |
395 | tmp = mr32(MVS_PCS); | 385 | tmp = mr32(MVS_PCS); |
396 | tmp |= PCS_CMD_RST; | 386 | tmp |= PCS_CMD_RST; |
387 | tmp &= ~PCS_SELF_CLEAR; | ||
397 | mw32(MVS_PCS, tmp); | 388 | mw32(MVS_PCS, tmp); |
398 | /* interrupt coalescing may cause missing HW interrput in some case, | 389 | /* |
399 | * and the max count is 0x1ff, while our max slot is 0x200, | 390 | * the max count is 0x1ff, while our max slot is 0x200, |
400 | * it will make count 0. | 391 | * it will make count 0. |
401 | */ | 392 | */ |
402 | tmp = 0; | 393 | tmp = 0; |
403 | mw32(MVS_INT_COAL, tmp); | 394 | if (MVS_CHIP_SLOT_SZ > 0x1ff) |
395 | mw32(MVS_INT_COAL, 0x1ff | COAL_EN); | ||
396 | else | ||
397 | mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ | COAL_EN); | ||
404 | 398 | ||
405 | tmp = 0x100; | 399 | tmp = 0x10000 | interrupt_coalescing; |
406 | mw32(MVS_INT_COAL_TMOUT, tmp); | 400 | mw32(MVS_INT_COAL_TMOUT, tmp); |
407 | 401 | ||
408 | /* ladies and gentlemen, start your engines */ | 402 | /* ladies and gentlemen, start your engines */ |
@@ -477,13 +471,11 @@ static irqreturn_t mvs_64xx_isr(struct mvs_info *mvi, int irq, u32 stat) | |||
477 | 471 | ||
478 | /* clear CMD_CMPLT ASAP */ | 472 | /* clear CMD_CMPLT ASAP */ |
479 | mw32_f(MVS_INT_STAT, CINT_DONE); | 473 | mw32_f(MVS_INT_STAT, CINT_DONE); |
480 | #ifndef MVS_USE_TASKLET | 474 | |
481 | spin_lock(&mvi->lock); | 475 | spin_lock(&mvi->lock); |
482 | #endif | ||
483 | mvs_int_full(mvi); | 476 | mvs_int_full(mvi); |
484 | #ifndef MVS_USE_TASKLET | ||
485 | spin_unlock(&mvi->lock); | 477 | spin_unlock(&mvi->lock); |
486 | #endif | 478 | |
487 | return IRQ_HANDLED; | 479 | return IRQ_HANDLED; |
488 | } | 480 | } |
489 | 481 | ||
@@ -630,7 +622,6 @@ static void mvs_64xx_phy_work_around(struct mvs_info *mvi, int i) | |||
630 | { | 622 | { |
631 | u32 tmp; | 623 | u32 tmp; |
632 | struct mvs_phy *phy = &mvi->phy[i]; | 624 | struct mvs_phy *phy = &mvi->phy[i]; |
633 | /* workaround for HW phy decoding error on 1.5g disk drive */ | ||
634 | mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE6); | 625 | mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE6); |
635 | tmp = mvs_read_port_vsr_data(mvi, i); | 626 | tmp = mvs_read_port_vsr_data(mvi, i); |
636 | if (((phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >> | 627 | if (((phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >> |
@@ -661,7 +652,7 @@ void mvs_64xx_phy_set_link_rate(struct mvs_info *mvi, u32 phy_id, | |||
661 | tmp |= lrmax; | 652 | tmp |= lrmax; |
662 | } | 653 | } |
663 | mvs_write_phy_ctl(mvi, phy_id, tmp); | 654 | mvs_write_phy_ctl(mvi, phy_id, tmp); |
664 | mvs_64xx_phy_reset(mvi, phy_id, 1); | 655 | mvs_64xx_phy_reset(mvi, phy_id, MVS_HARD_RESET); |
665 | } | 656 | } |
666 | 657 | ||
667 | static void mvs_64xx_clear_active_cmds(struct mvs_info *mvi) | 658 | static void mvs_64xx_clear_active_cmds(struct mvs_info *mvi) |
@@ -744,11 +735,13 @@ int mvs_64xx_spi_waitdataready(struct mvs_info *mvi, u32 timeout) | |||
744 | return -1; | 735 | return -1; |
745 | } | 736 | } |
746 | 737 | ||
747 | #ifndef DISABLE_HOTPLUG_DMA_FIX | 738 | void mvs_64xx_fix_dma(struct mvs_info *mvi, u32 phy_mask, |
748 | void mvs_64xx_fix_dma(dma_addr_t buf_dma, int buf_len, int from, void *prd) | 739 | int buf_len, int from, void *prd) |
749 | { | 740 | { |
750 | int i; | 741 | int i; |
751 | struct mvs_prd *buf_prd = prd; | 742 | struct mvs_prd *buf_prd = prd; |
743 | dma_addr_t buf_dma = mvi->bulk_buffer_dma; | ||
744 | |||
752 | buf_prd += from; | 745 | buf_prd += from; |
753 | for (i = 0; i < MAX_SG_ENTRY - from; i++) { | 746 | for (i = 0; i < MAX_SG_ENTRY - from; i++) { |
754 | buf_prd->addr = cpu_to_le64(buf_dma); | 747 | buf_prd->addr = cpu_to_le64(buf_dma); |
@@ -756,7 +749,28 @@ void mvs_64xx_fix_dma(dma_addr_t buf_dma, int buf_len, int from, void *prd) | |||
756 | ++buf_prd; | 749 | ++buf_prd; |
757 | } | 750 | } |
758 | } | 751 | } |
759 | #endif | 752 | |
753 | static void mvs_64xx_tune_interrupt(struct mvs_info *mvi, u32 time) | ||
754 | { | ||
755 | void __iomem *regs = mvi->regs; | ||
756 | u32 tmp = 0; | ||
757 | /* | ||
758 | * the max count is 0x1ff, while our max slot is 0x200, | ||
759 | * it will make count 0. | ||
760 | */ | ||
761 | if (time == 0) { | ||
762 | mw32(MVS_INT_COAL, 0); | ||
763 | mw32(MVS_INT_COAL_TMOUT, 0x10000); | ||
764 | } else { | ||
765 | if (MVS_CHIP_SLOT_SZ > 0x1ff) | ||
766 | mw32(MVS_INT_COAL, 0x1ff|COAL_EN); | ||
767 | else | ||
768 | mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ|COAL_EN); | ||
769 | |||
770 | tmp = 0x10000 | time; | ||
771 | mw32(MVS_INT_COAL_TMOUT, tmp); | ||
772 | } | ||
773 | } | ||
760 | 774 | ||
761 | const struct mvs_dispatch mvs_64xx_dispatch = { | 775 | const struct mvs_dispatch mvs_64xx_dispatch = { |
762 | "mv64xx", | 776 | "mv64xx", |
@@ -780,7 +794,6 @@ const struct mvs_dispatch mvs_64xx_dispatch = { | |||
780 | mvs_write_port_irq_stat, | 794 | mvs_write_port_irq_stat, |
781 | mvs_read_port_irq_mask, | 795 | mvs_read_port_irq_mask, |
782 | mvs_write_port_irq_mask, | 796 | mvs_write_port_irq_mask, |
783 | mvs_get_sas_addr, | ||
784 | mvs_64xx_command_active, | 797 | mvs_64xx_command_active, |
785 | mvs_64xx_clear_srs_irq, | 798 | mvs_64xx_clear_srs_irq, |
786 | mvs_64xx_issue_stop, | 799 | mvs_64xx_issue_stop, |
@@ -808,8 +821,8 @@ const struct mvs_dispatch mvs_64xx_dispatch = { | |||
808 | mvs_64xx_spi_buildcmd, | 821 | mvs_64xx_spi_buildcmd, |
809 | mvs_64xx_spi_issuecmd, | 822 | mvs_64xx_spi_issuecmd, |
810 | mvs_64xx_spi_waitdataready, | 823 | mvs_64xx_spi_waitdataready, |
811 | #ifndef DISABLE_HOTPLUG_DMA_FIX | ||
812 | mvs_64xx_fix_dma, | 824 | mvs_64xx_fix_dma, |
813 | #endif | 825 | mvs_64xx_tune_interrupt, |
826 | NULL, | ||
814 | }; | 827 | }; |
815 | 828 | ||
diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c index 78162c3c36e6..3501291618fd 100644 --- a/drivers/scsi/mvsas/mv_94xx.c +++ b/drivers/scsi/mvsas/mv_94xx.c | |||
@@ -48,6 +48,216 @@ static void mvs_94xx_detect_porttype(struct mvs_info *mvi, int i) | |||
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | void set_phy_tuning(struct mvs_info *mvi, int phy_id, | ||
52 | struct phy_tuning phy_tuning) | ||
53 | { | ||
54 | u32 tmp, setting_0 = 0, setting_1 = 0; | ||
55 | u8 i; | ||
56 | |||
57 | /* Remap information for B0 chip: | ||
58 | * | ||
59 | * R0Ch -> R118h[15:0] (Adapted DFE F3 - F5 coefficient) | ||
60 | * R0Dh -> R118h[31:16] (Generation 1 Setting 0) | ||
61 | * R0Eh -> R11Ch[15:0] (Generation 1 Setting 1) | ||
62 | * R0Fh -> R11Ch[31:16] (Generation 2 Setting 0) | ||
63 | * R10h -> R120h[15:0] (Generation 2 Setting 1) | ||
64 | * R11h -> R120h[31:16] (Generation 3 Setting 0) | ||
65 | * R12h -> R124h[15:0] (Generation 3 Setting 1) | ||
66 | * R13h -> R124h[31:16] (Generation 4 Setting 0 (Reserved)) | ||
67 | */ | ||
68 | |||
69 | /* A0 has a different set of registers */ | ||
70 | if (mvi->pdev->revision == VANIR_A0_REV) | ||
71 | return; | ||
72 | |||
73 | for (i = 0; i < 3; i++) { | ||
74 | /* loop 3 times, set Gen 1, Gen 2, Gen 3 */ | ||
75 | switch (i) { | ||
76 | case 0: | ||
77 | setting_0 = GENERATION_1_SETTING; | ||
78 | setting_1 = GENERATION_1_2_SETTING; | ||
79 | break; | ||
80 | case 1: | ||
81 | setting_0 = GENERATION_1_2_SETTING; | ||
82 | setting_1 = GENERATION_2_3_SETTING; | ||
83 | break; | ||
84 | case 2: | ||
85 | setting_0 = GENERATION_2_3_SETTING; | ||
86 | setting_1 = GENERATION_3_4_SETTING; | ||
87 | break; | ||
88 | } | ||
89 | |||
90 | /* Set: | ||
91 | * | ||
92 | * Transmitter Emphasis Enable | ||
93 | * Transmitter Emphasis Amplitude | ||
94 | * Transmitter Amplitude | ||
95 | */ | ||
96 | mvs_write_port_vsr_addr(mvi, phy_id, setting_0); | ||
97 | tmp = mvs_read_port_vsr_data(mvi, phy_id); | ||
98 | tmp &= ~(0xFBE << 16); | ||
99 | tmp |= (((phy_tuning.trans_emp_en << 11) | | ||
100 | (phy_tuning.trans_emp_amp << 7) | | ||
101 | (phy_tuning.trans_amp << 1)) << 16); | ||
102 | mvs_write_port_vsr_data(mvi, phy_id, tmp); | ||
103 | |||
104 | /* Set Transmitter Amplitude Adjust */ | ||
105 | mvs_write_port_vsr_addr(mvi, phy_id, setting_1); | ||
106 | tmp = mvs_read_port_vsr_data(mvi, phy_id); | ||
107 | tmp &= ~(0xC000); | ||
108 | tmp |= (phy_tuning.trans_amp_adj << 14); | ||
109 | mvs_write_port_vsr_data(mvi, phy_id, tmp); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | void set_phy_ffe_tuning(struct mvs_info *mvi, int phy_id, | ||
114 | struct ffe_control ffe) | ||
115 | { | ||
116 | u32 tmp; | ||
117 | |||
118 | /* Don't run this if A0/B0 */ | ||
119 | if ((mvi->pdev->revision == VANIR_A0_REV) | ||
120 | || (mvi->pdev->revision == VANIR_B0_REV)) | ||
121 | return; | ||
122 | |||
123 | /* FFE Resistor and Capacitor */ | ||
124 | /* R10Ch DFE Resolution Control/Squelch and FFE Setting | ||
125 | * | ||
126 | * FFE_FORCE [7] | ||
127 | * FFE_RES_SEL [6:4] | ||
128 | * FFE_CAP_SEL [3:0] | ||
129 | */ | ||
130 | mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_FFE_CONTROL); | ||
131 | tmp = mvs_read_port_vsr_data(mvi, phy_id); | ||
132 | tmp &= ~0xFF; | ||
133 | |||
134 | /* Read from HBA_Info_Page */ | ||
135 | tmp |= ((0x1 << 7) | | ||
136 | (ffe.ffe_rss_sel << 4) | | ||
137 | (ffe.ffe_cap_sel << 0)); | ||
138 | |||
139 | mvs_write_port_vsr_data(mvi, phy_id, tmp); | ||
140 | |||
141 | /* R064h PHY Mode Register 1 | ||
142 | * | ||
143 | * DFE_DIS 18 | ||
144 | */ | ||
145 | mvs_write_port_vsr_addr(mvi, phy_id, VSR_REF_CLOCK_CRTL); | ||
146 | tmp = mvs_read_port_vsr_data(mvi, phy_id); | ||
147 | tmp &= ~0x40001; | ||
148 | /* Hard coding */ | ||
149 | /* No defines in HBA_Info_Page */ | ||
150 | tmp |= (0 << 18); | ||
151 | mvs_write_port_vsr_data(mvi, phy_id, tmp); | ||
152 | |||
153 | /* R110h DFE F0-F1 Coefficient Control/DFE Update Control | ||
154 | * | ||
155 | * DFE_UPDATE_EN [11:6] | ||
156 | * DFE_FX_FORCE [5:0] | ||
157 | */ | ||
158 | mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_DFE_UPDATE_CRTL); | ||
159 | tmp = mvs_read_port_vsr_data(mvi, phy_id); | ||
160 | tmp &= ~0xFFF; | ||
161 | /* Hard coding */ | ||
162 | /* No defines in HBA_Info_Page */ | ||
163 | tmp |= ((0x3F << 6) | (0x0 << 0)); | ||
164 | mvs_write_port_vsr_data(mvi, phy_id, tmp); | ||
165 | |||
166 | /* R1A0h Interface and Digital Reference Clock Control/Reserved_50h | ||
167 | * | ||
168 | * FFE_TRAIN_EN 3 | ||
169 | */ | ||
170 | mvs_write_port_vsr_addr(mvi, phy_id, VSR_REF_CLOCK_CRTL); | ||
171 | tmp = mvs_read_port_vsr_data(mvi, phy_id); | ||
172 | tmp &= ~0x8; | ||
173 | /* Hard coding */ | ||
174 | /* No defines in HBA_Info_Page */ | ||
175 | tmp |= (0 << 3); | ||
176 | mvs_write_port_vsr_data(mvi, phy_id, tmp); | ||
177 | } | ||
178 | |||
179 | /*Notice: this function must be called when phy is disabled*/ | ||
180 | void set_phy_rate(struct mvs_info *mvi, int phy_id, u8 rate) | ||
181 | { | ||
182 | union reg_phy_cfg phy_cfg, phy_cfg_tmp; | ||
183 | mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2); | ||
184 | phy_cfg_tmp.v = mvs_read_port_vsr_data(mvi, phy_id); | ||
185 | phy_cfg.v = 0; | ||
186 | phy_cfg.u.disable_phy = phy_cfg_tmp.u.disable_phy; | ||
187 | phy_cfg.u.sas_support = 1; | ||
188 | phy_cfg.u.sata_support = 1; | ||
189 | phy_cfg.u.sata_host_mode = 1; | ||
190 | |||
191 | switch (rate) { | ||
192 | case 0x0: | ||
193 | /* support 1.5 Gbps */ | ||
194 | phy_cfg.u.speed_support = 1; | ||
195 | phy_cfg.u.snw_3_support = 0; | ||
196 | phy_cfg.u.tx_lnk_parity = 1; | ||
197 | phy_cfg.u.tx_spt_phs_lnk_rate = 0x30; | ||
198 | break; | ||
199 | case 0x1: | ||
200 | |||
201 | /* support 1.5, 3.0 Gbps */ | ||
202 | phy_cfg.u.speed_support = 3; | ||
203 | phy_cfg.u.tx_spt_phs_lnk_rate = 0x3c; | ||
204 | phy_cfg.u.tx_lgcl_lnk_rate = 0x08; | ||
205 | break; | ||
206 | case 0x2: | ||
207 | default: | ||
208 | /* support 1.5, 3.0, 6.0 Gbps */ | ||
209 | phy_cfg.u.speed_support = 7; | ||
210 | phy_cfg.u.snw_3_support = 1; | ||
211 | phy_cfg.u.tx_lnk_parity = 1; | ||
212 | phy_cfg.u.tx_spt_phs_lnk_rate = 0x3f; | ||
213 | phy_cfg.u.tx_lgcl_lnk_rate = 0x09; | ||
214 | break; | ||
215 | } | ||
216 | mvs_write_port_vsr_data(mvi, phy_id, phy_cfg.v); | ||
217 | } | ||
218 | |||
219 | static void __devinit | ||
220 | mvs_94xx_config_reg_from_hba(struct mvs_info *mvi, int phy_id) | ||
221 | { | ||
222 | u32 temp; | ||
223 | temp = (u32)(*(u32 *)&mvi->hba_info_param.phy_tuning[phy_id]); | ||
224 | if (temp == 0xFFFFFFFFL) { | ||
225 | mvi->hba_info_param.phy_tuning[phy_id].trans_emp_amp = 0x6; | ||
226 | mvi->hba_info_param.phy_tuning[phy_id].trans_amp = 0x1A; | ||
227 | mvi->hba_info_param.phy_tuning[phy_id].trans_amp_adj = 0x3; | ||
228 | } | ||
229 | |||
230 | temp = (u8)(*(u8 *)&mvi->hba_info_param.ffe_ctl[phy_id]); | ||
231 | if (temp == 0xFFL) { | ||
232 | switch (mvi->pdev->revision) { | ||
233 | case VANIR_A0_REV: | ||
234 | case VANIR_B0_REV: | ||
235 | mvi->hba_info_param.ffe_ctl[phy_id].ffe_rss_sel = 0x7; | ||
236 | mvi->hba_info_param.ffe_ctl[phy_id].ffe_cap_sel = 0x7; | ||
237 | break; | ||
238 | case VANIR_C0_REV: | ||
239 | case VANIR_C1_REV: | ||
240 | case VANIR_C2_REV: | ||
241 | default: | ||
242 | mvi->hba_info_param.ffe_ctl[phy_id].ffe_rss_sel = 0x7; | ||
243 | mvi->hba_info_param.ffe_ctl[phy_id].ffe_cap_sel = 0xC; | ||
244 | break; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | temp = (u8)(*(u8 *)&mvi->hba_info_param.phy_rate[phy_id]); | ||
249 | if (temp == 0xFFL) | ||
250 | /*set default phy_rate = 6Gbps*/ | ||
251 | mvi->hba_info_param.phy_rate[phy_id] = 0x2; | ||
252 | |||
253 | set_phy_tuning(mvi, phy_id, | ||
254 | mvi->hba_info_param.phy_tuning[phy_id]); | ||
255 | set_phy_ffe_tuning(mvi, phy_id, | ||
256 | mvi->hba_info_param.ffe_ctl[phy_id]); | ||
257 | set_phy_rate(mvi, phy_id, | ||
258 | mvi->hba_info_param.phy_rate[phy_id]); | ||
259 | } | ||
260 | |||
51 | static void __devinit mvs_94xx_enable_xmt(struct mvs_info *mvi, int phy_id) | 261 | static void __devinit mvs_94xx_enable_xmt(struct mvs_info *mvi, int phy_id) |
52 | { | 262 | { |
53 | void __iomem *regs = mvi->regs; | 263 | void __iomem *regs = mvi->regs; |
@@ -61,7 +271,14 @@ static void __devinit mvs_94xx_enable_xmt(struct mvs_info *mvi, int phy_id) | |||
61 | 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) |
62 | { | 272 | { |
63 | u32 tmp; | 273 | u32 tmp; |
64 | 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 | } | ||
65 | tmp = mvs_read_port_irq_stat(mvi, phy_id); | 282 | tmp = mvs_read_port_irq_stat(mvi, phy_id); |
66 | tmp &= ~PHYEV_RDY_CH; | 283 | tmp &= ~PHYEV_RDY_CH; |
67 | mvs_write_port_irq_stat(mvi, phy_id, tmp); | 284 | mvs_write_port_irq_stat(mvi, phy_id, tmp); |
@@ -71,12 +288,15 @@ static void mvs_94xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard) | |||
71 | mvs_write_phy_ctl(mvi, phy_id, tmp); | 288 | mvs_write_phy_ctl(mvi, phy_id, tmp); |
72 | do { | 289 | do { |
73 | tmp = mvs_read_phy_ctl(mvi, phy_id); | 290 | tmp = mvs_read_phy_ctl(mvi, phy_id); |
74 | } 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"); | ||
75 | } else { | 296 | } else { |
76 | mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_STAT); | 297 | tmp = mvs_read_phy_ctl(mvi, phy_id); |
77 | tmp = mvs_read_port_vsr_data(mvi, phy_id); | ||
78 | tmp |= PHY_RST; | 298 | tmp |= PHY_RST; |
79 | mvs_write_port_vsr_data(mvi, phy_id, tmp); | 299 | mvs_write_phy_ctl(mvi, phy_id, tmp); |
80 | } | 300 | } |
81 | } | 301 | } |
82 | 302 | ||
@@ -90,12 +310,25 @@ static void mvs_94xx_phy_disable(struct mvs_info *mvi, u32 phy_id) | |||
90 | 310 | ||
91 | static void mvs_94xx_phy_enable(struct mvs_info *mvi, u32 phy_id) | 311 | static void mvs_94xx_phy_enable(struct mvs_info *mvi, u32 phy_id) |
92 | { | 312 | { |
93 | mvs_write_port_vsr_addr(mvi, phy_id, 0x1B4); | 313 | u32 tmp; |
94 | mvs_write_port_vsr_data(mvi, phy_id, 0x8300ffc1); | 314 | u8 revision = 0; |
95 | mvs_write_port_vsr_addr(mvi, phy_id, 0x104); | 315 | |
96 | mvs_write_port_vsr_data(mvi, phy_id, 0x00018080); | 316 | revision = mvi->pdev->revision; |
317 | if (revision == VANIR_A0_REV) { | ||
318 | mvs_write_port_vsr_addr(mvi, phy_id, CMD_HOST_RD_DATA); | ||
319 | mvs_write_port_vsr_data(mvi, phy_id, 0x8300ffc1); | ||
320 | } | ||
321 | if (revision == VANIR_B0_REV) { | ||
322 | mvs_write_port_vsr_addr(mvi, phy_id, CMD_APP_MEM_CTL); | ||
323 | mvs_write_port_vsr_data(mvi, phy_id, 0x08001006); | ||
324 | mvs_write_port_vsr_addr(mvi, phy_id, CMD_HOST_RD_DATA); | ||
325 | mvs_write_port_vsr_data(mvi, phy_id, 0x0000705f); | ||
326 | } | ||
327 | |||
97 | mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2); | 328 | mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2); |
98 | mvs_write_port_vsr_data(mvi, phy_id, 0x00207fff); | 329 | tmp = mvs_read_port_vsr_data(mvi, phy_id); |
330 | tmp |= bit(0); | ||
331 | mvs_write_port_vsr_data(mvi, phy_id, tmp & 0xfd7fffff); | ||
99 | } | 332 | } |
100 | 333 | ||
101 | static int __devinit mvs_94xx_init(struct mvs_info *mvi) | 334 | static int __devinit mvs_94xx_init(struct mvs_info *mvi) |
@@ -103,7 +336,9 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi) | |||
103 | void __iomem *regs = mvi->regs; | 336 | void __iomem *regs = mvi->regs; |
104 | int i; | 337 | int i; |
105 | u32 tmp, cctl; | 338 | u32 tmp, cctl; |
339 | u8 revision; | ||
106 | 340 | ||
341 | revision = mvi->pdev->revision; | ||
107 | mvs_show_pcie_usage(mvi); | 342 | mvs_show_pcie_usage(mvi); |
108 | if (mvi->flags & MVF_FLAG_SOC) { | 343 | if (mvi->flags & MVF_FLAG_SOC) { |
109 | tmp = mr32(MVS_PHY_CTL); | 344 | tmp = mr32(MVS_PHY_CTL); |
@@ -133,6 +368,28 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi) | |||
133 | msleep(100); | 368 | msleep(100); |
134 | } | 369 | } |
135 | 370 | ||
371 | /* disable Multiplexing, enable phy implemented */ | ||
372 | mw32(MVS_PORTS_IMP, 0xFF); | ||
373 | |||
374 | if (revision == VANIR_A0_REV) { | ||
375 | mw32(MVS_PA_VSR_ADDR, CMD_CMWK_OOB_DET); | ||
376 | mw32(MVS_PA_VSR_PORT, 0x00018080); | ||
377 | } | ||
378 | mw32(MVS_PA_VSR_ADDR, VSR_PHY_MODE2); | ||
379 | if (revision == VANIR_A0_REV || revision == VANIR_B0_REV) | ||
380 | /* set 6G/3G/1.5G, multiplexing, without SSC */ | ||
381 | mw32(MVS_PA_VSR_PORT, 0x0084d4fe); | ||
382 | else | ||
383 | /* set 6G/3G/1.5G, multiplexing, with and without SSC */ | ||
384 | mw32(MVS_PA_VSR_PORT, 0x0084fffe); | ||
385 | |||
386 | if (revision == VANIR_B0_REV) { | ||
387 | mw32(MVS_PA_VSR_ADDR, CMD_APP_MEM_CTL); | ||
388 | mw32(MVS_PA_VSR_PORT, 0x08001006); | ||
389 | mw32(MVS_PA_VSR_ADDR, CMD_HOST_RD_DATA); | ||
390 | mw32(MVS_PA_VSR_PORT, 0x0000705f); | ||
391 | } | ||
392 | |||
136 | /* reset control */ | 393 | /* reset control */ |
137 | mw32(MVS_PCS, 0); /* MVS_PCS */ | 394 | mw32(MVS_PCS, 0); /* MVS_PCS */ |
138 | mw32(MVS_STP_REG_SET_0, 0); | 395 | mw32(MVS_STP_REG_SET_0, 0); |
@@ -141,17 +398,8 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi) | |||
141 | /* init phys */ | 398 | /* init phys */ |
142 | mvs_phy_hacks(mvi); | 399 | mvs_phy_hacks(mvi); |
143 | 400 | ||
144 | /* disable Multiplexing, enable phy implemented */ | ||
145 | mw32(MVS_PORTS_IMP, 0xFF); | ||
146 | |||
147 | |||
148 | mw32(MVS_PA_VSR_ADDR, 0x00000104); | ||
149 | mw32(MVS_PA_VSR_PORT, 0x00018080); | ||
150 | mw32(MVS_PA_VSR_ADDR, VSR_PHY_MODE8); | ||
151 | mw32(MVS_PA_VSR_PORT, 0x0084ffff); | ||
152 | |||
153 | /* set LED blink when IO*/ | 401 | /* set LED blink when IO*/ |
154 | mw32(MVS_PA_VSR_ADDR, 0x00000030); | 402 | mw32(MVS_PA_VSR_ADDR, VSR_PHY_ACT_LED); |
155 | tmp = mr32(MVS_PA_VSR_PORT); | 403 | tmp = mr32(MVS_PA_VSR_PORT); |
156 | tmp &= 0xFFFF00FF; | 404 | tmp &= 0xFFFF00FF; |
157 | tmp |= 0x00003300; | 405 | tmp |= 0x00003300; |
@@ -175,12 +423,13 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi) | |||
175 | mvs_94xx_phy_disable(mvi, i); | 423 | mvs_94xx_phy_disable(mvi, i); |
176 | /* set phy local SAS address */ | 424 | /* set phy local SAS address */ |
177 | 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, |
178 | (mvi->phy[i].dev_sas_addr)); | 426 | cpu_to_le64(mvi->phy[i].dev_sas_addr)); |
179 | 427 | ||
180 | mvs_94xx_enable_xmt(mvi, i); | 428 | mvs_94xx_enable_xmt(mvi, i); |
429 | mvs_94xx_config_reg_from_hba(mvi, i); | ||
181 | mvs_94xx_phy_enable(mvi, i); | 430 | mvs_94xx_phy_enable(mvi, i); |
182 | 431 | ||
183 | mvs_94xx_phy_reset(mvi, i, 1); | 432 | mvs_94xx_phy_reset(mvi, i, PHY_RST_HARD); |
184 | msleep(500); | 433 | msleep(500); |
185 | mvs_94xx_detect_porttype(mvi, i); | 434 | mvs_94xx_detect_porttype(mvi, i); |
186 | } | 435 | } |
@@ -211,16 +460,9 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi) | |||
211 | mvs_update_phyinfo(mvi, i, 1); | 460 | mvs_update_phyinfo(mvi, i, 1); |
212 | } | 461 | } |
213 | 462 | ||
214 | /* FIXME: update wide port bitmaps */ | ||
215 | |||
216 | /* little endian for open address and command table, etc. */ | 463 | /* little endian for open address and command table, etc. */ |
217 | /* | ||
218 | * it seems that ( from the spec ) turning on big-endian won't | ||
219 | * do us any good on big-endian machines, need further confirmation | ||
220 | */ | ||
221 | cctl = mr32(MVS_CTL); | 464 | cctl = mr32(MVS_CTL); |
222 | cctl |= CCTL_ENDIAN_CMD; | 465 | cctl |= CCTL_ENDIAN_CMD; |
223 | cctl |= CCTL_ENDIAN_DATA; | ||
224 | cctl &= ~CCTL_ENDIAN_OPEN; | 466 | cctl &= ~CCTL_ENDIAN_OPEN; |
225 | cctl |= CCTL_ENDIAN_RSP; | 467 | cctl |= CCTL_ENDIAN_RSP; |
226 | mw32_f(MVS_CTL, cctl); | 468 | mw32_f(MVS_CTL, cctl); |
@@ -228,15 +470,20 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi) | |||
228 | /* reset CMD queue */ | 470 | /* reset CMD queue */ |
229 | tmp = mr32(MVS_PCS); | 471 | tmp = mr32(MVS_PCS); |
230 | tmp |= PCS_CMD_RST; | 472 | tmp |= PCS_CMD_RST; |
473 | tmp &= ~PCS_SELF_CLEAR; | ||
231 | mw32(MVS_PCS, tmp); | 474 | mw32(MVS_PCS, tmp); |
232 | /* interrupt coalescing may cause missing HW interrput in some case, | 475 | /* |
233 | * and the max count is 0x1ff, while our max slot is 0x200, | 476 | * the max count is 0x1ff, while our max slot is 0x200, |
234 | * it will make count 0. | 477 | * it will make count 0. |
235 | */ | 478 | */ |
236 | tmp = 0; | 479 | tmp = 0; |
237 | mw32(MVS_INT_COAL, tmp); | 480 | if (MVS_CHIP_SLOT_SZ > 0x1ff) |
481 | mw32(MVS_INT_COAL, 0x1ff | COAL_EN); | ||
482 | else | ||
483 | mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ | COAL_EN); | ||
238 | 484 | ||
239 | tmp = 0x100; | 485 | /* default interrupt coalescing time is 128us */ |
486 | tmp = 0x10000 | interrupt_coalescing; | ||
240 | mw32(MVS_INT_COAL_TMOUT, tmp); | 487 | mw32(MVS_INT_COAL_TMOUT, tmp); |
241 | 488 | ||
242 | /* ladies and gentlemen, start your engines */ | 489 | /* ladies and gentlemen, start your engines */ |
@@ -249,7 +496,7 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi) | |||
249 | 496 | ||
250 | /* enable completion queue interrupt */ | 497 | /* enable completion queue interrupt */ |
251 | tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS | CINT_CI_STOP | | 498 | tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS | CINT_CI_STOP | |
252 | CINT_DMA_PCIE); | 499 | CINT_DMA_PCIE | CINT_NON_SPEC_NCQ_ERROR); |
253 | tmp |= CINT_PHY_MASK; | 500 | tmp |= CINT_PHY_MASK; |
254 | mw32(MVS_INT_MASK, tmp); | 501 | mw32(MVS_INT_MASK, tmp); |
255 | 502 | ||
@@ -332,13 +579,10 @@ static irqreturn_t mvs_94xx_isr(struct mvs_info *mvi, int irq, u32 stat) | |||
332 | if (((stat & IRQ_SAS_A) && mvi->id == 0) || | 579 | if (((stat & IRQ_SAS_A) && mvi->id == 0) || |
333 | ((stat & IRQ_SAS_B) && mvi->id == 1)) { | 580 | ((stat & IRQ_SAS_B) && mvi->id == 1)) { |
334 | mw32_f(MVS_INT_STAT, CINT_DONE); | 581 | mw32_f(MVS_INT_STAT, CINT_DONE); |
335 | #ifndef MVS_USE_TASKLET | 582 | |
336 | spin_lock(&mvi->lock); | 583 | spin_lock(&mvi->lock); |
337 | #endif | ||
338 | mvs_int_full(mvi); | 584 | mvs_int_full(mvi); |
339 | #ifndef MVS_USE_TASKLET | ||
340 | spin_unlock(&mvi->lock); | 585 | spin_unlock(&mvi->lock); |
341 | #endif | ||
342 | } | 586 | } |
343 | return IRQ_HANDLED; | 587 | return IRQ_HANDLED; |
344 | } | 588 | } |
@@ -346,10 +590,48 @@ static irqreturn_t mvs_94xx_isr(struct mvs_info *mvi, int irq, u32 stat) | |||
346 | static void mvs_94xx_command_active(struct mvs_info *mvi, u32 slot_idx) | 590 | static void mvs_94xx_command_active(struct mvs_info *mvi, u32 slot_idx) |
347 | { | 591 | { |
348 | u32 tmp; | 592 | u32 tmp; |
349 | mvs_cw32(mvi, 0x300 + (slot_idx >> 3), 1 << (slot_idx % 32)); | 593 | tmp = mvs_cr32(mvi, MVS_COMMAND_ACTIVE+(slot_idx >> 3)); |
350 | do { | 594 | if (tmp && 1 << (slot_idx % 32)) { |
351 | tmp = mvs_cr32(mvi, 0x300 + (slot_idx >> 3)); | 595 | mv_printk("command active %08X, slot [%x].\n", tmp, slot_idx); |
352 | } while (tmp & 1 << (slot_idx % 32)); | 596 | mvs_cw32(mvi, MVS_COMMAND_ACTIVE + (slot_idx >> 3), |
597 | 1 << (slot_idx % 32)); | ||
598 | do { | ||
599 | tmp = mvs_cr32(mvi, | ||
600 | MVS_COMMAND_ACTIVE + (slot_idx >> 3)); | ||
601 | } while (tmp & 1 << (slot_idx % 32)); | ||
602 | } | ||
603 | } | ||
604 | |||
605 | void mvs_94xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set, u8 clear_all) | ||
606 | { | ||
607 | void __iomem *regs = mvi->regs; | ||
608 | u32 tmp; | ||
609 | |||
610 | if (clear_all) { | ||
611 | tmp = mr32(MVS_INT_STAT_SRS_0); | ||
612 | if (tmp) { | ||
613 | mv_dprintk("check SRS 0 %08X.\n", tmp); | ||
614 | mw32(MVS_INT_STAT_SRS_0, tmp); | ||
615 | } | ||
616 | tmp = mr32(MVS_INT_STAT_SRS_1); | ||
617 | if (tmp) { | ||
618 | mv_dprintk("check SRS 1 %08X.\n", tmp); | ||
619 | mw32(MVS_INT_STAT_SRS_1, tmp); | ||
620 | } | ||
621 | } else { | ||
622 | if (reg_set > 31) | ||
623 | tmp = mr32(MVS_INT_STAT_SRS_1); | ||
624 | else | ||
625 | tmp = mr32(MVS_INT_STAT_SRS_0); | ||
626 | |||
627 | if (tmp & (1 << (reg_set % 32))) { | ||
628 | mv_dprintk("register set 0x%x was stopped.\n", reg_set); | ||
629 | if (reg_set > 31) | ||
630 | mw32(MVS_INT_STAT_SRS_1, 1 << (reg_set % 32)); | ||
631 | else | ||
632 | mw32(MVS_INT_STAT_SRS_0, 1 << (reg_set % 32)); | ||
633 | } | ||
634 | } | ||
353 | } | 635 | } |
354 | 636 | ||
355 | static void mvs_94xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type, | 637 | static void mvs_94xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type, |
@@ -357,37 +639,56 @@ static void mvs_94xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type, | |||
357 | { | 639 | { |
358 | void __iomem *regs = mvi->regs; | 640 | void __iomem *regs = mvi->regs; |
359 | u32 tmp; | 641 | u32 tmp; |
642 | mvs_94xx_clear_srs_irq(mvi, 0, 1); | ||
360 | 643 | ||
361 | if (type == PORT_TYPE_SATA) { | 644 | tmp = mr32(MVS_INT_STAT); |
362 | tmp = mr32(MVS_INT_STAT_SRS_0) | (1U << tfs); | 645 | mw32(MVS_INT_STAT, tmp | CINT_CI_STOP); |
363 | mw32(MVS_INT_STAT_SRS_0, tmp); | ||
364 | } | ||
365 | mw32(MVS_INT_STAT, CINT_CI_STOP); | ||
366 | tmp = mr32(MVS_PCS) | 0xFF00; | 646 | tmp = mr32(MVS_PCS) | 0xFF00; |
367 | mw32(MVS_PCS, tmp); | 647 | mw32(MVS_PCS, tmp); |
368 | } | 648 | } |
369 | 649 | ||
650 | static void mvs_94xx_non_spec_ncq_error(struct mvs_info *mvi) | ||
651 | { | ||
652 | void __iomem *regs = mvi->regs; | ||
653 | u32 err_0, err_1; | ||
654 | u8 i; | ||
655 | struct mvs_device *device; | ||
656 | |||
657 | err_0 = mr32(MVS_NON_NCQ_ERR_0); | ||
658 | err_1 = mr32(MVS_NON_NCQ_ERR_1); | ||
659 | |||
660 | mv_dprintk("non specific ncq error err_0:%x,err_1:%x.\n", | ||
661 | err_0, err_1); | ||
662 | for (i = 0; i < 32; i++) { | ||
663 | if (err_0 & bit(i)) { | ||
664 | device = mvs_find_dev_by_reg_set(mvi, i); | ||
665 | if (device) | ||
666 | mvs_release_task(mvi, device->sas_device); | ||
667 | } | ||
668 | if (err_1 & bit(i)) { | ||
669 | device = mvs_find_dev_by_reg_set(mvi, i+32); | ||
670 | if (device) | ||
671 | mvs_release_task(mvi, device->sas_device); | ||
672 | } | ||
673 | } | ||
674 | |||
675 | mw32(MVS_NON_NCQ_ERR_0, err_0); | ||
676 | mw32(MVS_NON_NCQ_ERR_1, err_1); | ||
677 | } | ||
678 | |||
370 | static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs) | 679 | static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs) |
371 | { | 680 | { |
372 | void __iomem *regs = mvi->regs; | 681 | void __iomem *regs = mvi->regs; |
373 | u32 tmp; | ||
374 | u8 reg_set = *tfs; | 682 | u8 reg_set = *tfs; |
375 | 683 | ||
376 | if (*tfs == MVS_ID_NOT_MAPPED) | 684 | if (*tfs == MVS_ID_NOT_MAPPED) |
377 | return; | 685 | return; |
378 | 686 | ||
379 | mvi->sata_reg_set &= ~bit(reg_set); | 687 | mvi->sata_reg_set &= ~bit(reg_set); |
380 | if (reg_set < 32) { | 688 | if (reg_set < 32) |
381 | w_reg_set_enable(reg_set, (u32)mvi->sata_reg_set); | 689 | w_reg_set_enable(reg_set, (u32)mvi->sata_reg_set); |
382 | tmp = mr32(MVS_INT_STAT_SRS_0) & (u32)mvi->sata_reg_set; | 690 | else |
383 | if (tmp) | 691 | w_reg_set_enable(reg_set, (u32)(mvi->sata_reg_set >> 32)); |
384 | mw32(MVS_INT_STAT_SRS_0, tmp); | ||
385 | } else { | ||
386 | w_reg_set_enable(reg_set, mvi->sata_reg_set); | ||
387 | tmp = mr32(MVS_INT_STAT_SRS_1) & mvi->sata_reg_set; | ||
388 | if (tmp) | ||
389 | mw32(MVS_INT_STAT_SRS_1, tmp); | ||
390 | } | ||
391 | 692 | ||
392 | *tfs = MVS_ID_NOT_MAPPED; | 693 | *tfs = MVS_ID_NOT_MAPPED; |
393 | 694 | ||
@@ -403,7 +704,7 @@ static u8 mvs_94xx_assign_reg_set(struct mvs_info *mvi, u8 *tfs) | |||
403 | return 0; | 704 | return 0; |
404 | 705 | ||
405 | i = mv_ffc64(mvi->sata_reg_set); | 706 | i = mv_ffc64(mvi->sata_reg_set); |
406 | if (i > 32) { | 707 | if (i >= 32) { |
407 | mvi->sata_reg_set |= bit(i); | 708 | mvi->sata_reg_set |= bit(i); |
408 | w_reg_set_enable(i, (u32)(mvi->sata_reg_set >> 32)); | 709 | w_reg_set_enable(i, (u32)(mvi->sata_reg_set >> 32)); |
409 | *tfs = i; | 710 | *tfs = i; |
@@ -422,9 +723,12 @@ static void mvs_94xx_make_prd(struct scatterlist *scatter, int nr, void *prd) | |||
422 | int i; | 723 | int i; |
423 | struct scatterlist *sg; | 724 | struct scatterlist *sg; |
424 | struct mvs_prd *buf_prd = prd; | 725 | struct mvs_prd *buf_prd = prd; |
726 | struct mvs_prd_imt im_len; | ||
727 | *(u32 *)&im_len = 0; | ||
425 | for_each_sg(scatter, sg, nr, i) { | 728 | for_each_sg(scatter, sg, nr, i) { |
426 | buf_prd->addr = cpu_to_le64(sg_dma_address(sg)); | 729 | buf_prd->addr = cpu_to_le64(sg_dma_address(sg)); |
427 | buf_prd->im_len.len = cpu_to_le32(sg_dma_len(sg)); | 730 | im_len.len = sg_dma_len(sg); |
731 | buf_prd->im_len = cpu_to_le32(*(u32 *)&im_len); | ||
428 | buf_prd++; | 732 | buf_prd++; |
429 | } | 733 | } |
430 | } | 734 | } |
@@ -433,7 +737,7 @@ static int mvs_94xx_oob_done(struct mvs_info *mvi, int i) | |||
433 | { | 737 | { |
434 | u32 phy_st; | 738 | u32 phy_st; |
435 | phy_st = mvs_read_phy_ctl(mvi, i); | 739 | phy_st = mvs_read_phy_ctl(mvi, i); |
436 | if (phy_st & PHY_READY_MASK) /* phy ready */ | 740 | if (phy_st & PHY_READY_MASK) |
437 | return 1; | 741 | return 1; |
438 | return 0; | 742 | return 0; |
439 | } | 743 | } |
@@ -447,7 +751,7 @@ static void mvs_94xx_get_dev_identify_frame(struct mvs_info *mvi, int port_id, | |||
447 | for (i = 0; i < 7; i++) { | 751 | for (i = 0; i < 7; i++) { |
448 | mvs_write_port_cfg_addr(mvi, port_id, | 752 | mvs_write_port_cfg_addr(mvi, port_id, |
449 | CONFIG_ID_FRAME0 + i * 4); | 753 | CONFIG_ID_FRAME0 + i * 4); |
450 | id_frame[i] = mvs_read_port_cfg_data(mvi, port_id); | 754 | id_frame[i] = cpu_to_le32(mvs_read_port_cfg_data(mvi, port_id)); |
451 | } | 755 | } |
452 | memcpy(id, id_frame, 28); | 756 | memcpy(id, id_frame, 28); |
453 | } | 757 | } |
@@ -458,15 +762,13 @@ static void mvs_94xx_get_att_identify_frame(struct mvs_info *mvi, int port_id, | |||
458 | int i; | 762 | int i; |
459 | u32 id_frame[7]; | 763 | u32 id_frame[7]; |
460 | 764 | ||
461 | /* mvs_hexdump(28, (u8 *)id_frame, 0); */ | ||
462 | for (i = 0; i < 7; i++) { | 765 | for (i = 0; i < 7; i++) { |
463 | mvs_write_port_cfg_addr(mvi, port_id, | 766 | mvs_write_port_cfg_addr(mvi, port_id, |
464 | CONFIG_ATT_ID_FRAME0 + i * 4); | 767 | CONFIG_ATT_ID_FRAME0 + i * 4); |
465 | id_frame[i] = mvs_read_port_cfg_data(mvi, port_id); | 768 | id_frame[i] = cpu_to_le32(mvs_read_port_cfg_data(mvi, port_id)); |
466 | mv_dprintk("94xx phy %d atta frame %d %x.\n", | 769 | mv_dprintk("94xx phy %d atta frame %d %x.\n", |
467 | port_id + mvi->id * mvi->chip->n_phy, i, id_frame[i]); | 770 | port_id + mvi->id * mvi->chip->n_phy, i, id_frame[i]); |
468 | } | 771 | } |
469 | /* mvs_hexdump(28, (u8 *)id_frame, 0); */ | ||
470 | memcpy(id, id_frame, 28); | 772 | memcpy(id, id_frame, 28); |
471 | } | 773 | } |
472 | 774 | ||
@@ -526,7 +828,18 @@ static void mvs_94xx_fix_phy_info(struct mvs_info *mvi, int i, | |||
526 | void mvs_94xx_phy_set_link_rate(struct mvs_info *mvi, u32 phy_id, | 828 | void mvs_94xx_phy_set_link_rate(struct mvs_info *mvi, u32 phy_id, |
527 | struct sas_phy_linkrates *rates) | 829 | struct sas_phy_linkrates *rates) |
528 | { | 830 | { |
529 | /* TODO */ | 831 | u32 lrmax = 0; |
832 | u32 tmp; | ||
833 | |||
834 | tmp = mvs_read_phy_ctl(mvi, phy_id); | ||
835 | lrmax = (rates->maximum_linkrate - SAS_LINK_RATE_1_5_GBPS) << 12; | ||
836 | |||
837 | if (lrmax) { | ||
838 | tmp &= ~(0x3 << 12); | ||
839 | tmp |= lrmax; | ||
840 | } | ||
841 | mvs_write_phy_ctl(mvi, phy_id, tmp); | ||
842 | mvs_94xx_phy_reset(mvi, phy_id, PHY_RST_HARD); | ||
530 | } | 843 | } |
531 | 844 | ||
532 | static void mvs_94xx_clear_active_cmds(struct mvs_info *mvi) | 845 | static void mvs_94xx_clear_active_cmds(struct mvs_info *mvi) |
@@ -603,27 +916,59 @@ int mvs_94xx_spi_waitdataready(struct mvs_info *mvi, u32 timeout) | |||
603 | return -1; | 916 | return -1; |
604 | } | 917 | } |
605 | 918 | ||
606 | #ifndef DISABLE_HOTPLUG_DMA_FIX | 919 | void mvs_94xx_fix_dma(struct mvs_info *mvi, u32 phy_mask, |
607 | void mvs_94xx_fix_dma(dma_addr_t buf_dma, int buf_len, int from, void *prd) | 920 | int buf_len, int from, void *prd) |
608 | { | 921 | { |
609 | int i; | 922 | int i; |
610 | struct mvs_prd *buf_prd = prd; | 923 | struct mvs_prd *buf_prd = prd; |
924 | dma_addr_t buf_dma; | ||
925 | struct mvs_prd_imt im_len; | ||
926 | |||
927 | *(u32 *)&im_len = 0; | ||
611 | buf_prd += from; | 928 | buf_prd += from; |
612 | for (i = 0; i < MAX_SG_ENTRY - from; i++) { | 929 | |
613 | buf_prd->addr = cpu_to_le64(buf_dma); | 930 | #define PRD_CHAINED_ENTRY 0x01 |
614 | buf_prd->im_len.len = cpu_to_le32(buf_len); | 931 | if ((mvi->pdev->revision == VANIR_A0_REV) || |
615 | ++buf_prd; | 932 | (mvi->pdev->revision == VANIR_B0_REV)) |
933 | buf_dma = (phy_mask <= 0x08) ? | ||
934 | mvi->bulk_buffer_dma : mvi->bulk_buffer_dma1; | ||
935 | else | ||
936 | return; | ||
937 | |||
938 | for (i = from; i < MAX_SG_ENTRY; i++, ++buf_prd) { | ||
939 | if (i == MAX_SG_ENTRY - 1) { | ||
940 | buf_prd->addr = cpu_to_le64(virt_to_phys(buf_prd - 1)); | ||
941 | im_len.len = 2; | ||
942 | im_len.misc_ctl = PRD_CHAINED_ENTRY; | ||
943 | } else { | ||
944 | buf_prd->addr = cpu_to_le64(buf_dma); | ||
945 | im_len.len = buf_len; | ||
946 | } | ||
947 | buf_prd->im_len = cpu_to_le32(*(u32 *)&im_len); | ||
616 | } | 948 | } |
617 | } | 949 | } |
618 | #endif | ||
619 | 950 | ||
620 | /* | 951 | static void mvs_94xx_tune_interrupt(struct mvs_info *mvi, u32 time) |
621 | * FIXME JEJB: temporary nop clear_srs_irq to make 94xx still work | ||
622 | * with 64xx fixes | ||
623 | */ | ||
624 | static void mvs_94xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set, | ||
625 | u8 clear_all) | ||
626 | { | 952 | { |
953 | void __iomem *regs = mvi->regs; | ||
954 | u32 tmp = 0; | ||
955 | /* | ||
956 | * the max count is 0x1ff, while our max slot is 0x200, | ||
957 | * it will make count 0. | ||
958 | */ | ||
959 | if (time == 0) { | ||
960 | mw32(MVS_INT_COAL, 0); | ||
961 | mw32(MVS_INT_COAL_TMOUT, 0x10000); | ||
962 | } else { | ||
963 | if (MVS_CHIP_SLOT_SZ > 0x1ff) | ||
964 | mw32(MVS_INT_COAL, 0x1ff|COAL_EN); | ||
965 | else | ||
966 | mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ|COAL_EN); | ||
967 | |||
968 | tmp = 0x10000 | time; | ||
969 | mw32(MVS_INT_COAL_TMOUT, tmp); | ||
970 | } | ||
971 | |||
627 | } | 972 | } |
628 | 973 | ||
629 | const struct mvs_dispatch mvs_94xx_dispatch = { | 974 | const struct mvs_dispatch mvs_94xx_dispatch = { |
@@ -648,7 +993,6 @@ const struct mvs_dispatch mvs_94xx_dispatch = { | |||
648 | mvs_write_port_irq_stat, | 993 | mvs_write_port_irq_stat, |
649 | mvs_read_port_irq_mask, | 994 | mvs_read_port_irq_mask, |
650 | mvs_write_port_irq_mask, | 995 | mvs_write_port_irq_mask, |
651 | mvs_get_sas_addr, | ||
652 | mvs_94xx_command_active, | 996 | mvs_94xx_command_active, |
653 | mvs_94xx_clear_srs_irq, | 997 | mvs_94xx_clear_srs_irq, |
654 | mvs_94xx_issue_stop, | 998 | mvs_94xx_issue_stop, |
@@ -676,8 +1020,8 @@ const struct mvs_dispatch mvs_94xx_dispatch = { | |||
676 | mvs_94xx_spi_buildcmd, | 1020 | mvs_94xx_spi_buildcmd, |
677 | mvs_94xx_spi_issuecmd, | 1021 | mvs_94xx_spi_issuecmd, |
678 | mvs_94xx_spi_waitdataready, | 1022 | mvs_94xx_spi_waitdataready, |
679 | #ifndef DISABLE_HOTPLUG_DMA_FIX | ||
680 | mvs_94xx_fix_dma, | 1023 | mvs_94xx_fix_dma, |
681 | #endif | 1024 | mvs_94xx_tune_interrupt, |
1025 | mvs_94xx_non_spec_ncq_error, | ||
682 | }; | 1026 | }; |
683 | 1027 | ||
diff --git a/drivers/scsi/mvsas/mv_94xx.h b/drivers/scsi/mvsas/mv_94xx.h index 8835befe2c0e..8f7eb4f21140 100644 --- a/drivers/scsi/mvsas/mv_94xx.h +++ b/drivers/scsi/mvsas/mv_94xx.h | |||
@@ -30,6 +30,14 @@ | |||
30 | 30 | ||
31 | #define MAX_LINK_RATE SAS_LINK_RATE_6_0_GBPS | 31 | #define MAX_LINK_RATE SAS_LINK_RATE_6_0_GBPS |
32 | 32 | ||
33 | enum VANIR_REVISION_ID { | ||
34 | VANIR_A0_REV = 0xA0, | ||
35 | VANIR_B0_REV = 0x01, | ||
36 | VANIR_C0_REV = 0x02, | ||
37 | VANIR_C1_REV = 0x03, | ||
38 | VANIR_C2_REV = 0xC2, | ||
39 | }; | ||
40 | |||
33 | enum hw_registers { | 41 | enum hw_registers { |
34 | MVS_GBL_CTL = 0x04, /* global control */ | 42 | MVS_GBL_CTL = 0x04, /* global control */ |
35 | MVS_GBL_INT_STAT = 0x00, /* global irq status */ | 43 | MVS_GBL_INT_STAT = 0x00, /* global irq status */ |
@@ -101,6 +109,7 @@ enum hw_registers { | |||
101 | MVS_P4_VSR_DATA = 0x254, /* phy4 VSR data */ | 109 | MVS_P4_VSR_DATA = 0x254, /* phy4 VSR data */ |
102 | MVS_PA_VSR_ADDR = 0x290, /* All port VSR addr */ | 110 | MVS_PA_VSR_ADDR = 0x290, /* All port VSR addr */ |
103 | MVS_PA_VSR_PORT = 0x294, /* All port VSR data */ | 111 | MVS_PA_VSR_PORT = 0x294, /* All port VSR data */ |
112 | MVS_COMMAND_ACTIVE = 0x300, | ||
104 | }; | 113 | }; |
105 | 114 | ||
106 | enum pci_cfg_registers { | 115 | enum pci_cfg_registers { |
@@ -112,26 +121,29 @@ enum pci_cfg_registers { | |||
112 | 121 | ||
113 | /* SAS/SATA Vendor Specific Port Registers */ | 122 | /* SAS/SATA Vendor Specific Port Registers */ |
114 | enum sas_sata_vsp_regs { | 123 | enum sas_sata_vsp_regs { |
115 | VSR_PHY_STAT = 0x00 * 4, /* Phy Status */ | 124 | VSR_PHY_STAT = 0x00 * 4, /* Phy Interrupt Status */ |
116 | VSR_PHY_MODE1 = 0x01 * 4, /* phy tx */ | 125 | VSR_PHY_MODE1 = 0x01 * 4, /* phy Interrupt Enable */ |
117 | VSR_PHY_MODE2 = 0x02 * 4, /* tx scc */ | 126 | VSR_PHY_MODE2 = 0x02 * 4, /* Phy Configuration */ |
118 | VSR_PHY_MODE3 = 0x03 * 4, /* pll */ | 127 | VSR_PHY_MODE3 = 0x03 * 4, /* Phy Status */ |
119 | VSR_PHY_MODE4 = 0x04 * 4, /* VCO */ | 128 | VSR_PHY_MODE4 = 0x04 * 4, /* Phy Counter 0 */ |
120 | VSR_PHY_MODE5 = 0x05 * 4, /* Rx */ | 129 | VSR_PHY_MODE5 = 0x05 * 4, /* Phy Counter 1 */ |
121 | VSR_PHY_MODE6 = 0x06 * 4, /* CDR */ | 130 | VSR_PHY_MODE6 = 0x06 * 4, /* Event Counter Control */ |
122 | VSR_PHY_MODE7 = 0x07 * 4, /* Impedance */ | 131 | VSR_PHY_MODE7 = 0x07 * 4, /* Event Counter Select */ |
123 | VSR_PHY_MODE8 = 0x08 * 4, /* Voltage */ | 132 | VSR_PHY_MODE8 = 0x08 * 4, /* Event Counter 0 */ |
124 | VSR_PHY_MODE9 = 0x09 * 4, /* Test */ | 133 | VSR_PHY_MODE9 = 0x09 * 4, /* Event Counter 1 */ |
125 | VSR_PHY_MODE10 = 0x0A * 4, /* Power */ | 134 | VSR_PHY_MODE10 = 0x0A * 4, /* Event Counter 2 */ |
126 | VSR_PHY_MODE11 = 0x0B * 4, /* Phy Mode */ | 135 | VSR_PHY_MODE11 = 0x0B * 4, /* Event Counter 3 */ |
127 | VSR_PHY_VS0 = 0x0C * 4, /* Vednor Specific 0 */ | 136 | VSR_PHY_ACT_LED = 0x0C * 4, /* Activity LED control */ |
128 | VSR_PHY_VS1 = 0x0D * 4, /* Vednor Specific 1 */ | 137 | |
138 | VSR_PHY_FFE_CONTROL = 0x10C, | ||
139 | VSR_PHY_DFE_UPDATE_CRTL = 0x110, | ||
140 | VSR_REF_CLOCK_CRTL = 0x1A0, | ||
129 | }; | 141 | }; |
130 | 142 | ||
131 | enum chip_register_bits { | 143 | enum chip_register_bits { |
132 | PHY_MIN_SPP_PHYS_LINK_RATE_MASK = (0x7 << 8), | 144 | PHY_MIN_SPP_PHYS_LINK_RATE_MASK = (0x7 << 8), |
133 | PHY_MAX_SPP_PHYS_LINK_RATE_MASK = (0x7 << 8), | 145 | PHY_MAX_SPP_PHYS_LINK_RATE_MASK = (0x7 << 12), |
134 | PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET = (12), | 146 | PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET = (16), |
135 | PHY_NEG_SPP_PHYS_LINK_RATE_MASK = | 147 | PHY_NEG_SPP_PHYS_LINK_RATE_MASK = |
136 | (0x3 << PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET), | 148 | (0x3 << PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET), |
137 | }; | 149 | }; |
@@ -169,22 +181,75 @@ enum pci_interrupt_cause { | |||
169 | IRQ_PCIE_ERR = (1 << 31), | 181 | IRQ_PCIE_ERR = (1 << 31), |
170 | }; | 182 | }; |
171 | 183 | ||
184 | union reg_phy_cfg { | ||
185 | u32 v; | ||
186 | struct { | ||
187 | u32 phy_reset:1; | ||
188 | u32 sas_support:1; | ||
189 | u32 sata_support:1; | ||
190 | u32 sata_host_mode:1; | ||
191 | /* | ||
192 | * bit 2: 6Gbps support | ||
193 | * bit 1: 3Gbps support | ||
194 | * bit 0: 1.5Gbps support | ||
195 | */ | ||
196 | u32 speed_support:3; | ||
197 | u32 snw_3_support:1; | ||
198 | u32 tx_lnk_parity:1; | ||
199 | /* | ||
200 | * bit 5: G1 (1.5Gbps) Without SSC | ||
201 | * bit 4: G1 (1.5Gbps) with SSC | ||
202 | * bit 3: G2 (3.0Gbps) Without SSC | ||
203 | * bit 2: G2 (3.0Gbps) with SSC | ||
204 | * bit 1: G3 (6.0Gbps) without SSC | ||
205 | * bit 0: G3 (6.0Gbps) with SSC | ||
206 | */ | ||
207 | u32 tx_spt_phs_lnk_rate:6; | ||
208 | /* 8h: 1.5Gbps 9h: 3Gbps Ah: 6Gbps */ | ||
209 | u32 tx_lgcl_lnk_rate:4; | ||
210 | u32 tx_ssc_type:1; | ||
211 | u32 sata_spin_up_spt:1; | ||
212 | u32 sata_spin_up_en:1; | ||
213 | u32 bypass_oob:1; | ||
214 | u32 disable_phy:1; | ||
215 | u32 rsvd:8; | ||
216 | } u; | ||
217 | }; | ||
218 | |||
172 | #define MAX_SG_ENTRY 255 | 219 | #define MAX_SG_ENTRY 255 |
173 | 220 | ||
174 | struct mvs_prd_imt { | 221 | struct mvs_prd_imt { |
222 | #ifndef __BIG_ENDIAN | ||
175 | __le32 len:22; | 223 | __le32 len:22; |
176 | u8 _r_a:2; | 224 | u8 _r_a:2; |
177 | u8 misc_ctl:4; | 225 | u8 misc_ctl:4; |
178 | 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 | ||
179 | }; | 233 | }; |
180 | 234 | ||
181 | struct mvs_prd { | 235 | struct mvs_prd { |
182 | /* 64-bit buffer address */ | 236 | /* 64-bit buffer address */ |
183 | __le64 addr; | 237 | __le64 addr; |
184 | /* 22-bit length */ | 238 | /* 22-bit length */ |
185 | struct mvs_prd_imt im_len; | 239 | __le32 im_len; |
186 | } __attribute__ ((packed)); | 240 | } __attribute__ ((packed)); |
187 | 241 | ||
242 | /* | ||
243 | * these registers are accessed through port vendor | ||
244 | * specific address/data registers | ||
245 | */ | ||
246 | enum sas_sata_phy_regs { | ||
247 | GENERATION_1_SETTING = 0x118, | ||
248 | GENERATION_1_2_SETTING = 0x11C, | ||
249 | GENERATION_2_3_SETTING = 0x120, | ||
250 | GENERATION_3_4_SETTING = 0x124, | ||
251 | }; | ||
252 | |||
188 | #define SPI_CTRL_REG_94XX 0xc800 | 253 | #define SPI_CTRL_REG_94XX 0xc800 |
189 | #define SPI_ADDR_REG_94XX 0xc804 | 254 | #define SPI_ADDR_REG_94XX 0xc804 |
190 | #define SPI_WR_DATA_REG_94XX 0xc808 | 255 | #define SPI_WR_DATA_REG_94XX 0xc808 |
diff --git a/drivers/scsi/mvsas/mv_chips.h b/drivers/scsi/mvsas/mv_chips.h index 1753a6fc42d0..bcc408042cee 100644 --- a/drivers/scsi/mvsas/mv_chips.h +++ b/drivers/scsi/mvsas/mv_chips.h | |||
@@ -164,7 +164,6 @@ static inline void __devinit mvs_phy_hacks(struct mvs_info *mvi) | |||
164 | { | 164 | { |
165 | u32 tmp; | 165 | u32 tmp; |
166 | 166 | ||
167 | /* workaround for SATA R-ERR, to ignore phy glitch */ | ||
168 | tmp = mvs_cr32(mvi, CMD_PHY_TIMER); | 167 | tmp = mvs_cr32(mvi, CMD_PHY_TIMER); |
169 | tmp &= ~(1 << 9); | 168 | tmp &= ~(1 << 9); |
170 | tmp |= (1 << 10); | 169 | tmp |= (1 << 10); |
@@ -179,23 +178,10 @@ static inline void __devinit mvs_phy_hacks(struct mvs_info *mvi) | |||
179 | tmp |= 0x3fff; | 178 | tmp |= 0x3fff; |
180 | mvs_cw32(mvi, CMD_SAS_CTL0, tmp); | 179 | mvs_cw32(mvi, CMD_SAS_CTL0, tmp); |
181 | 180 | ||
182 | /* workaround for WDTIMEOUT , set to 550 ms */ | ||
183 | mvs_cw32(mvi, CMD_WD_TIMER, 0x7a0000); | 181 | mvs_cw32(mvi, CMD_WD_TIMER, 0x7a0000); |
184 | 182 | ||
185 | /* not to halt for different port op during wideport link change */ | 183 | /* not to halt for different port op during wideport link change */ |
186 | mvs_cw32(mvi, CMD_APP_ERR_CONFIG, 0xffefbf7d); | 184 | 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 | } | 185 | } |
200 | 186 | ||
201 | static inline void mvs_int_sata(struct mvs_info *mvi) | 187 | static inline void mvs_int_sata(struct mvs_info *mvi) |
@@ -223,6 +209,9 @@ static inline void mvs_int_full(struct mvs_info *mvi) | |||
223 | mvs_int_port(mvi, i, tmp); | 209 | mvs_int_port(mvi, i, tmp); |
224 | } | 210 | } |
225 | 211 | ||
212 | if (stat & CINT_NON_SPEC_NCQ_ERROR) | ||
213 | MVS_CHIP_DISP->non_spec_ncq_error(mvi); | ||
214 | |||
226 | if (stat & CINT_SRS) | 215 | if (stat & CINT_SRS) |
227 | mvs_int_sata(mvi); | 216 | mvs_int_sata(mvi); |
228 | 217 | ||
diff --git a/drivers/scsi/mvsas/mv_defs.h b/drivers/scsi/mvsas/mv_defs.h index bc00c940743c..dec7cadb7485 100644 --- a/drivers/scsi/mvsas/mv_defs.h +++ b/drivers/scsi/mvsas/mv_defs.h | |||
@@ -43,7 +43,6 @@ enum chip_flavors { | |||
43 | 43 | ||
44 | /* driver compile-time configuration */ | 44 | /* driver compile-time configuration */ |
45 | enum driver_configuration { | 45 | enum driver_configuration { |
46 | MVS_SLOTS = 512, /* command slots */ | ||
47 | MVS_TX_RING_SZ = 1024, /* TX ring size (12-bit) */ | 46 | MVS_TX_RING_SZ = 1024, /* TX ring size (12-bit) */ |
48 | MVS_RX_RING_SZ = 1024, /* RX ring size (12-bit) */ | 47 | MVS_RX_RING_SZ = 1024, /* RX ring size (12-bit) */ |
49 | /* software requires power-of-2 | 48 | /* software requires power-of-2 |
@@ -56,8 +55,7 @@ enum driver_configuration { | |||
56 | MVS_SSP_CMD_SZ = 64, /* SSP command table buffer size */ | 55 | MVS_SSP_CMD_SZ = 64, /* SSP command table buffer size */ |
57 | MVS_ATA_CMD_SZ = 96, /* SATA command table buffer size */ | 56 | MVS_ATA_CMD_SZ = 96, /* SATA command table buffer size */ |
58 | MVS_OAF_SZ = 64, /* Open address frame buffer size */ | 57 | MVS_OAF_SZ = 64, /* Open address frame buffer size */ |
59 | MVS_QUEUE_SIZE = 32, /* Support Queue depth */ | 58 | MVS_QUEUE_SIZE = 64, /* Support Queue depth */ |
60 | MVS_CAN_QUEUE = MVS_SLOTS - 2, /* SCSI Queue depth */ | ||
61 | MVS_SOC_CAN_QUEUE = MVS_SOC_SLOTS - 2, | 59 | MVS_SOC_CAN_QUEUE = MVS_SOC_SLOTS - 2, |
62 | }; | 60 | }; |
63 | 61 | ||
@@ -144,6 +142,7 @@ enum hw_register_bits { | |||
144 | CINT_DMA_PCIE = (1U << 27), /* DMA to PCIE timeout */ | 142 | CINT_DMA_PCIE = (1U << 27), /* DMA to PCIE timeout */ |
145 | CINT_MEM = (1U << 26), /* int mem parity err */ | 143 | CINT_MEM = (1U << 26), /* int mem parity err */ |
146 | CINT_I2C_SLAVE = (1U << 25), /* slave I2C event */ | 144 | CINT_I2C_SLAVE = (1U << 25), /* slave I2C event */ |
145 | CINT_NON_SPEC_NCQ_ERROR = (1U << 25), /* Non specific NCQ error */ | ||
147 | CINT_SRS = (1U << 3), /* SRS event */ | 146 | CINT_SRS = (1U << 3), /* SRS event */ |
148 | CINT_CI_STOP = (1U << 1), /* cmd issue stopped */ | 147 | CINT_CI_STOP = (1U << 1), /* cmd issue stopped */ |
149 | CINT_DONE = (1U << 0), /* cmd completion */ | 148 | CINT_DONE = (1U << 0), /* cmd completion */ |
@@ -161,7 +160,7 @@ enum hw_register_bits { | |||
161 | TXQ_CMD_SSP = 1, /* SSP protocol */ | 160 | TXQ_CMD_SSP = 1, /* SSP protocol */ |
162 | TXQ_CMD_SMP = 2, /* SMP protocol */ | 161 | TXQ_CMD_SMP = 2, /* SMP protocol */ |
163 | TXQ_CMD_STP = 3, /* STP/SATA protocol */ | 162 | TXQ_CMD_STP = 3, /* STP/SATA protocol */ |
164 | TXQ_CMD_SSP_FREE_LIST = 4, /* add to SSP targ free list */ | 163 | TXQ_CMD_SSP_FREE_LIST = 4, /* add to SSP target free list */ |
165 | TXQ_CMD_SLOT_RESET = 7, /* reset command slot */ | 164 | TXQ_CMD_SLOT_RESET = 7, /* reset command slot */ |
166 | TXQ_MODE_I = (1U << 28), /* mode: 0=target,1=initiator */ | 165 | TXQ_MODE_I = (1U << 28), /* mode: 0=target,1=initiator */ |
167 | TXQ_MODE_TARGET = 0, | 166 | TXQ_MODE_TARGET = 0, |
@@ -391,15 +390,15 @@ enum sas_cmd_port_registers { | |||
391 | }; | 390 | }; |
392 | 391 | ||
393 | enum mvs_info_flags { | 392 | enum mvs_info_flags { |
394 | MVF_MSI = (1U << 0), /* MSI is enabled */ | ||
395 | MVF_PHY_PWR_FIX = (1U << 1), /* bug workaround */ | 393 | MVF_PHY_PWR_FIX = (1U << 1), /* bug workaround */ |
396 | MVF_FLAG_SOC = (1U << 2), /* SoC integrated controllers */ | 394 | MVF_FLAG_SOC = (1U << 2), /* SoC integrated controllers */ |
397 | }; | 395 | }; |
398 | 396 | ||
399 | enum mvs_event_flags { | 397 | enum mvs_event_flags { |
400 | PHY_PLUG_EVENT = (3U), | 398 | PHY_PLUG_EVENT = (3U), |
401 | PHY_PLUG_IN = (1U << 0), /* phy plug in */ | 399 | PHY_PLUG_IN = (1U << 0), /* phy plug in */ |
402 | PHY_PLUG_OUT = (1U << 1), /* phy plug out */ | 400 | PHY_PLUG_OUT = (1U << 1), /* phy plug out */ |
401 | EXP_BRCT_CHG = (1U << 2), /* broadcast change */ | ||
403 | }; | 402 | }; |
404 | 403 | ||
405 | enum mvs_port_type { | 404 | enum mvs_port_type { |
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index 90b636611cde..4e9af66fd1d3 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c | |||
@@ -34,22 +34,25 @@ MODULE_PARM_DESC(collector, "\n" | |||
34 | "\tThe mvsas SAS LLDD supports both modes.\n" | 34 | "\tThe mvsas SAS LLDD supports both modes.\n" |
35 | "\tDefault: 1 (Direct Mode).\n"); | 35 | "\tDefault: 1 (Direct Mode).\n"); |
36 | 36 | ||
37 | int interrupt_coalescing = 0x80; | ||
38 | |||
37 | static struct scsi_transport_template *mvs_stt; | 39 | static struct scsi_transport_template *mvs_stt; |
38 | struct kmem_cache *mvs_task_list_cache; | 40 | struct kmem_cache *mvs_task_list_cache; |
39 | static const struct mvs_chip_info mvs_chips[] = { | 41 | static const struct mvs_chip_info mvs_chips[] = { |
40 | [chip_6320] = { 1, 2, 0x400, 17, 16, 9, &mvs_64xx_dispatch, }, | 42 | [chip_6320] = { 1, 2, 0x400, 17, 16, 6, 9, &mvs_64xx_dispatch, }, |
41 | [chip_6440] = { 1, 4, 0x400, 17, 16, 9, &mvs_64xx_dispatch, }, | 43 | [chip_6440] = { 1, 4, 0x400, 17, 16, 6, 9, &mvs_64xx_dispatch, }, |
42 | [chip_6485] = { 1, 8, 0x800, 33, 32, 10, &mvs_64xx_dispatch, }, | 44 | [chip_6485] = { 1, 8, 0x800, 33, 32, 6, 10, &mvs_64xx_dispatch, }, |
43 | [chip_9180] = { 2, 4, 0x800, 17, 64, 9, &mvs_94xx_dispatch, }, | 45 | [chip_9180] = { 2, 4, 0x800, 17, 64, 8, 9, &mvs_94xx_dispatch, }, |
44 | [chip_9480] = { 2, 4, 0x800, 17, 64, 9, &mvs_94xx_dispatch, }, | 46 | [chip_9480] = { 2, 4, 0x800, 17, 64, 8, 9, &mvs_94xx_dispatch, }, |
45 | [chip_9445] = { 1, 4, 0x800, 17, 64, 11, &mvs_94xx_dispatch, }, | 47 | [chip_9445] = { 1, 4, 0x800, 17, 64, 8, 11, &mvs_94xx_dispatch, }, |
46 | [chip_9485] = { 2, 4, 0x800, 17, 64, 11, &mvs_94xx_dispatch, }, | 48 | [chip_9485] = { 2, 4, 0x800, 17, 64, 8, 11, &mvs_94xx_dispatch, }, |
47 | [chip_1300] = { 1, 4, 0x400, 17, 16, 9, &mvs_64xx_dispatch, }, | 49 | [chip_1300] = { 1, 4, 0x400, 17, 16, 6, 9, &mvs_64xx_dispatch, }, |
48 | [chip_1320] = { 2, 4, 0x800, 17, 64, 9, &mvs_94xx_dispatch, }, | 50 | [chip_1320] = { 2, 4, 0x800, 17, 64, 8, 9, &mvs_94xx_dispatch, }, |
49 | }; | 51 | }; |
50 | 52 | ||
53 | struct device_attribute *mvst_host_attrs[]; | ||
54 | |||
51 | #define SOC_SAS_NUM 2 | 55 | #define SOC_SAS_NUM 2 |
52 | #define SG_MX 64 | ||
53 | 56 | ||
54 | static struct scsi_host_template mvs_sht = { | 57 | static struct scsi_host_template mvs_sht = { |
55 | .module = THIS_MODULE, | 58 | .module = THIS_MODULE, |
@@ -66,7 +69,7 @@ static struct scsi_host_template mvs_sht = { | |||
66 | .can_queue = 1, | 69 | .can_queue = 1, |
67 | .cmd_per_lun = 1, | 70 | .cmd_per_lun = 1, |
68 | .this_id = -1, | 71 | .this_id = -1, |
69 | .sg_tablesize = SG_MX, | 72 | .sg_tablesize = SG_ALL, |
70 | .max_sectors = SCSI_DEFAULT_MAX_SECTORS, | 73 | .max_sectors = SCSI_DEFAULT_MAX_SECTORS, |
71 | .use_clustering = ENABLE_CLUSTERING, | 74 | .use_clustering = ENABLE_CLUSTERING, |
72 | .eh_device_reset_handler = sas_eh_device_reset_handler, | 75 | .eh_device_reset_handler = sas_eh_device_reset_handler, |
@@ -74,6 +77,7 @@ static struct scsi_host_template mvs_sht = { | |||
74 | .slave_alloc = mvs_slave_alloc, | 77 | .slave_alloc = mvs_slave_alloc, |
75 | .target_destroy = sas_target_destroy, | 78 | .target_destroy = sas_target_destroy, |
76 | .ioctl = sas_ioctl, | 79 | .ioctl = sas_ioctl, |
80 | .shost_attrs = mvst_host_attrs, | ||
77 | }; | 81 | }; |
78 | 82 | ||
79 | static struct sas_domain_function_template mvs_transport_ops = { | 83 | static struct sas_domain_function_template mvs_transport_ops = { |
@@ -100,6 +104,7 @@ static void __devinit mvs_phy_init(struct mvs_info *mvi, int phy_id) | |||
100 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | 104 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
101 | 105 | ||
102 | phy->mvi = mvi; | 106 | phy->mvi = mvi; |
107 | phy->port = NULL; | ||
103 | init_timer(&phy->timer); | 108 | init_timer(&phy->timer); |
104 | sas_phy->enabled = (phy_id < mvi->chip->n_phy) ? 1 : 0; | 109 | sas_phy->enabled = (phy_id < mvi->chip->n_phy) ? 1 : 0; |
105 | sas_phy->class = SAS; | 110 | sas_phy->class = SAS; |
@@ -128,7 +133,7 @@ static void mvs_free(struct mvs_info *mvi) | |||
128 | if (mvi->flags & MVF_FLAG_SOC) | 133 | if (mvi->flags & MVF_FLAG_SOC) |
129 | slot_nr = MVS_SOC_SLOTS; | 134 | slot_nr = MVS_SOC_SLOTS; |
130 | else | 135 | else |
131 | slot_nr = MVS_SLOTS; | 136 | slot_nr = MVS_CHIP_SLOT_SZ; |
132 | 137 | ||
133 | if (mvi->dma_pool) | 138 | if (mvi->dma_pool) |
134 | pci_pool_destroy(mvi->dma_pool); | 139 | pci_pool_destroy(mvi->dma_pool); |
@@ -148,25 +153,26 @@ static void mvs_free(struct mvs_info *mvi) | |||
148 | dma_free_coherent(mvi->dev, | 153 | dma_free_coherent(mvi->dev, |
149 | sizeof(*mvi->slot) * slot_nr, | 154 | sizeof(*mvi->slot) * slot_nr, |
150 | mvi->slot, mvi->slot_dma); | 155 | mvi->slot, mvi->slot_dma); |
151 | #ifndef DISABLE_HOTPLUG_DMA_FIX | 156 | |
152 | if (mvi->bulk_buffer) | 157 | if (mvi->bulk_buffer) |
153 | dma_free_coherent(mvi->dev, TRASH_BUCKET_SIZE, | 158 | dma_free_coherent(mvi->dev, TRASH_BUCKET_SIZE, |
154 | mvi->bulk_buffer, mvi->bulk_buffer_dma); | 159 | mvi->bulk_buffer, mvi->bulk_buffer_dma); |
155 | #endif | 160 | if (mvi->bulk_buffer1) |
161 | dma_free_coherent(mvi->dev, TRASH_BUCKET_SIZE, | ||
162 | mvi->bulk_buffer1, mvi->bulk_buffer_dma1); | ||
156 | 163 | ||
157 | MVS_CHIP_DISP->chip_iounmap(mvi); | 164 | MVS_CHIP_DISP->chip_iounmap(mvi); |
158 | if (mvi->shost) | 165 | if (mvi->shost) |
159 | scsi_host_put(mvi->shost); | 166 | scsi_host_put(mvi->shost); |
160 | list_for_each_entry(mwq, &mvi->wq_list, entry) | 167 | list_for_each_entry(mwq, &mvi->wq_list, entry) |
161 | cancel_delayed_work(&mwq->work_q); | 168 | cancel_delayed_work(&mwq->work_q); |
169 | kfree(mvi->tags); | ||
162 | kfree(mvi); | 170 | kfree(mvi); |
163 | } | 171 | } |
164 | 172 | ||
165 | #ifdef MVS_USE_TASKLET | 173 | #ifdef CONFIG_SCSI_MVSAS_TASKLET |
166 | struct tasklet_struct mv_tasklet; | ||
167 | static void mvs_tasklet(unsigned long opaque) | 174 | static void mvs_tasklet(unsigned long opaque) |
168 | { | 175 | { |
169 | unsigned long flags; | ||
170 | u32 stat; | 176 | u32 stat; |
171 | u16 core_nr, i = 0; | 177 | u16 core_nr, i = 0; |
172 | 178 | ||
@@ -179,35 +185,49 @@ static void mvs_tasklet(unsigned long opaque) | |||
179 | if (unlikely(!mvi)) | 185 | if (unlikely(!mvi)) |
180 | BUG_ON(1); | 186 | BUG_ON(1); |
181 | 187 | ||
188 | stat = MVS_CHIP_DISP->isr_status(mvi, mvi->pdev->irq); | ||
189 | if (!stat) | ||
190 | goto out; | ||
191 | |||
182 | for (i = 0; i < core_nr; i++) { | 192 | for (i = 0; i < core_nr; i++) { |
183 | mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; | 193 | mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; |
184 | stat = MVS_CHIP_DISP->isr_status(mvi, mvi->irq); | 194 | MVS_CHIP_DISP->isr(mvi, mvi->pdev->irq, stat); |
185 | if (stat) | ||
186 | MVS_CHIP_DISP->isr(mvi, mvi->irq, stat); | ||
187 | } | 195 | } |
196 | out: | ||
197 | MVS_CHIP_DISP->interrupt_enable(mvi); | ||
188 | 198 | ||
189 | } | 199 | } |
190 | #endif | 200 | #endif |
191 | 201 | ||
192 | static irqreturn_t mvs_interrupt(int irq, void *opaque) | 202 | static irqreturn_t mvs_interrupt(int irq, void *opaque) |
193 | { | 203 | { |
194 | u32 core_nr, i = 0; | 204 | u32 core_nr; |
195 | u32 stat; | 205 | u32 stat; |
196 | struct mvs_info *mvi; | 206 | struct mvs_info *mvi; |
197 | struct sas_ha_struct *sha = opaque; | 207 | struct sas_ha_struct *sha = opaque; |
208 | #ifndef CONFIG_SCSI_MVSAS_TASKLET | ||
209 | u32 i; | ||
210 | #endif | ||
198 | 211 | ||
199 | core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; | 212 | core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; |
200 | mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0]; | 213 | mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0]; |
201 | 214 | ||
202 | if (unlikely(!mvi)) | 215 | if (unlikely(!mvi)) |
203 | return IRQ_NONE; | 216 | return IRQ_NONE; |
217 | #ifdef CONFIG_SCSI_MVSAS_TASKLET | ||
218 | MVS_CHIP_DISP->interrupt_disable(mvi); | ||
219 | #endif | ||
204 | 220 | ||
205 | stat = MVS_CHIP_DISP->isr_status(mvi, irq); | 221 | stat = MVS_CHIP_DISP->isr_status(mvi, irq); |
206 | if (!stat) | 222 | if (!stat) { |
223 | #ifdef CONFIG_SCSI_MVSAS_TASKLET | ||
224 | MVS_CHIP_DISP->interrupt_enable(mvi); | ||
225 | #endif | ||
207 | return IRQ_NONE; | 226 | return IRQ_NONE; |
227 | } | ||
208 | 228 | ||
209 | #ifdef MVS_USE_TASKLET | 229 | #ifdef CONFIG_SCSI_MVSAS_TASKLET |
210 | tasklet_schedule(&mv_tasklet); | 230 | tasklet_schedule(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet); |
211 | #else | 231 | #else |
212 | for (i = 0; i < core_nr; i++) { | 232 | for (i = 0; i < core_nr; i++) { |
213 | mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; | 233 | mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; |
@@ -225,7 +245,7 @@ static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost) | |||
225 | if (mvi->flags & MVF_FLAG_SOC) | 245 | if (mvi->flags & MVF_FLAG_SOC) |
226 | slot_nr = MVS_SOC_SLOTS; | 246 | slot_nr = MVS_SOC_SLOTS; |
227 | else | 247 | else |
228 | slot_nr = MVS_SLOTS; | 248 | slot_nr = MVS_CHIP_SLOT_SZ; |
229 | 249 | ||
230 | spin_lock_init(&mvi->lock); | 250 | spin_lock_init(&mvi->lock); |
231 | for (i = 0; i < mvi->chip->n_phy; i++) { | 251 | for (i = 0; i < mvi->chip->n_phy; i++) { |
@@ -273,13 +293,18 @@ static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost) | |||
273 | goto err_out; | 293 | goto err_out; |
274 | memset(mvi->slot, 0, sizeof(*mvi->slot) * slot_nr); | 294 | memset(mvi->slot, 0, sizeof(*mvi->slot) * slot_nr); |
275 | 295 | ||
276 | #ifndef DISABLE_HOTPLUG_DMA_FIX | ||
277 | mvi->bulk_buffer = dma_alloc_coherent(mvi->dev, | 296 | mvi->bulk_buffer = dma_alloc_coherent(mvi->dev, |
278 | TRASH_BUCKET_SIZE, | 297 | TRASH_BUCKET_SIZE, |
279 | &mvi->bulk_buffer_dma, GFP_KERNEL); | 298 | &mvi->bulk_buffer_dma, GFP_KERNEL); |
280 | if (!mvi->bulk_buffer) | 299 | if (!mvi->bulk_buffer) |
281 | goto err_out; | 300 | goto err_out; |
282 | #endif | 301 | |
302 | mvi->bulk_buffer1 = dma_alloc_coherent(mvi->dev, | ||
303 | TRASH_BUCKET_SIZE, | ||
304 | &mvi->bulk_buffer_dma1, GFP_KERNEL); | ||
305 | if (!mvi->bulk_buffer1) | ||
306 | goto err_out; | ||
307 | |||
283 | sprintf(pool_name, "%s%d", "mvs_dma_pool", mvi->id); | 308 | sprintf(pool_name, "%s%d", "mvs_dma_pool", mvi->id); |
284 | mvi->dma_pool = pci_pool_create(pool_name, mvi->pdev, MVS_SLOT_BUF_SZ, 16, 0); | 309 | mvi->dma_pool = pci_pool_create(pool_name, mvi->pdev, MVS_SLOT_BUF_SZ, 16, 0); |
285 | if (!mvi->dma_pool) { | 310 | if (!mvi->dma_pool) { |
@@ -354,11 +379,12 @@ static struct mvs_info *__devinit mvs_pci_alloc(struct pci_dev *pdev, | |||
354 | const struct pci_device_id *ent, | 379 | const struct pci_device_id *ent, |
355 | struct Scsi_Host *shost, unsigned int id) | 380 | struct Scsi_Host *shost, unsigned int id) |
356 | { | 381 | { |
357 | struct mvs_info *mvi; | 382 | struct mvs_info *mvi = NULL; |
358 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); | 383 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); |
359 | 384 | ||
360 | mvi = kzalloc(sizeof(*mvi) + MVS_SLOTS * sizeof(struct mvs_slot_info), | 385 | mvi = kzalloc(sizeof(*mvi) + |
361 | GFP_KERNEL); | 386 | (1L << mvs_chips[ent->driver_data].slot_width) * |
387 | sizeof(struct mvs_slot_info), GFP_KERNEL); | ||
362 | if (!mvi) | 388 | if (!mvi) |
363 | return NULL; | 389 | return NULL; |
364 | 390 | ||
@@ -367,7 +393,6 @@ static struct mvs_info *__devinit mvs_pci_alloc(struct pci_dev *pdev, | |||
367 | mvi->chip_id = ent->driver_data; | 393 | mvi->chip_id = ent->driver_data; |
368 | mvi->chip = &mvs_chips[mvi->chip_id]; | 394 | mvi->chip = &mvs_chips[mvi->chip_id]; |
369 | INIT_LIST_HEAD(&mvi->wq_list); | 395 | INIT_LIST_HEAD(&mvi->wq_list); |
370 | mvi->irq = pdev->irq; | ||
371 | 396 | ||
372 | ((struct mvs_prv_info *)sha->lldd_ha)->mvi[id] = mvi; | 397 | ((struct mvs_prv_info *)sha->lldd_ha)->mvi[id] = mvi; |
373 | ((struct mvs_prv_info *)sha->lldd_ha)->n_phy = mvi->chip->n_phy; | 398 | ((struct mvs_prv_info *)sha->lldd_ha)->n_phy = mvi->chip->n_phy; |
@@ -375,9 +400,10 @@ static struct mvs_info *__devinit mvs_pci_alloc(struct pci_dev *pdev, | |||
375 | mvi->id = id; | 400 | mvi->id = id; |
376 | mvi->sas = sha; | 401 | mvi->sas = sha; |
377 | mvi->shost = shost; | 402 | mvi->shost = shost; |
378 | #ifdef MVS_USE_TASKLET | 403 | |
379 | tasklet_init(&mv_tasklet, mvs_tasklet, (unsigned long)sha); | 404 | mvi->tags = kzalloc(MVS_CHIP_SLOT_SZ>>3, GFP_KERNEL); |
380 | #endif | 405 | if (!mvi->tags) |
406 | goto err_out; | ||
381 | 407 | ||
382 | if (MVS_CHIP_DISP->chip_ioremap(mvi)) | 408 | if (MVS_CHIP_DISP->chip_ioremap(mvi)) |
383 | goto err_out; | 409 | goto err_out; |
@@ -388,7 +414,6 @@ err_out: | |||
388 | return NULL; | 414 | return NULL; |
389 | } | 415 | } |
390 | 416 | ||
391 | /* move to PCI layer or libata core? */ | ||
392 | static int pci_go_64(struct pci_dev *pdev) | 417 | static int pci_go_64(struct pci_dev *pdev) |
393 | { | 418 | { |
394 | int rc; | 419 | int rc; |
@@ -450,7 +475,7 @@ static int __devinit mvs_prep_sas_ha_init(struct Scsi_Host *shost, | |||
450 | ((struct mvs_prv_info *)sha->lldd_ha)->n_host = core_nr; | 475 | ((struct mvs_prv_info *)sha->lldd_ha)->n_host = core_nr; |
451 | 476 | ||
452 | shost->transportt = mvs_stt; | 477 | shost->transportt = mvs_stt; |
453 | shost->max_id = 128; | 478 | shost->max_id = MVS_MAX_DEVICES; |
454 | shost->max_lun = ~0; | 479 | shost->max_lun = ~0; |
455 | shost->max_channel = 1; | 480 | shost->max_channel = 1; |
456 | shost->max_cmd_len = 16; | 481 | shost->max_cmd_len = 16; |
@@ -493,11 +518,12 @@ static void __devinit mvs_post_sas_ha_init(struct Scsi_Host *shost, | |||
493 | if (mvi->flags & MVF_FLAG_SOC) | 518 | if (mvi->flags & MVF_FLAG_SOC) |
494 | can_queue = MVS_SOC_CAN_QUEUE; | 519 | can_queue = MVS_SOC_CAN_QUEUE; |
495 | else | 520 | else |
496 | can_queue = MVS_CAN_QUEUE; | 521 | can_queue = MVS_CHIP_SLOT_SZ; |
497 | 522 | ||
498 | sha->lldd_queue_size = can_queue; | 523 | sha->lldd_queue_size = can_queue; |
524 | shost->sg_tablesize = min_t(u16, SG_ALL, MVS_MAX_SG); | ||
499 | shost->can_queue = can_queue; | 525 | shost->can_queue = can_queue; |
500 | mvi->shost->cmd_per_lun = MVS_SLOTS/sha->num_phys; | 526 | mvi->shost->cmd_per_lun = MVS_QUEUE_SIZE; |
501 | sha->core.shost = mvi->shost; | 527 | sha->core.shost = mvi->shost; |
502 | } | 528 | } |
503 | 529 | ||
@@ -518,6 +544,7 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev, | |||
518 | { | 544 | { |
519 | unsigned int rc, nhost = 0; | 545 | unsigned int rc, nhost = 0; |
520 | struct mvs_info *mvi; | 546 | struct mvs_info *mvi; |
547 | struct mvs_prv_info *mpi; | ||
521 | irq_handler_t irq_handler = mvs_interrupt; | 548 | irq_handler_t irq_handler = mvs_interrupt; |
522 | struct Scsi_Host *shost = NULL; | 549 | struct Scsi_Host *shost = NULL; |
523 | const struct mvs_chip_info *chip; | 550 | const struct mvs_chip_info *chip; |
@@ -569,6 +596,9 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev, | |||
569 | goto err_out_regions; | 596 | goto err_out_regions; |
570 | } | 597 | } |
571 | 598 | ||
599 | memset(&mvi->hba_info_param, 0xFF, | ||
600 | sizeof(struct hba_info_page)); | ||
601 | |||
572 | mvs_init_sas_add(mvi); | 602 | mvs_init_sas_add(mvi); |
573 | 603 | ||
574 | mvi->instance = nhost; | 604 | mvi->instance = nhost; |
@@ -579,8 +609,9 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev, | |||
579 | } | 609 | } |
580 | nhost++; | 610 | nhost++; |
581 | } while (nhost < chip->n_host); | 611 | } while (nhost < chip->n_host); |
582 | #ifdef MVS_USE_TASKLET | 612 | mpi = (struct mvs_prv_info *)(SHOST_TO_SAS_HA(shost)->lldd_ha); |
583 | tasklet_init(&mv_tasklet, mvs_tasklet, | 613 | #ifdef CONFIG_SCSI_MVSAS_TASKLET |
614 | tasklet_init(&(mpi->mv_tasklet), mvs_tasklet, | ||
584 | (unsigned long)SHOST_TO_SAS_HA(shost)); | 615 | (unsigned long)SHOST_TO_SAS_HA(shost)); |
585 | #endif | 616 | #endif |
586 | 617 | ||
@@ -625,8 +656,8 @@ static void __devexit mvs_pci_remove(struct pci_dev *pdev) | |||
625 | core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; | 656 | core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; |
626 | mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0]; | 657 | mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0]; |
627 | 658 | ||
628 | #ifdef MVS_USE_TASKLET | 659 | #ifdef CONFIG_SCSI_MVSAS_TASKLET |
629 | tasklet_kill(&mv_tasklet); | 660 | tasklet_kill(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet); |
630 | #endif | 661 | #endif |
631 | 662 | ||
632 | pci_set_drvdata(pdev, NULL); | 663 | pci_set_drvdata(pdev, NULL); |
@@ -635,7 +666,7 @@ static void __devexit mvs_pci_remove(struct pci_dev *pdev) | |||
635 | scsi_remove_host(mvi->shost); | 666 | scsi_remove_host(mvi->shost); |
636 | 667 | ||
637 | MVS_CHIP_DISP->interrupt_disable(mvi); | 668 | MVS_CHIP_DISP->interrupt_disable(mvi); |
638 | free_irq(mvi->irq, sha); | 669 | free_irq(mvi->pdev->irq, sha); |
639 | for (i = 0; i < core_nr; i++) { | 670 | for (i = 0; i < core_nr; i++) { |
640 | mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; | 671 | mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; |
641 | mvs_free(mvi); | 672 | mvs_free(mvi); |
@@ -703,6 +734,70 @@ static struct pci_driver mvs_pci_driver = { | |||
703 | .remove = __devexit_p(mvs_pci_remove), | 734 | .remove = __devexit_p(mvs_pci_remove), |
704 | }; | 735 | }; |
705 | 736 | ||
737 | static ssize_t | ||
738 | mvs_show_driver_version(struct device *cdev, | ||
739 | struct device_attribute *attr, char *buffer) | ||
740 | { | ||
741 | return snprintf(buffer, PAGE_SIZE, "%s\n", DRV_VERSION); | ||
742 | } | ||
743 | |||
744 | static DEVICE_ATTR(driver_version, | ||
745 | S_IRUGO, | ||
746 | mvs_show_driver_version, | ||
747 | NULL); | ||
748 | |||
749 | static ssize_t | ||
750 | mvs_store_interrupt_coalescing(struct device *cdev, | ||
751 | struct device_attribute *attr, | ||
752 | const char *buffer, size_t size) | ||
753 | { | ||
754 | int val = 0; | ||
755 | struct mvs_info *mvi = NULL; | ||
756 | struct Scsi_Host *shost = class_to_shost(cdev); | ||
757 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); | ||
758 | u8 i, core_nr; | ||
759 | if (buffer == NULL) | ||
760 | return size; | ||
761 | |||
762 | if (sscanf(buffer, "%d", &val) != 1) | ||
763 | return -EINVAL; | ||
764 | |||
765 | if (val >= 0x10000) { | ||
766 | mv_dprintk("interrupt coalescing timer %d us is" | ||
767 | "too long\n", val); | ||
768 | return strlen(buffer); | ||
769 | } | ||
770 | |||
771 | interrupt_coalescing = val; | ||
772 | |||
773 | core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; | ||
774 | mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0]; | ||
775 | |||
776 | if (unlikely(!mvi)) | ||
777 | return -EINVAL; | ||
778 | |||
779 | for (i = 0; i < core_nr; i++) { | ||
780 | mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; | ||
781 | if (MVS_CHIP_DISP->tune_interrupt) | ||
782 | MVS_CHIP_DISP->tune_interrupt(mvi, | ||
783 | interrupt_coalescing); | ||
784 | } | ||
785 | mv_dprintk("set interrupt coalescing time to %d us\n", | ||
786 | interrupt_coalescing); | ||
787 | return strlen(buffer); | ||
788 | } | ||
789 | |||
790 | static ssize_t mvs_show_interrupt_coalescing(struct device *cdev, | ||
791 | struct device_attribute *attr, char *buffer) | ||
792 | { | ||
793 | return snprintf(buffer, PAGE_SIZE, "%d\n", interrupt_coalescing); | ||
794 | } | ||
795 | |||
796 | static DEVICE_ATTR(interrupt_coalescing, | ||
797 | S_IRUGO|S_IWUSR, | ||
798 | mvs_show_interrupt_coalescing, | ||
799 | mvs_store_interrupt_coalescing); | ||
800 | |||
706 | /* task handler */ | 801 | /* task handler */ |
707 | struct task_struct *mvs_th; | 802 | struct task_struct *mvs_th; |
708 | static int __init mvs_init(void) | 803 | static int __init mvs_init(void) |
@@ -739,6 +834,12 @@ static void __exit mvs_exit(void) | |||
739 | kmem_cache_destroy(mvs_task_list_cache); | 834 | kmem_cache_destroy(mvs_task_list_cache); |
740 | } | 835 | } |
741 | 836 | ||
837 | struct device_attribute *mvst_host_attrs[] = { | ||
838 | &dev_attr_driver_version, | ||
839 | &dev_attr_interrupt_coalescing, | ||
840 | NULL, | ||
841 | }; | ||
842 | |||
742 | module_init(mvs_init); | 843 | module_init(mvs_init); |
743 | module_exit(mvs_exit); | 844 | module_exit(mvs_exit); |
744 | 845 | ||
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index 0ef27425c447..4958fefff365 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c | |||
@@ -38,7 +38,7 @@ static int mvs_find_tag(struct mvs_info *mvi, struct sas_task *task, u32 *tag) | |||
38 | 38 | ||
39 | void mvs_tag_clear(struct mvs_info *mvi, u32 tag) | 39 | void mvs_tag_clear(struct mvs_info *mvi, u32 tag) |
40 | { | 40 | { |
41 | void *bitmap = &mvi->tags; | 41 | void *bitmap = mvi->tags; |
42 | clear_bit(tag, bitmap); | 42 | clear_bit(tag, bitmap); |
43 | } | 43 | } |
44 | 44 | ||
@@ -49,14 +49,14 @@ void mvs_tag_free(struct mvs_info *mvi, u32 tag) | |||
49 | 49 | ||
50 | void mvs_tag_set(struct mvs_info *mvi, unsigned int tag) | 50 | void mvs_tag_set(struct mvs_info *mvi, unsigned int tag) |
51 | { | 51 | { |
52 | void *bitmap = &mvi->tags; | 52 | void *bitmap = mvi->tags; |
53 | set_bit(tag, bitmap); | 53 | set_bit(tag, bitmap); |
54 | } | 54 | } |
55 | 55 | ||
56 | inline int mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out) | 56 | inline int mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out) |
57 | { | 57 | { |
58 | unsigned int index, tag; | 58 | unsigned int index, tag; |
59 | void *bitmap = &mvi->tags; | 59 | void *bitmap = mvi->tags; |
60 | 60 | ||
61 | index = find_first_zero_bit(bitmap, mvi->tags_num); | 61 | index = find_first_zero_bit(bitmap, mvi->tags_num); |
62 | tag = index; | 62 | tag = index; |
@@ -74,126 +74,6 @@ void mvs_tag_init(struct mvs_info *mvi) | |||
74 | mvs_tag_clear(mvi, i); | 74 | mvs_tag_clear(mvi, i); |
75 | } | 75 | } |
76 | 76 | ||
77 | void mvs_hexdump(u32 size, u8 *data, u32 baseaddr) | ||
78 | { | ||
79 | u32 i; | ||
80 | u32 run; | ||
81 | u32 offset; | ||
82 | |||
83 | offset = 0; | ||
84 | while (size) { | ||
85 | printk(KERN_DEBUG"%08X : ", baseaddr + offset); | ||
86 | if (size >= 16) | ||
87 | run = 16; | ||
88 | else | ||
89 | run = size; | ||
90 | size -= run; | ||
91 | for (i = 0; i < 16; i++) { | ||
92 | if (i < run) | ||
93 | printk(KERN_DEBUG"%02X ", (u32)data[i]); | ||
94 | else | ||
95 | printk(KERN_DEBUG" "); | ||
96 | } | ||
97 | printk(KERN_DEBUG": "); | ||
98 | for (i = 0; i < run; i++) | ||
99 | printk(KERN_DEBUG"%c", | ||
100 | isalnum(data[i]) ? data[i] : '.'); | ||
101 | printk(KERN_DEBUG"\n"); | ||
102 | data = &data[16]; | ||
103 | offset += run; | ||
104 | } | ||
105 | printk(KERN_DEBUG"\n"); | ||
106 | } | ||
107 | |||
108 | #if (_MV_DUMP > 1) | ||
109 | static void mvs_hba_sb_dump(struct mvs_info *mvi, u32 tag, | ||
110 | enum sas_protocol proto) | ||
111 | { | ||
112 | u32 offset; | ||
113 | struct mvs_slot_info *slot = &mvi->slot_info[tag]; | ||
114 | |||
115 | offset = slot->cmd_size + MVS_OAF_SZ + | ||
116 | MVS_CHIP_DISP->prd_size() * slot->n_elem; | ||
117 | dev_printk(KERN_DEBUG, mvi->dev, "+---->Status buffer[%d] :\n", | ||
118 | tag); | ||
119 | mvs_hexdump(32, (u8 *) slot->response, | ||
120 | (u32) slot->buf_dma + offset); | ||
121 | } | ||
122 | #endif | ||
123 | |||
124 | static void mvs_hba_memory_dump(struct mvs_info *mvi, u32 tag, | ||
125 | enum sas_protocol proto) | ||
126 | { | ||
127 | #if (_MV_DUMP > 1) | ||
128 | u32 sz, w_ptr; | ||
129 | u64 addr; | ||
130 | struct mvs_slot_info *slot = &mvi->slot_info[tag]; | ||
131 | |||
132 | /*Delivery Queue */ | ||
133 | sz = MVS_CHIP_SLOT_SZ; | ||
134 | w_ptr = slot->tx; | ||
135 | addr = mvi->tx_dma; | ||
136 | dev_printk(KERN_DEBUG, mvi->dev, | ||
137 | "Delivery Queue Size=%04d , WRT_PTR=%04X\n", sz, w_ptr); | ||
138 | dev_printk(KERN_DEBUG, mvi->dev, | ||
139 | "Delivery Queue Base Address=0x%llX (PA)" | ||
140 | "(tx_dma=0x%llX), Entry=%04d\n", | ||
141 | addr, (unsigned long long)mvi->tx_dma, w_ptr); | ||
142 | mvs_hexdump(sizeof(u32), (u8 *)(&mvi->tx[mvi->tx_prod]), | ||
143 | (u32) mvi->tx_dma + sizeof(u32) * w_ptr); | ||
144 | /*Command List */ | ||
145 | addr = mvi->slot_dma; | ||
146 | dev_printk(KERN_DEBUG, mvi->dev, | ||
147 | "Command List Base Address=0x%llX (PA)" | ||
148 | "(slot_dma=0x%llX), Header=%03d\n", | ||
149 | addr, (unsigned long long)slot->buf_dma, tag); | ||
150 | dev_printk(KERN_DEBUG, mvi->dev, "Command Header[%03d]:\n", tag); | ||
151 | /*mvs_cmd_hdr */ | ||
152 | mvs_hexdump(sizeof(struct mvs_cmd_hdr), (u8 *)(&mvi->slot[tag]), | ||
153 | (u32) mvi->slot_dma + tag * sizeof(struct mvs_cmd_hdr)); | ||
154 | /*1.command table area */ | ||
155 | dev_printk(KERN_DEBUG, mvi->dev, "+---->Command Table :\n"); | ||
156 | mvs_hexdump(slot->cmd_size, (u8 *) slot->buf, (u32) slot->buf_dma); | ||
157 | /*2.open address frame area */ | ||
158 | dev_printk(KERN_DEBUG, mvi->dev, "+---->Open Address Frame :\n"); | ||
159 | mvs_hexdump(MVS_OAF_SZ, (u8 *) slot->buf + slot->cmd_size, | ||
160 | (u32) slot->buf_dma + slot->cmd_size); | ||
161 | /*3.status buffer */ | ||
162 | mvs_hba_sb_dump(mvi, tag, proto); | ||
163 | /*4.PRD table */ | ||
164 | dev_printk(KERN_DEBUG, mvi->dev, "+---->PRD table :\n"); | ||
165 | mvs_hexdump(MVS_CHIP_DISP->prd_size() * slot->n_elem, | ||
166 | (u8 *) slot->buf + slot->cmd_size + MVS_OAF_SZ, | ||
167 | (u32) slot->buf_dma + slot->cmd_size + MVS_OAF_SZ); | ||
168 | #endif | ||
169 | } | ||
170 | |||
171 | static void mvs_hba_cq_dump(struct mvs_info *mvi) | ||
172 | { | ||
173 | #if (_MV_DUMP > 2) | ||
174 | u64 addr; | ||
175 | void __iomem *regs = mvi->regs; | ||
176 | u32 entry = mvi->rx_cons + 1; | ||
177 | u32 rx_desc = le32_to_cpu(mvi->rx[entry]); | ||
178 | |||
179 | /*Completion Queue */ | ||
180 | addr = mr32(RX_HI) << 16 << 16 | mr32(RX_LO); | ||
181 | dev_printk(KERN_DEBUG, mvi->dev, "Completion Task = 0x%p\n", | ||
182 | mvi->slot_info[rx_desc & RXQ_SLOT_MASK].task); | ||
183 | dev_printk(KERN_DEBUG, mvi->dev, | ||
184 | "Completion List Base Address=0x%llX (PA), " | ||
185 | "CQ_Entry=%04d, CQ_WP=0x%08X\n", | ||
186 | addr, entry - 1, mvi->rx[0]); | ||
187 | mvs_hexdump(sizeof(u32), (u8 *)(&rx_desc), | ||
188 | mvi->rx_dma + sizeof(u32) * entry); | ||
189 | #endif | ||
190 | } | ||
191 | |||
192 | void mvs_get_sas_addr(void *buf, u32 buflen) | ||
193 | { | ||
194 | /*memcpy(buf, "\x50\x05\x04\x30\x11\xab\x64\x40", 8);*/ | ||
195 | } | ||
196 | |||
197 | struct mvs_info *mvs_find_dev_mvi(struct domain_device *dev) | 77 | struct mvs_info *mvs_find_dev_mvi(struct domain_device *dev) |
198 | { | 78 | { |
199 | unsigned long i = 0, j = 0, hi = 0; | 79 | unsigned long i = 0, j = 0, hi = 0; |
@@ -222,7 +102,6 @@ struct mvs_info *mvs_find_dev_mvi(struct domain_device *dev) | |||
222 | 102 | ||
223 | } | 103 | } |
224 | 104 | ||
225 | /* FIXME */ | ||
226 | int mvs_find_dev_phyno(struct domain_device *dev, int *phyno) | 105 | int mvs_find_dev_phyno(struct domain_device *dev, int *phyno) |
227 | { | 106 | { |
228 | unsigned long i = 0, j = 0, n = 0, num = 0; | 107 | unsigned long i = 0, j = 0, n = 0, num = 0; |
@@ -253,6 +132,20 @@ int mvs_find_dev_phyno(struct domain_device *dev, int *phyno) | |||
253 | return num; | 132 | return num; |
254 | } | 133 | } |
255 | 134 | ||
135 | struct mvs_device *mvs_find_dev_by_reg_set(struct mvs_info *mvi, | ||
136 | u8 reg_set) | ||
137 | { | ||
138 | u32 dev_no; | ||
139 | for (dev_no = 0; dev_no < MVS_MAX_DEVICES; dev_no++) { | ||
140 | if (mvi->devices[dev_no].taskfileset == MVS_ID_NOT_MAPPED) | ||
141 | continue; | ||
142 | |||
143 | if (mvi->devices[dev_no].taskfileset == reg_set) | ||
144 | return &mvi->devices[dev_no]; | ||
145 | } | ||
146 | return NULL; | ||
147 | } | ||
148 | |||
256 | static inline void mvs_free_reg_set(struct mvs_info *mvi, | 149 | static inline void mvs_free_reg_set(struct mvs_info *mvi, |
257 | struct mvs_device *dev) | 150 | struct mvs_device *dev) |
258 | { | 151 | { |
@@ -283,7 +176,6 @@ void mvs_phys_reset(struct mvs_info *mvi, u32 phy_mask, int hard) | |||
283 | } | 176 | } |
284 | } | 177 | } |
285 | 178 | ||
286 | /* FIXME: locking? */ | ||
287 | int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, | 179 | int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, |
288 | void *funcdata) | 180 | void *funcdata) |
289 | { | 181 | { |
@@ -309,12 +201,12 @@ int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, | |||
309 | tmp = MVS_CHIP_DISP->read_phy_ctl(mvi, phy_id); | 201 | tmp = MVS_CHIP_DISP->read_phy_ctl(mvi, phy_id); |
310 | if (tmp & PHY_RST_HARD) | 202 | if (tmp & PHY_RST_HARD) |
311 | break; | 203 | break; |
312 | MVS_CHIP_DISP->phy_reset(mvi, phy_id, 1); | 204 | MVS_CHIP_DISP->phy_reset(mvi, phy_id, MVS_HARD_RESET); |
313 | break; | 205 | break; |
314 | 206 | ||
315 | case PHY_FUNC_LINK_RESET: | 207 | case PHY_FUNC_LINK_RESET: |
316 | MVS_CHIP_DISP->phy_enable(mvi, phy_id); | 208 | MVS_CHIP_DISP->phy_enable(mvi, phy_id); |
317 | MVS_CHIP_DISP->phy_reset(mvi, phy_id, 0); | 209 | MVS_CHIP_DISP->phy_reset(mvi, phy_id, MVS_SOFT_RESET); |
318 | break; | 210 | break; |
319 | 211 | ||
320 | case PHY_FUNC_DISABLE: | 212 | case PHY_FUNC_DISABLE: |
@@ -406,14 +298,10 @@ int mvs_slave_configure(struct scsi_device *sdev) | |||
406 | 298 | ||
407 | if (ret) | 299 | if (ret) |
408 | return ret; | 300 | return ret; |
409 | if (dev_is_sata(dev)) { | 301 | if (!dev_is_sata(dev)) { |
410 | /* may set PIO mode */ | 302 | sas_change_queue_depth(sdev, |
411 | #if MV_DISABLE_NCQ | 303 | MVS_QUEUE_SIZE, |
412 | struct ata_port *ap = dev->sata_dev.ap; | 304 | SCSI_QDEPTH_DEFAULT); |
413 | struct ata_device *adev = ap->link.device; | ||
414 | adev->flags |= ATA_DFLAG_NCQ_OFF; | ||
415 | scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, 1); | ||
416 | #endif | ||
417 | } | 305 | } |
418 | return 0; | 306 | return 0; |
419 | } | 307 | } |
@@ -424,6 +312,7 @@ void mvs_scan_start(struct Scsi_Host *shost) | |||
424 | unsigned short core_nr; | 312 | unsigned short core_nr; |
425 | struct mvs_info *mvi; | 313 | struct mvs_info *mvi; |
426 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); | 314 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); |
315 | struct mvs_prv_info *mvs_prv = sha->lldd_ha; | ||
427 | 316 | ||
428 | core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; | 317 | core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; |
429 | 318 | ||
@@ -432,15 +321,17 @@ void mvs_scan_start(struct Scsi_Host *shost) | |||
432 | for (i = 0; i < mvi->chip->n_phy; ++i) | 321 | for (i = 0; i < mvi->chip->n_phy; ++i) |
433 | mvs_bytes_dmaed(mvi, i); | 322 | mvs_bytes_dmaed(mvi, i); |
434 | } | 323 | } |
324 | mvs_prv->scan_finished = 1; | ||
435 | } | 325 | } |
436 | 326 | ||
437 | int mvs_scan_finished(struct Scsi_Host *shost, unsigned long time) | 327 | int mvs_scan_finished(struct Scsi_Host *shost, unsigned long time) |
438 | { | 328 | { |
439 | /* give the phy enabling interrupt event time to come in (1s | 329 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); |
440 | * is empirically about all it takes) */ | 330 | struct mvs_prv_info *mvs_prv = sha->lldd_ha; |
441 | if (time < HZ) | 331 | |
332 | if (mvs_prv->scan_finished == 0) | ||
442 | return 0; | 333 | return 0; |
443 | /* Wait for discovery to finish */ | 334 | |
444 | scsi_flush_work(shost); | 335 | scsi_flush_work(shost); |
445 | return 1; | 336 | return 1; |
446 | } | 337 | } |
@@ -461,10 +352,7 @@ static int mvs_task_prep_smp(struct mvs_info *mvi, | |||
461 | void *buf_prd; | 352 | void *buf_prd; |
462 | struct mvs_slot_info *slot = &mvi->slot_info[tag]; | 353 | struct mvs_slot_info *slot = &mvi->slot_info[tag]; |
463 | u32 flags = (tei->n_elem << MCH_PRD_LEN_SHIFT); | 354 | u32 flags = (tei->n_elem << MCH_PRD_LEN_SHIFT); |
464 | #if _MV_DUMP | 355 | |
465 | u8 *buf_cmd; | ||
466 | void *from; | ||
467 | #endif | ||
468 | /* | 356 | /* |
469 | * DMA-map SMP request, response buffers | 357 | * DMA-map SMP request, response buffers |
470 | */ | 358 | */ |
@@ -496,15 +384,7 @@ static int mvs_task_prep_smp(struct mvs_info *mvi, | |||
496 | buf_tmp = slot->buf; | 384 | buf_tmp = slot->buf; |
497 | buf_tmp_dma = slot->buf_dma; | 385 | buf_tmp_dma = slot->buf_dma; |
498 | 386 | ||
499 | #if _MV_DUMP | ||
500 | buf_cmd = buf_tmp; | ||
501 | hdr->cmd_tbl = cpu_to_le64(buf_tmp_dma); | ||
502 | buf_tmp += req_len; | ||
503 | buf_tmp_dma += req_len; | ||
504 | slot->cmd_size = req_len; | ||
505 | #else | ||
506 | hdr->cmd_tbl = cpu_to_le64(sg_dma_address(sg_req)); | 387 | hdr->cmd_tbl = cpu_to_le64(sg_dma_address(sg_req)); |
507 | #endif | ||
508 | 388 | ||
509 | /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */ | 389 | /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */ |
510 | buf_oaf = buf_tmp; | 390 | buf_oaf = buf_tmp; |
@@ -553,12 +433,6 @@ static int mvs_task_prep_smp(struct mvs_info *mvi, | |||
553 | /* fill in PRD (scatter/gather) table, if any */ | 433 | /* fill in PRD (scatter/gather) table, if any */ |
554 | MVS_CHIP_DISP->make_prd(task->scatter, tei->n_elem, buf_prd); | 434 | MVS_CHIP_DISP->make_prd(task->scatter, tei->n_elem, buf_prd); |
555 | 435 | ||
556 | #if _MV_DUMP | ||
557 | /* copy cmd table */ | ||
558 | from = kmap_atomic(sg_page(sg_req), KM_IRQ0); | ||
559 | memcpy(buf_cmd, from + sg_req->offset, req_len); | ||
560 | kunmap_atomic(from, KM_IRQ0); | ||
561 | #endif | ||
562 | return 0; | 436 | return 0; |
563 | 437 | ||
564 | err_out_2: | 438 | err_out_2: |
@@ -616,14 +490,11 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, | |||
616 | (mvi_dev->taskfileset << TXQ_SRS_SHIFT); | 490 | (mvi_dev->taskfileset << TXQ_SRS_SHIFT); |
617 | mvi->tx[mvi->tx_prod] = cpu_to_le32(del_q); | 491 | mvi->tx[mvi->tx_prod] = cpu_to_le32(del_q); |
618 | 492 | ||
619 | #ifndef DISABLE_HOTPLUG_DMA_FIX | ||
620 | if (task->data_dir == DMA_FROM_DEVICE) | 493 | if (task->data_dir == DMA_FROM_DEVICE) |
621 | flags = (MVS_CHIP_DISP->prd_count() << MCH_PRD_LEN_SHIFT); | 494 | flags = (MVS_CHIP_DISP->prd_count() << MCH_PRD_LEN_SHIFT); |
622 | else | 495 | else |
623 | flags = (tei->n_elem << MCH_PRD_LEN_SHIFT); | 496 | flags = (tei->n_elem << MCH_PRD_LEN_SHIFT); |
624 | #else | 497 | |
625 | flags = (tei->n_elem << MCH_PRD_LEN_SHIFT); | ||
626 | #endif | ||
627 | if (task->ata_task.use_ncq) | 498 | if (task->ata_task.use_ncq) |
628 | flags |= MCH_FPDMA; | 499 | flags |= MCH_FPDMA; |
629 | if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) { | 500 | if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) { |
@@ -631,11 +502,8 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, | |||
631 | flags |= MCH_ATAPI; | 502 | flags |= MCH_ATAPI; |
632 | } | 503 | } |
633 | 504 | ||
634 | /* FIXME: fill in port multiplier number */ | ||
635 | |||
636 | hdr->flags = cpu_to_le32(flags); | 505 | hdr->flags = cpu_to_le32(flags); |
637 | 506 | ||
638 | /* FIXME: the low order order 5 bits for the TAG if enable NCQ */ | ||
639 | if (task->ata_task.use_ncq && mvs_get_ncq_tag(task, &hdr_tag)) | 507 | if (task->ata_task.use_ncq && mvs_get_ncq_tag(task, &hdr_tag)) |
640 | task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3); | 508 | task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3); |
641 | else | 509 | else |
@@ -657,9 +525,6 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, | |||
657 | 525 | ||
658 | buf_tmp += MVS_ATA_CMD_SZ; | 526 | buf_tmp += MVS_ATA_CMD_SZ; |
659 | buf_tmp_dma += MVS_ATA_CMD_SZ; | 527 | buf_tmp_dma += MVS_ATA_CMD_SZ; |
660 | #if _MV_DUMP | ||
661 | slot->cmd_size = MVS_ATA_CMD_SZ; | ||
662 | #endif | ||
663 | 528 | ||
664 | /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */ | 529 | /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */ |
665 | /* used for STP. unused for SATA? */ | 530 | /* used for STP. unused for SATA? */ |
@@ -682,9 +547,6 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, | |||
682 | buf_tmp_dma += i; | 547 | buf_tmp_dma += i; |
683 | 548 | ||
684 | /* region 4: status buffer (larger the PRD, smaller this buf) ****** */ | 549 | /* region 4: status buffer (larger the PRD, smaller this buf) ****** */ |
685 | /* FIXME: probably unused, for SATA. kept here just in case | ||
686 | * we get a STP/SATA error information record | ||
687 | */ | ||
688 | slot->response = buf_tmp; | 550 | slot->response = buf_tmp; |
689 | hdr->status_buf = cpu_to_le64(buf_tmp_dma); | 551 | hdr->status_buf = cpu_to_le64(buf_tmp_dma); |
690 | if (mvi->flags & MVF_FLAG_SOC) | 552 | if (mvi->flags & MVF_FLAG_SOC) |
@@ -715,11 +577,11 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, | |||
715 | 577 | ||
716 | /* fill in PRD (scatter/gather) table, if any */ | 578 | /* fill in PRD (scatter/gather) table, if any */ |
717 | MVS_CHIP_DISP->make_prd(task->scatter, tei->n_elem, buf_prd); | 579 | MVS_CHIP_DISP->make_prd(task->scatter, tei->n_elem, buf_prd); |
718 | #ifndef DISABLE_HOTPLUG_DMA_FIX | 580 | |
719 | if (task->data_dir == DMA_FROM_DEVICE) | 581 | if (task->data_dir == DMA_FROM_DEVICE) |
720 | MVS_CHIP_DISP->dma_fix(mvi->bulk_buffer_dma, | 582 | MVS_CHIP_DISP->dma_fix(mvi, sas_port->phy_mask, |
721 | TRASH_BUCKET_SIZE, tei->n_elem, buf_prd); | 583 | TRASH_BUCKET_SIZE, tei->n_elem, buf_prd); |
722 | #endif | 584 | |
723 | return 0; | 585 | return 0; |
724 | } | 586 | } |
725 | 587 | ||
@@ -761,6 +623,9 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, | |||
761 | } | 623 | } |
762 | if (is_tmf) | 624 | if (is_tmf) |
763 | flags |= (MCH_SSP_FR_TASK << MCH_SSP_FR_TYPE_SHIFT); | 625 | flags |= (MCH_SSP_FR_TASK << MCH_SSP_FR_TYPE_SHIFT); |
626 | else | ||
627 | flags |= (MCH_SSP_FR_CMD << MCH_SSP_FR_TYPE_SHIFT); | ||
628 | |||
764 | hdr->flags = cpu_to_le32(flags | (tei->n_elem << MCH_PRD_LEN_SHIFT)); | 629 | hdr->flags = cpu_to_le32(flags | (tei->n_elem << MCH_PRD_LEN_SHIFT)); |
765 | hdr->tags = cpu_to_le32(tag); | 630 | hdr->tags = cpu_to_le32(tag); |
766 | hdr->data_len = cpu_to_le32(task->total_xfer_len); | 631 | hdr->data_len = cpu_to_le32(task->total_xfer_len); |
@@ -777,9 +642,6 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, | |||
777 | 642 | ||
778 | buf_tmp += MVS_SSP_CMD_SZ; | 643 | buf_tmp += MVS_SSP_CMD_SZ; |
779 | buf_tmp_dma += MVS_SSP_CMD_SZ; | 644 | buf_tmp_dma += MVS_SSP_CMD_SZ; |
780 | #if _MV_DUMP | ||
781 | slot->cmd_size = MVS_SSP_CMD_SZ; | ||
782 | #endif | ||
783 | 645 | ||
784 | /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */ | 646 | /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */ |
785 | buf_oaf = buf_tmp; | 647 | buf_oaf = buf_tmp; |
@@ -986,7 +848,6 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf | |||
986 | task->task_state_flags |= SAS_TASK_AT_INITIATOR; | 848 | task->task_state_flags |= SAS_TASK_AT_INITIATOR; |
987 | spin_unlock(&task->task_state_lock); | 849 | spin_unlock(&task->task_state_lock); |
988 | 850 | ||
989 | mvs_hba_memory_dump(mvi, tag, task->task_proto); | ||
990 | mvi_dev->running_req++; | 851 | mvi_dev->running_req++; |
991 | ++(*pass); | 852 | ++(*pass); |
992 | mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1); | 853 | mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1); |
@@ -1189,9 +1050,9 @@ static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task, | |||
1189 | mvs_slot_free(mvi, slot_idx); | 1050 | mvs_slot_free(mvi, slot_idx); |
1190 | } | 1051 | } |
1191 | 1052 | ||
1192 | static void mvs_update_wideport(struct mvs_info *mvi, int i) | 1053 | static void mvs_update_wideport(struct mvs_info *mvi, int phy_no) |
1193 | { | 1054 | { |
1194 | struct mvs_phy *phy = &mvi->phy[i]; | 1055 | struct mvs_phy *phy = &mvi->phy[phy_no]; |
1195 | struct mvs_port *port = phy->port; | 1056 | struct mvs_port *port = phy->port; |
1196 | int j, no; | 1057 | int j, no; |
1197 | 1058 | ||
@@ -1246,18 +1107,17 @@ static void *mvs_get_d2h_reg(struct mvs_info *mvi, int i, void *buf) | |||
1246 | return NULL; | 1107 | return NULL; |
1247 | 1108 | ||
1248 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG3); | 1109 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG3); |
1249 | s[3] = MVS_CHIP_DISP->read_port_cfg_data(mvi, i); | 1110 | s[3] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i)); |
1250 | 1111 | ||
1251 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG2); | 1112 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG2); |
1252 | s[2] = MVS_CHIP_DISP->read_port_cfg_data(mvi, i); | 1113 | s[2] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i)); |
1253 | 1114 | ||
1254 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG1); | 1115 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG1); |
1255 | s[1] = MVS_CHIP_DISP->read_port_cfg_data(mvi, i); | 1116 | s[1] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i)); |
1256 | 1117 | ||
1257 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG0); | 1118 | MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG0); |
1258 | s[0] = MVS_CHIP_DISP->read_port_cfg_data(mvi, i); | 1119 | s[0] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i)); |
1259 | 1120 | ||
1260 | /* Workaround: take some ATAPI devices for ATA */ | ||
1261 | if (((s[1] & 0x00FFFFFF) == 0x00EB1401) && (*(u8 *)&s[3] == 0x01)) | 1121 | if (((s[1] & 0x00FFFFFF) == 0x00EB1401) && (*(u8 *)&s[3] == 0x01)) |
1262 | s[1] = 0x00EB1401 | (*((u8 *)&s[1] + 3) & 0x10); | 1122 | s[1] = 0x00EB1401 | (*((u8 *)&s[1] + 3) & 0x10); |
1263 | 1123 | ||
@@ -1269,6 +1129,13 @@ static u32 mvs_is_sig_fis_received(u32 irq_status) | |||
1269 | return irq_status & PHYEV_SIG_FIS; | 1129 | return irq_status & PHYEV_SIG_FIS; |
1270 | } | 1130 | } |
1271 | 1131 | ||
1132 | static void mvs_sig_remove_timer(struct mvs_phy *phy) | ||
1133 | { | ||
1134 | if (phy->timer.function) | ||
1135 | del_timer(&phy->timer); | ||
1136 | phy->timer.function = NULL; | ||
1137 | } | ||
1138 | |||
1272 | void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) | 1139 | void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) |
1273 | { | 1140 | { |
1274 | struct mvs_phy *phy = &mvi->phy[i]; | 1141 | struct mvs_phy *phy = &mvi->phy[i]; |
@@ -1291,6 +1158,7 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) | |||
1291 | if (phy->phy_type & PORT_TYPE_SATA) { | 1158 | if (phy->phy_type & PORT_TYPE_SATA) { |
1292 | phy->identify.target_port_protocols = SAS_PROTOCOL_STP; | 1159 | phy->identify.target_port_protocols = SAS_PROTOCOL_STP; |
1293 | if (mvs_is_sig_fis_received(phy->irq_status)) { | 1160 | if (mvs_is_sig_fis_received(phy->irq_status)) { |
1161 | mvs_sig_remove_timer(phy); | ||
1294 | phy->phy_attached = 1; | 1162 | phy->phy_attached = 1; |
1295 | phy->att_dev_sas_addr = | 1163 | phy->att_dev_sas_addr = |
1296 | i + mvi->id * mvi->chip->n_phy; | 1164 | i + mvi->id * mvi->chip->n_phy; |
@@ -1308,7 +1176,6 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) | |||
1308 | tmp | PHYEV_SIG_FIS); | 1176 | tmp | PHYEV_SIG_FIS); |
1309 | phy->phy_attached = 0; | 1177 | phy->phy_attached = 0; |
1310 | phy->phy_type &= ~PORT_TYPE_SATA; | 1178 | phy->phy_type &= ~PORT_TYPE_SATA; |
1311 | MVS_CHIP_DISP->phy_reset(mvi, i, 0); | ||
1312 | goto out_done; | 1179 | goto out_done; |
1313 | } | 1180 | } |
1314 | } else if (phy->phy_type & PORT_TYPE_SAS | 1181 | } else if (phy->phy_type & PORT_TYPE_SAS |
@@ -1334,9 +1201,9 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) | |||
1334 | if (MVS_CHIP_DISP->phy_work_around) | 1201 | if (MVS_CHIP_DISP->phy_work_around) |
1335 | MVS_CHIP_DISP->phy_work_around(mvi, i); | 1202 | MVS_CHIP_DISP->phy_work_around(mvi, i); |
1336 | } | 1203 | } |
1337 | mv_dprintk("port %d attach dev info is %x\n", | 1204 | mv_dprintk("phy %d attach dev info is %x\n", |
1338 | i + mvi->id * mvi->chip->n_phy, phy->att_dev_info); | 1205 | i + mvi->id * mvi->chip->n_phy, phy->att_dev_info); |
1339 | mv_dprintk("port %d attach sas addr is %llx\n", | 1206 | mv_dprintk("phy %d attach sas addr is %llx\n", |
1340 | i + mvi->id * mvi->chip->n_phy, phy->att_dev_sas_addr); | 1207 | i + mvi->id * mvi->chip->n_phy, phy->att_dev_sas_addr); |
1341 | out_done: | 1208 | out_done: |
1342 | if (get_st) | 1209 | if (get_st) |
@@ -1361,10 +1228,10 @@ static void mvs_port_notify_formed(struct asd_sas_phy *sas_phy, int lock) | |||
1361 | } | 1228 | } |
1362 | hi = i/((struct mvs_prv_info *)sas_ha->lldd_ha)->n_phy; | 1229 | hi = i/((struct mvs_prv_info *)sas_ha->lldd_ha)->n_phy; |
1363 | mvi = ((struct mvs_prv_info *)sas_ha->lldd_ha)->mvi[hi]; | 1230 | mvi = ((struct mvs_prv_info *)sas_ha->lldd_ha)->mvi[hi]; |
1364 | if (sas_port->id >= mvi->chip->n_phy) | 1231 | if (i >= mvi->chip->n_phy) |
1365 | port = &mvi->port[sas_port->id - mvi->chip->n_phy]; | 1232 | port = &mvi->port[i - mvi->chip->n_phy]; |
1366 | else | 1233 | else |
1367 | port = &mvi->port[sas_port->id]; | 1234 | port = &mvi->port[i]; |
1368 | if (lock) | 1235 | if (lock) |
1369 | spin_lock_irqsave(&mvi->lock, flags); | 1236 | spin_lock_irqsave(&mvi->lock, flags); |
1370 | port->port_attached = 1; | 1237 | port->port_attached = 1; |
@@ -1393,7 +1260,7 @@ static void mvs_port_notify_deformed(struct asd_sas_phy *sas_phy, int lock) | |||
1393 | return; | 1260 | return; |
1394 | } | 1261 | } |
1395 | list_for_each_entry(dev, &port->dev_list, dev_list_node) | 1262 | list_for_each_entry(dev, &port->dev_list, dev_list_node) |
1396 | mvs_do_release_task(phy->mvi, phy_no, NULL); | 1263 | mvs_do_release_task(phy->mvi, phy_no, dev); |
1397 | 1264 | ||
1398 | } | 1265 | } |
1399 | 1266 | ||
@@ -1457,6 +1324,7 @@ int mvs_dev_found_notify(struct domain_device *dev, int lock) | |||
1457 | mvi_device->dev_status = MVS_DEV_NORMAL; | 1324 | mvi_device->dev_status = MVS_DEV_NORMAL; |
1458 | mvi_device->dev_type = dev->dev_type; | 1325 | mvi_device->dev_type = dev->dev_type; |
1459 | mvi_device->mvi_info = mvi; | 1326 | mvi_device->mvi_info = mvi; |
1327 | mvi_device->sas_device = dev; | ||
1460 | if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) { | 1328 | if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) { |
1461 | int phy_id; | 1329 | int phy_id; |
1462 | u8 phy_num = parent_dev->ex_dev.num_phys; | 1330 | u8 phy_num = parent_dev->ex_dev.num_phys; |
@@ -1508,6 +1376,7 @@ void mvs_dev_gone_notify(struct domain_device *dev) | |||
1508 | mv_dprintk("found dev has gone.\n"); | 1376 | mv_dprintk("found dev has gone.\n"); |
1509 | } | 1377 | } |
1510 | dev->lldd_dev = NULL; | 1378 | dev->lldd_dev = NULL; |
1379 | mvi_dev->sas_device = NULL; | ||
1511 | 1380 | ||
1512 | spin_unlock_irqrestore(&mvi->lock, flags); | 1381 | spin_unlock_irqrestore(&mvi->lock, flags); |
1513 | } | 1382 | } |
@@ -1555,7 +1424,6 @@ static void mvs_tmf_timedout(unsigned long data) | |||
1555 | complete(&task->completion); | 1424 | complete(&task->completion); |
1556 | } | 1425 | } |
1557 | 1426 | ||
1558 | /* XXX */ | ||
1559 | #define MVS_TASK_TIMEOUT 20 | 1427 | #define MVS_TASK_TIMEOUT 20 |
1560 | static int mvs_exec_internal_tmf_task(struct domain_device *dev, | 1428 | static int mvs_exec_internal_tmf_task(struct domain_device *dev, |
1561 | void *parameter, u32 para_len, struct mvs_tmf_task *tmf) | 1429 | void *parameter, u32 para_len, struct mvs_tmf_task *tmf) |
@@ -1588,7 +1456,7 @@ static int mvs_exec_internal_tmf_task(struct domain_device *dev, | |||
1588 | } | 1456 | } |
1589 | 1457 | ||
1590 | wait_for_completion(&task->completion); | 1458 | wait_for_completion(&task->completion); |
1591 | res = -TMF_RESP_FUNC_FAILED; | 1459 | res = TMF_RESP_FUNC_FAILED; |
1592 | /* Even TMF timed out, return direct. */ | 1460 | /* Even TMF timed out, return direct. */ |
1593 | if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { | 1461 | if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { |
1594 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { | 1462 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { |
@@ -1638,11 +1506,10 @@ static int mvs_debug_issue_ssp_tmf(struct domain_device *dev, | |||
1638 | u8 *lun, struct mvs_tmf_task *tmf) | 1506 | u8 *lun, struct mvs_tmf_task *tmf) |
1639 | { | 1507 | { |
1640 | struct sas_ssp_task ssp_task; | 1508 | struct sas_ssp_task ssp_task; |
1641 | DECLARE_COMPLETION_ONSTACK(completion); | ||
1642 | if (!(dev->tproto & SAS_PROTOCOL_SSP)) | 1509 | if (!(dev->tproto & SAS_PROTOCOL_SSP)) |
1643 | return TMF_RESP_FUNC_ESUPP; | 1510 | return TMF_RESP_FUNC_ESUPP; |
1644 | 1511 | ||
1645 | strncpy((u8 *)&ssp_task.LUN, lun, 8); | 1512 | memcpy(ssp_task.LUN, lun, 8); |
1646 | 1513 | ||
1647 | return mvs_exec_internal_tmf_task(dev, &ssp_task, | 1514 | return mvs_exec_internal_tmf_task(dev, &ssp_task, |
1648 | sizeof(ssp_task), tmf); | 1515 | sizeof(ssp_task), tmf); |
@@ -1666,7 +1533,7 @@ static int mvs_debug_I_T_nexus_reset(struct domain_device *dev) | |||
1666 | int mvs_lu_reset(struct domain_device *dev, u8 *lun) | 1533 | int mvs_lu_reset(struct domain_device *dev, u8 *lun) |
1667 | { | 1534 | { |
1668 | unsigned long flags; | 1535 | unsigned long flags; |
1669 | int i, phyno[WIDE_PORT_MAX_PHY], num , rc = TMF_RESP_FUNC_FAILED; | 1536 | int rc = TMF_RESP_FUNC_FAILED; |
1670 | struct mvs_tmf_task tmf_task; | 1537 | struct mvs_tmf_task tmf_task; |
1671 | struct mvs_device * mvi_dev = dev->lldd_dev; | 1538 | struct mvs_device * mvi_dev = dev->lldd_dev; |
1672 | struct mvs_info *mvi = mvi_dev->mvi_info; | 1539 | struct mvs_info *mvi = mvi_dev->mvi_info; |
@@ -1675,10 +1542,8 @@ int mvs_lu_reset(struct domain_device *dev, u8 *lun) | |||
1675 | mvi_dev->dev_status = MVS_DEV_EH; | 1542 | mvi_dev->dev_status = MVS_DEV_EH; |
1676 | rc = mvs_debug_issue_ssp_tmf(dev, lun, &tmf_task); | 1543 | rc = mvs_debug_issue_ssp_tmf(dev, lun, &tmf_task); |
1677 | if (rc == TMF_RESP_FUNC_COMPLETE) { | 1544 | if (rc == TMF_RESP_FUNC_COMPLETE) { |
1678 | num = mvs_find_dev_phyno(dev, phyno); | ||
1679 | spin_lock_irqsave(&mvi->lock, flags); | 1545 | spin_lock_irqsave(&mvi->lock, flags); |
1680 | for (i = 0; i < num; i++) | 1546 | mvs_release_task(mvi, dev); |
1681 | mvs_release_task(mvi, dev); | ||
1682 | spin_unlock_irqrestore(&mvi->lock, flags); | 1547 | spin_unlock_irqrestore(&mvi->lock, flags); |
1683 | } | 1548 | } |
1684 | /* If failed, fall-through I_T_Nexus reset */ | 1549 | /* If failed, fall-through I_T_Nexus reset */ |
@@ -1696,11 +1561,12 @@ int mvs_I_T_nexus_reset(struct domain_device *dev) | |||
1696 | 1561 | ||
1697 | if (mvi_dev->dev_status != MVS_DEV_EH) | 1562 | if (mvi_dev->dev_status != MVS_DEV_EH) |
1698 | return TMF_RESP_FUNC_COMPLETE; | 1563 | return TMF_RESP_FUNC_COMPLETE; |
1564 | else | ||
1565 | mvi_dev->dev_status = MVS_DEV_NORMAL; | ||
1699 | rc = mvs_debug_I_T_nexus_reset(dev); | 1566 | rc = mvs_debug_I_T_nexus_reset(dev); |
1700 | mv_printk("%s for device[%x]:rc= %d\n", | 1567 | mv_printk("%s for device[%x]:rc= %d\n", |
1701 | __func__, mvi_dev->device_id, rc); | 1568 | __func__, mvi_dev->device_id, rc); |
1702 | 1569 | ||
1703 | /* housekeeper */ | ||
1704 | spin_lock_irqsave(&mvi->lock, flags); | 1570 | spin_lock_irqsave(&mvi->lock, flags); |
1705 | mvs_release_task(mvi, dev); | 1571 | mvs_release_task(mvi, dev); |
1706 | spin_unlock_irqrestore(&mvi->lock, flags); | 1572 | spin_unlock_irqrestore(&mvi->lock, flags); |
@@ -1739,9 +1605,6 @@ int mvs_query_task(struct sas_task *task) | |||
1739 | case TMF_RESP_FUNC_FAILED: | 1605 | case TMF_RESP_FUNC_FAILED: |
1740 | case TMF_RESP_FUNC_COMPLETE: | 1606 | case TMF_RESP_FUNC_COMPLETE: |
1741 | break; | 1607 | break; |
1742 | default: | ||
1743 | rc = TMF_RESP_FUNC_COMPLETE; | ||
1744 | break; | ||
1745 | } | 1608 | } |
1746 | } | 1609 | } |
1747 | mv_printk("%s:rc= %d\n", __func__, rc); | 1610 | mv_printk("%s:rc= %d\n", __func__, rc); |
@@ -1761,8 +1624,8 @@ int mvs_abort_task(struct sas_task *task) | |||
1761 | u32 tag; | 1624 | u32 tag; |
1762 | 1625 | ||
1763 | if (!mvi_dev) { | 1626 | if (!mvi_dev) { |
1764 | mv_printk("%s:%d TMF_RESP_FUNC_FAILED\n", __func__, __LINE__); | 1627 | mv_printk("Device has removed\n"); |
1765 | rc = TMF_RESP_FUNC_FAILED; | 1628 | return TMF_RESP_FUNC_FAILED; |
1766 | } | 1629 | } |
1767 | 1630 | ||
1768 | mvi = mvi_dev->mvi_info; | 1631 | mvi = mvi_dev->mvi_info; |
@@ -1807,25 +1670,17 @@ int mvs_abort_task(struct sas_task *task) | |||
1807 | 1670 | ||
1808 | } else if (task->task_proto & SAS_PROTOCOL_SATA || | 1671 | } else if (task->task_proto & SAS_PROTOCOL_SATA || |
1809 | task->task_proto & SAS_PROTOCOL_STP) { | 1672 | task->task_proto & SAS_PROTOCOL_STP) { |
1810 | /* to do free register_set */ | ||
1811 | if (SATA_DEV == dev->dev_type) { | 1673 | if (SATA_DEV == dev->dev_type) { |
1812 | struct mvs_slot_info *slot = task->lldd_task; | 1674 | struct mvs_slot_info *slot = task->lldd_task; |
1813 | struct task_status_struct *tstat; | ||
1814 | u32 slot_idx = (u32)(slot - mvi->slot_info); | 1675 | u32 slot_idx = (u32)(slot - mvi->slot_info); |
1815 | tstat = &task->task_status; | 1676 | mv_dprintk("mvs_abort_task() mvi=%p task=%p " |
1816 | mv_dprintk(KERN_DEBUG "mv_abort_task() mvi=%p task=%p " | ||
1817 | "slot=%p slot_idx=x%x\n", | 1677 | "slot=%p slot_idx=x%x\n", |
1818 | mvi, task, slot, slot_idx); | 1678 | mvi, task, slot, slot_idx); |
1819 | tstat->stat = SAS_ABORTED_TASK; | 1679 | mvs_tmf_timedout((unsigned long)task); |
1820 | if (mvi_dev && mvi_dev->running_req) | ||
1821 | mvi_dev->running_req--; | ||
1822 | if (sas_protocol_ata(task->task_proto)) | ||
1823 | mvs_free_reg_set(mvi, mvi_dev); | ||
1824 | mvs_slot_task_free(mvi, task, slot, slot_idx); | 1680 | mvs_slot_task_free(mvi, task, slot, slot_idx); |
1825 | return -1; | 1681 | rc = TMF_RESP_FUNC_COMPLETE; |
1682 | goto out; | ||
1826 | } | 1683 | } |
1827 | } else { | ||
1828 | /* SMP */ | ||
1829 | 1684 | ||
1830 | } | 1685 | } |
1831 | out: | 1686 | out: |
@@ -1891,12 +1746,63 @@ static int mvs_sata_done(struct mvs_info *mvi, struct sas_task *task, | |||
1891 | return stat; | 1746 | return stat; |
1892 | } | 1747 | } |
1893 | 1748 | ||
1749 | void mvs_set_sense(u8 *buffer, int len, int d_sense, | ||
1750 | int key, int asc, int ascq) | ||
1751 | { | ||
1752 | memset(buffer, 0, len); | ||
1753 | |||
1754 | if (d_sense) { | ||
1755 | /* Descriptor format */ | ||
1756 | if (len < 4) { | ||
1757 | mv_printk("Length %d of sense buffer too small to " | ||
1758 | "fit sense %x:%x:%x", len, key, asc, ascq); | ||
1759 | } | ||
1760 | |||
1761 | buffer[0] = 0x72; /* Response Code */ | ||
1762 | if (len > 1) | ||
1763 | buffer[1] = key; /* Sense Key */ | ||
1764 | if (len > 2) | ||
1765 | buffer[2] = asc; /* ASC */ | ||
1766 | if (len > 3) | ||
1767 | buffer[3] = ascq; /* ASCQ */ | ||
1768 | } else { | ||
1769 | if (len < 14) { | ||
1770 | mv_printk("Length %d of sense buffer too small to " | ||
1771 | "fit sense %x:%x:%x", len, key, asc, ascq); | ||
1772 | } | ||
1773 | |||
1774 | buffer[0] = 0x70; /* Response Code */ | ||
1775 | if (len > 2) | ||
1776 | buffer[2] = key; /* Sense Key */ | ||
1777 | if (len > 7) | ||
1778 | buffer[7] = 0x0a; /* Additional Sense Length */ | ||
1779 | if (len > 12) | ||
1780 | buffer[12] = asc; /* ASC */ | ||
1781 | if (len > 13) | ||
1782 | buffer[13] = ascq; /* ASCQ */ | ||
1783 | } | ||
1784 | |||
1785 | return; | ||
1786 | } | ||
1787 | |||
1788 | void mvs_fill_ssp_resp_iu(struct ssp_response_iu *iu, | ||
1789 | u8 key, u8 asc, u8 asc_q) | ||
1790 | { | ||
1791 | iu->datapres = 2; | ||
1792 | iu->response_data_len = 0; | ||
1793 | iu->sense_data_len = 17; | ||
1794 | iu->status = 02; | ||
1795 | mvs_set_sense(iu->sense_data, 17, 0, | ||
1796 | key, asc, asc_q); | ||
1797 | } | ||
1798 | |||
1894 | static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task, | 1799 | static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task, |
1895 | u32 slot_idx) | 1800 | u32 slot_idx) |
1896 | { | 1801 | { |
1897 | struct mvs_slot_info *slot = &mvi->slot_info[slot_idx]; | 1802 | struct mvs_slot_info *slot = &mvi->slot_info[slot_idx]; |
1898 | int stat; | 1803 | int stat; |
1899 | u32 err_dw0 = le32_to_cpu(*(u32 *) (slot->response)); | 1804 | u32 err_dw0 = le32_to_cpu(*(u32 *)slot->response); |
1805 | u32 err_dw1 = le32_to_cpu(*((u32 *)slot->response + 1)); | ||
1900 | u32 tfs = 0; | 1806 | u32 tfs = 0; |
1901 | enum mvs_port_type type = PORT_TYPE_SAS; | 1807 | enum mvs_port_type type = PORT_TYPE_SAS; |
1902 | 1808 | ||
@@ -1908,8 +1814,19 @@ static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task, | |||
1908 | stat = SAM_STAT_CHECK_CONDITION; | 1814 | stat = SAM_STAT_CHECK_CONDITION; |
1909 | switch (task->task_proto) { | 1815 | switch (task->task_proto) { |
1910 | case SAS_PROTOCOL_SSP: | 1816 | case SAS_PROTOCOL_SSP: |
1817 | { | ||
1911 | stat = SAS_ABORTED_TASK; | 1818 | stat = SAS_ABORTED_TASK; |
1819 | if ((err_dw0 & NO_DEST) || err_dw1 & bit(31)) { | ||
1820 | struct ssp_response_iu *iu = slot->response + | ||
1821 | sizeof(struct mvs_err_info); | ||
1822 | mvs_fill_ssp_resp_iu(iu, NOT_READY, 0x04, 01); | ||
1823 | sas_ssp_task_response(mvi->dev, task, iu); | ||
1824 | stat = SAM_STAT_CHECK_CONDITION; | ||
1825 | } | ||
1826 | if (err_dw1 & bit(31)) | ||
1827 | mv_printk("reuse same slot, retry command.\n"); | ||
1912 | break; | 1828 | break; |
1829 | } | ||
1913 | case SAS_PROTOCOL_SMP: | 1830 | case SAS_PROTOCOL_SMP: |
1914 | stat = SAM_STAT_CHECK_CONDITION; | 1831 | stat = SAM_STAT_CHECK_CONDITION; |
1915 | break; | 1832 | break; |
@@ -1918,10 +1835,8 @@ static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task, | |||
1918 | case SAS_PROTOCOL_STP: | 1835 | case SAS_PROTOCOL_STP: |
1919 | case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: | 1836 | case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: |
1920 | { | 1837 | { |
1921 | if (err_dw0 == 0x80400002) | ||
1922 | mv_printk("find reserved error, why?\n"); | ||
1923 | |||
1924 | task->ata_task.use_ncq = 0; | 1838 | task->ata_task.use_ncq = 0; |
1839 | stat = SAS_PROTO_RESPONSE; | ||
1925 | mvs_sata_done(mvi, task, slot_idx, err_dw0); | 1840 | mvs_sata_done(mvi, task, slot_idx, err_dw0); |
1926 | } | 1841 | } |
1927 | break; | 1842 | break; |
@@ -1945,8 +1860,6 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) | |||
1945 | void *to; | 1860 | void *to; |
1946 | enum exec_status sts; | 1861 | enum exec_status sts; |
1947 | 1862 | ||
1948 | if (mvi->exp_req) | ||
1949 | mvi->exp_req--; | ||
1950 | if (unlikely(!task || !task->lldd_task || !task->dev)) | 1863 | if (unlikely(!task || !task->lldd_task || !task->dev)) |
1951 | return -1; | 1864 | return -1; |
1952 | 1865 | ||
@@ -1954,8 +1867,6 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) | |||
1954 | dev = task->dev; | 1867 | dev = task->dev; |
1955 | mvi_dev = dev->lldd_dev; | 1868 | mvi_dev = dev->lldd_dev; |
1956 | 1869 | ||
1957 | mvs_hba_cq_dump(mvi); | ||
1958 | |||
1959 | spin_lock(&task->task_state_lock); | 1870 | spin_lock(&task->task_state_lock); |
1960 | task->task_state_flags &= | 1871 | task->task_state_flags &= |
1961 | ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR); | 1872 | ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR); |
@@ -1978,6 +1889,7 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) | |||
1978 | return -1; | 1889 | return -1; |
1979 | } | 1890 | } |
1980 | 1891 | ||
1892 | /* when no device attaching, go ahead and complete by error handling*/ | ||
1981 | if (unlikely(!mvi_dev || flags)) { | 1893 | if (unlikely(!mvi_dev || flags)) { |
1982 | if (!mvi_dev) | 1894 | if (!mvi_dev) |
1983 | mv_dprintk("port has not device.\n"); | 1895 | mv_dprintk("port has not device.\n"); |
@@ -1987,6 +1899,9 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) | |||
1987 | 1899 | ||
1988 | /* error info record present */ | 1900 | /* error info record present */ |
1989 | if (unlikely((rx_desc & RXQ_ERR) && (*(u64 *) slot->response))) { | 1901 | if (unlikely((rx_desc & RXQ_ERR) && (*(u64 *) slot->response))) { |
1902 | mv_dprintk("port %d slot %d rx_desc %X has error info" | ||
1903 | "%016llX.\n", slot->port->sas_port.id, slot_idx, | ||
1904 | rx_desc, (u64)(*(u64 *)slot->response)); | ||
1990 | tstat->stat = mvs_slot_err(mvi, task, slot_idx); | 1905 | tstat->stat = mvs_slot_err(mvi, task, slot_idx); |
1991 | tstat->resp = SAS_TASK_COMPLETE; | 1906 | tstat->resp = SAS_TASK_COMPLETE; |
1992 | goto out; | 1907 | goto out; |
@@ -2048,8 +1963,7 @@ out: | |||
2048 | spin_unlock(&mvi->lock); | 1963 | spin_unlock(&mvi->lock); |
2049 | if (task->task_done) | 1964 | if (task->task_done) |
2050 | task->task_done(task); | 1965 | task->task_done(task); |
2051 | else | 1966 | |
2052 | mv_dprintk("why has not task_done.\n"); | ||
2053 | spin_lock(&mvi->lock); | 1967 | spin_lock(&mvi->lock); |
2054 | 1968 | ||
2055 | return sts; | 1969 | return sts; |
@@ -2092,7 +2006,6 @@ void mvs_release_task(struct mvs_info *mvi, | |||
2092 | struct domain_device *dev) | 2006 | struct domain_device *dev) |
2093 | { | 2007 | { |
2094 | int i, phyno[WIDE_PORT_MAX_PHY], num; | 2008 | int i, phyno[WIDE_PORT_MAX_PHY], num; |
2095 | /* housekeeper */ | ||
2096 | num = mvs_find_dev_phyno(dev, phyno); | 2009 | num = mvs_find_dev_phyno(dev, phyno); |
2097 | for (i = 0; i < num; i++) | 2010 | for (i = 0; i < num; i++) |
2098 | mvs_do_release_task(mvi, phyno[i], dev); | 2011 | mvs_do_release_task(mvi, phyno[i], dev); |
@@ -2111,13 +2024,13 @@ static void mvs_work_queue(struct work_struct *work) | |||
2111 | struct mvs_wq *mwq = container_of(dw, struct mvs_wq, work_q); | 2024 | struct mvs_wq *mwq = container_of(dw, struct mvs_wq, work_q); |
2112 | struct mvs_info *mvi = mwq->mvi; | 2025 | struct mvs_info *mvi = mwq->mvi; |
2113 | unsigned long flags; | 2026 | unsigned long flags; |
2027 | u32 phy_no = (unsigned long) mwq->data; | ||
2028 | struct sas_ha_struct *sas_ha = mvi->sas; | ||
2029 | struct mvs_phy *phy = &mvi->phy[phy_no]; | ||
2030 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | ||
2114 | 2031 | ||
2115 | spin_lock_irqsave(&mvi->lock, flags); | 2032 | spin_lock_irqsave(&mvi->lock, flags); |
2116 | if (mwq->handler & PHY_PLUG_EVENT) { | 2033 | if (mwq->handler & PHY_PLUG_EVENT) { |
2117 | u32 phy_no = (unsigned long) mwq->data; | ||
2118 | struct sas_ha_struct *sas_ha = mvi->sas; | ||
2119 | struct mvs_phy *phy = &mvi->phy[phy_no]; | ||
2120 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | ||
2121 | 2034 | ||
2122 | if (phy->phy_event & PHY_PLUG_OUT) { | 2035 | if (phy->phy_event & PHY_PLUG_OUT) { |
2123 | u32 tmp; | 2036 | u32 tmp; |
@@ -2139,6 +2052,11 @@ static void mvs_work_queue(struct work_struct *work) | |||
2139 | mv_dprintk("phy%d Attached Device\n", phy_no); | 2052 | mv_dprintk("phy%d Attached Device\n", phy_no); |
2140 | } | 2053 | } |
2141 | } | 2054 | } |
2055 | } else if (mwq->handler & EXP_BRCT_CHG) { | ||
2056 | phy->phy_event &= ~EXP_BRCT_CHG; | ||
2057 | sas_ha->notify_port_event(sas_phy, | ||
2058 | PORTE_BROADCAST_RCVD); | ||
2059 | mv_dprintk("phy%d Got Broadcast Change\n", phy_no); | ||
2142 | } | 2060 | } |
2143 | list_del(&mwq->entry); | 2061 | list_del(&mwq->entry); |
2144 | spin_unlock_irqrestore(&mvi->lock, flags); | 2062 | spin_unlock_irqrestore(&mvi->lock, flags); |
@@ -2174,29 +2092,21 @@ static void mvs_sig_time_out(unsigned long tphy) | |||
2174 | if (&mvi->phy[phy_no] == phy) { | 2092 | if (&mvi->phy[phy_no] == phy) { |
2175 | mv_dprintk("Get signature time out, reset phy %d\n", | 2093 | mv_dprintk("Get signature time out, reset phy %d\n", |
2176 | phy_no+mvi->id*mvi->chip->n_phy); | 2094 | phy_no+mvi->id*mvi->chip->n_phy); |
2177 | MVS_CHIP_DISP->phy_reset(mvi, phy_no, 1); | 2095 | MVS_CHIP_DISP->phy_reset(mvi, phy_no, MVS_HARD_RESET); |
2178 | } | 2096 | } |
2179 | } | 2097 | } |
2180 | } | 2098 | } |
2181 | 2099 | ||
2182 | static void mvs_sig_remove_timer(struct mvs_phy *phy) | ||
2183 | { | ||
2184 | if (phy->timer.function) | ||
2185 | del_timer(&phy->timer); | ||
2186 | phy->timer.function = NULL; | ||
2187 | } | ||
2188 | |||
2189 | void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | 2100 | void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) |
2190 | { | 2101 | { |
2191 | u32 tmp; | 2102 | u32 tmp; |
2192 | struct sas_ha_struct *sas_ha = mvi->sas; | ||
2193 | struct mvs_phy *phy = &mvi->phy[phy_no]; | 2103 | struct mvs_phy *phy = &mvi->phy[phy_no]; |
2194 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | ||
2195 | 2104 | ||
2196 | phy->irq_status = MVS_CHIP_DISP->read_port_irq_stat(mvi, phy_no); | 2105 | phy->irq_status = MVS_CHIP_DISP->read_port_irq_stat(mvi, phy_no); |
2197 | mv_dprintk("port %d ctrl sts=0x%X.\n", phy_no+mvi->id*mvi->chip->n_phy, | 2106 | MVS_CHIP_DISP->write_port_irq_stat(mvi, phy_no, phy->irq_status); |
2107 | mv_dprintk("phy %d ctrl sts=0x%08X.\n", phy_no+mvi->id*mvi->chip->n_phy, | ||
2198 | MVS_CHIP_DISP->read_phy_ctl(mvi, phy_no)); | 2108 | MVS_CHIP_DISP->read_phy_ctl(mvi, phy_no)); |
2199 | mv_dprintk("Port %d irq sts = 0x%X\n", phy_no+mvi->id*mvi->chip->n_phy, | 2109 | mv_dprintk("phy %d irq sts = 0x%08X\n", phy_no+mvi->id*mvi->chip->n_phy, |
2200 | phy->irq_status); | 2110 | phy->irq_status); |
2201 | 2111 | ||
2202 | /* | 2112 | /* |
@@ -2205,11 +2115,12 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | |||
2205 | */ | 2115 | */ |
2206 | 2116 | ||
2207 | if (phy->irq_status & PHYEV_DCDR_ERR) { | 2117 | if (phy->irq_status & PHYEV_DCDR_ERR) { |
2208 | mv_dprintk("port %d STP decoding error.\n", | 2118 | mv_dprintk("phy %d STP decoding error.\n", |
2209 | phy_no + mvi->id*mvi->chip->n_phy); | 2119 | phy_no + mvi->id*mvi->chip->n_phy); |
2210 | } | 2120 | } |
2211 | 2121 | ||
2212 | if (phy->irq_status & PHYEV_POOF) { | 2122 | if (phy->irq_status & PHYEV_POOF) { |
2123 | mdelay(500); | ||
2213 | if (!(phy->phy_event & PHY_PLUG_OUT)) { | 2124 | if (!(phy->phy_event & PHY_PLUG_OUT)) { |
2214 | int dev_sata = phy->phy_type & PORT_TYPE_SATA; | 2125 | int dev_sata = phy->phy_type & PORT_TYPE_SATA; |
2215 | int ready; | 2126 | int ready; |
@@ -2220,17 +2131,13 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | |||
2220 | (void *)(unsigned long)phy_no, | 2131 | (void *)(unsigned long)phy_no, |
2221 | PHY_PLUG_EVENT); | 2132 | PHY_PLUG_EVENT); |
2222 | ready = mvs_is_phy_ready(mvi, phy_no); | 2133 | ready = mvs_is_phy_ready(mvi, phy_no); |
2223 | if (!ready) | ||
2224 | mv_dprintk("phy%d Unplug Notice\n", | ||
2225 | phy_no + | ||
2226 | mvi->id * mvi->chip->n_phy); | ||
2227 | if (ready || dev_sata) { | 2134 | if (ready || dev_sata) { |
2228 | if (MVS_CHIP_DISP->stp_reset) | 2135 | if (MVS_CHIP_DISP->stp_reset) |
2229 | MVS_CHIP_DISP->stp_reset(mvi, | 2136 | MVS_CHIP_DISP->stp_reset(mvi, |
2230 | phy_no); | 2137 | phy_no); |
2231 | else | 2138 | else |
2232 | MVS_CHIP_DISP->phy_reset(mvi, | 2139 | MVS_CHIP_DISP->phy_reset(mvi, |
2233 | phy_no, 0); | 2140 | phy_no, MVS_SOFT_RESET); |
2234 | return; | 2141 | return; |
2235 | } | 2142 | } |
2236 | } | 2143 | } |
@@ -2243,13 +2150,12 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | |||
2243 | if (phy->timer.function == NULL) { | 2150 | if (phy->timer.function == NULL) { |
2244 | phy->timer.data = (unsigned long)phy; | 2151 | phy->timer.data = (unsigned long)phy; |
2245 | phy->timer.function = mvs_sig_time_out; | 2152 | phy->timer.function = mvs_sig_time_out; |
2246 | phy->timer.expires = jiffies + 10*HZ; | 2153 | phy->timer.expires = jiffies + 5*HZ; |
2247 | add_timer(&phy->timer); | 2154 | add_timer(&phy->timer); |
2248 | } | 2155 | } |
2249 | } | 2156 | } |
2250 | if (phy->irq_status & (PHYEV_SIG_FIS | PHYEV_ID_DONE)) { | 2157 | if (phy->irq_status & (PHYEV_SIG_FIS | PHYEV_ID_DONE)) { |
2251 | phy->phy_status = mvs_is_phy_ready(mvi, phy_no); | 2158 | phy->phy_status = mvs_is_phy_ready(mvi, phy_no); |
2252 | mvs_sig_remove_timer(phy); | ||
2253 | mv_dprintk("notify plug in on phy[%d]\n", phy_no); | 2159 | mv_dprintk("notify plug in on phy[%d]\n", phy_no); |
2254 | if (phy->phy_status) { | 2160 | if (phy->phy_status) { |
2255 | mdelay(10); | 2161 | mdelay(10); |
@@ -2263,14 +2169,14 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | |||
2263 | } | 2169 | } |
2264 | mvs_update_phyinfo(mvi, phy_no, 0); | 2170 | mvs_update_phyinfo(mvi, phy_no, 0); |
2265 | if (phy->phy_type & PORT_TYPE_SAS) { | 2171 | if (phy->phy_type & PORT_TYPE_SAS) { |
2266 | MVS_CHIP_DISP->phy_reset(mvi, phy_no, 2); | 2172 | MVS_CHIP_DISP->phy_reset(mvi, phy_no, MVS_PHY_TUNE); |
2267 | mdelay(10); | 2173 | mdelay(10); |
2268 | } | 2174 | } |
2269 | 2175 | ||
2270 | mvs_bytes_dmaed(mvi, phy_no); | 2176 | mvs_bytes_dmaed(mvi, phy_no); |
2271 | /* whether driver is going to handle hot plug */ | 2177 | /* whether driver is going to handle hot plug */ |
2272 | if (phy->phy_event & PHY_PLUG_OUT) { | 2178 | if (phy->phy_event & PHY_PLUG_OUT) { |
2273 | mvs_port_notify_formed(sas_phy, 0); | 2179 | mvs_port_notify_formed(&phy->sas_phy, 0); |
2274 | phy->phy_event &= ~PHY_PLUG_OUT; | 2180 | phy->phy_event &= ~PHY_PLUG_OUT; |
2275 | } | 2181 | } |
2276 | } else { | 2182 | } else { |
@@ -2278,13 +2184,11 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | |||
2278 | phy_no + mvi->id*mvi->chip->n_phy); | 2184 | phy_no + mvi->id*mvi->chip->n_phy); |
2279 | } | 2185 | } |
2280 | } else if (phy->irq_status & PHYEV_BROAD_CH) { | 2186 | } else if (phy->irq_status & PHYEV_BROAD_CH) { |
2281 | mv_dprintk("port %d broadcast change.\n", | 2187 | mv_dprintk("phy %d broadcast change.\n", |
2282 | phy_no + mvi->id*mvi->chip->n_phy); | 2188 | phy_no + mvi->id*mvi->chip->n_phy); |
2283 | /* exception for Samsung disk drive*/ | 2189 | mvs_handle_event(mvi, (void *)(unsigned long)phy_no, |
2284 | mdelay(1000); | 2190 | EXP_BRCT_CHG); |
2285 | sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); | ||
2286 | } | 2191 | } |
2287 | MVS_CHIP_DISP->write_port_irq_stat(mvi, phy_no, phy->irq_status); | ||
2288 | } | 2192 | } |
2289 | 2193 | ||
2290 | int mvs_int_rx(struct mvs_info *mvi, bool self_clear) | 2194 | 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 d6fd740e8bdd..44b474513223 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h | |||
@@ -47,12 +47,8 @@ | |||
47 | 47 | ||
48 | #define DRV_NAME "mvsas" | 48 | #define DRV_NAME "mvsas" |
49 | #define DRV_VERSION "0.8.2" | 49 | #define DRV_VERSION "0.8.2" |
50 | #define _MV_DUMP 0 | ||
51 | #define MVS_ID_NOT_MAPPED 0x7f | 50 | #define MVS_ID_NOT_MAPPED 0x7f |
52 | /* #define DISABLE_HOTPLUG_DMA_FIX */ | ||
53 | // #define MAX_EXP_RUNNING_REQ 2 | ||
54 | #define WIDE_PORT_MAX_PHY 4 | 51 | #define WIDE_PORT_MAX_PHY 4 |
55 | #define MV_DISABLE_NCQ 0 | ||
56 | #define mv_printk(fmt, arg ...) \ | 52 | #define mv_printk(fmt, arg ...) \ |
57 | printk(KERN_DEBUG"%s %d:" fmt, __FILE__, __LINE__, ## arg) | 53 | printk(KERN_DEBUG"%s %d:" fmt, __FILE__, __LINE__, ## arg) |
58 | #ifdef MV_DEBUG | 54 | #ifdef MV_DEBUG |
@@ -63,6 +59,7 @@ | |||
63 | #endif | 59 | #endif |
64 | #define MV_MAX_U32 0xffffffff | 60 | #define MV_MAX_U32 0xffffffff |
65 | 61 | ||
62 | extern int interrupt_coalescing; | ||
66 | extern struct mvs_tgt_initiator mvs_tgt; | 63 | extern struct mvs_tgt_initiator mvs_tgt; |
67 | extern struct mvs_info *tgt_mvi; | 64 | extern struct mvs_info *tgt_mvi; |
68 | extern const struct mvs_dispatch mvs_64xx_dispatch; | 65 | extern const struct mvs_dispatch mvs_64xx_dispatch; |
@@ -98,6 +95,11 @@ enum dev_status { | |||
98 | MVS_DEV_EH = 0x1, | 95 | MVS_DEV_EH = 0x1, |
99 | }; | 96 | }; |
100 | 97 | ||
98 | enum dev_reset { | ||
99 | MVS_SOFT_RESET = 0, | ||
100 | MVS_HARD_RESET = 1, | ||
101 | MVS_PHY_TUNE = 2, | ||
102 | }; | ||
101 | 103 | ||
102 | struct mvs_info; | 104 | struct mvs_info; |
103 | 105 | ||
@@ -129,7 +131,6 @@ struct mvs_dispatch { | |||
129 | u32 (*read_port_irq_mask)(struct mvs_info *mvi, u32 port); | 131 | u32 (*read_port_irq_mask)(struct mvs_info *mvi, u32 port); |
130 | void (*write_port_irq_mask)(struct mvs_info *mvi, u32 port, u32 val); | 132 | void (*write_port_irq_mask)(struct mvs_info *mvi, u32 port, u32 val); |
131 | 133 | ||
132 | void (*get_sas_addr)(void *buf, u32 buflen); | ||
133 | void (*command_active)(struct mvs_info *mvi, u32 slot_idx); | 134 | void (*command_active)(struct mvs_info *mvi, u32 slot_idx); |
134 | void (*clear_srs_irq)(struct mvs_info *mvi, u8 reg_set, u8 clear_all); | 135 | void (*clear_srs_irq)(struct mvs_info *mvi, u8 reg_set, u8 clear_all); |
135 | void (*issue_stop)(struct mvs_info *mvi, enum mvs_port_type type, | 136 | void (*issue_stop)(struct mvs_info *mvi, enum mvs_port_type type, |
@@ -166,9 +167,10 @@ struct mvs_dispatch { | |||
166 | ); | 167 | ); |
167 | int (*spi_issuecmd)(struct mvs_info *mvi, u32 cmd); | 168 | int (*spi_issuecmd)(struct mvs_info *mvi, u32 cmd); |
168 | int (*spi_waitdataready)(struct mvs_info *mvi, u32 timeout); | 169 | int (*spi_waitdataready)(struct mvs_info *mvi, u32 timeout); |
169 | #ifndef DISABLE_HOTPLUG_DMA_FIX | 170 | void (*dma_fix)(struct mvs_info *mvi, u32 phy_mask, |
170 | void (*dma_fix)(dma_addr_t buf_dma, int buf_len, int from, void *prd); | 171 | int buf_len, int from, void *prd); |
171 | #endif | 172 | void (*tune_interrupt)(struct mvs_info *mvi, u32 time); |
173 | void (*non_spec_ncq_error)(struct mvs_info *mvi); | ||
172 | 174 | ||
173 | }; | 175 | }; |
174 | 176 | ||
@@ -178,9 +180,11 @@ struct mvs_chip_info { | |||
178 | u32 fis_offs; | 180 | u32 fis_offs; |
179 | u32 fis_count; | 181 | u32 fis_count; |
180 | u32 srs_sz; | 182 | u32 srs_sz; |
183 | u32 sg_width; | ||
181 | u32 slot_width; | 184 | u32 slot_width; |
182 | const struct mvs_dispatch *dispatch; | 185 | const struct mvs_dispatch *dispatch; |
183 | }; | 186 | }; |
187 | #define MVS_MAX_SG (1U << mvi->chip->sg_width) | ||
184 | #define MVS_CHIP_SLOT_SZ (1U << mvi->chip->slot_width) | 188 | #define MVS_CHIP_SLOT_SZ (1U << mvi->chip->slot_width) |
185 | #define MVS_RX_FISL_SZ \ | 189 | #define MVS_RX_FISL_SZ \ |
186 | (mvi->chip->fis_offs + (mvi->chip->fis_count * 0x100)) | 190 | (mvi->chip->fis_offs + (mvi->chip->fis_count * 0x100)) |
@@ -248,6 +252,73 @@ struct mvs_device { | |||
248 | u16 reserved; | 252 | u16 reserved; |
249 | }; | 253 | }; |
250 | 254 | ||
255 | /* Generate PHY tunning parameters */ | ||
256 | struct phy_tuning { | ||
257 | /* 1 bit, transmitter emphasis enable */ | ||
258 | u8 trans_emp_en:1; | ||
259 | /* 4 bits, transmitter emphasis amplitude */ | ||
260 | u8 trans_emp_amp:4; | ||
261 | /* 3 bits, reserved space */ | ||
262 | u8 Reserved_2bit_1:3; | ||
263 | /* 5 bits, transmitter amplitude */ | ||
264 | u8 trans_amp:5; | ||
265 | /* 2 bits, transmitter amplitude adjust */ | ||
266 | u8 trans_amp_adj:2; | ||
267 | /* 1 bit, reserved space */ | ||
268 | u8 resv_2bit_2:1; | ||
269 | /* 2 bytes, reserved space */ | ||
270 | u8 reserved[2]; | ||
271 | }; | ||
272 | |||
273 | struct ffe_control { | ||
274 | /* 4 bits, FFE Capacitor Select (value range 0~F) */ | ||
275 | u8 ffe_cap_sel:4; | ||
276 | /* 3 bits, FFE Resistor Select (value range 0~7) */ | ||
277 | u8 ffe_rss_sel:3; | ||
278 | /* 1 bit reserve*/ | ||
279 | u8 reserved:1; | ||
280 | }; | ||
281 | |||
282 | /* | ||
283 | * HBA_Info_Page is saved in Flash/NVRAM, total 256 bytes. | ||
284 | * The data area is valid only Signature="MRVL". | ||
285 | * If any member fills with 0xFF, the member is invalid. | ||
286 | */ | ||
287 | struct hba_info_page { | ||
288 | /* Dword 0 */ | ||
289 | /* 4 bytes, structure signature,should be "MRVL" at first initial */ | ||
290 | u8 signature[4]; | ||
291 | |||
292 | /* Dword 1-13 */ | ||
293 | u32 reserved1[13]; | ||
294 | |||
295 | /* Dword 14-29 */ | ||
296 | /* 64 bytes, SAS address for each port */ | ||
297 | u64 sas_addr[8]; | ||
298 | |||
299 | /* Dword 30-31 */ | ||
300 | /* 8 bytes for vanir 8 port PHY FFE seeting | ||
301 | * BIT 0~3 : FFE Capacitor select(value range 0~F) | ||
302 | * BIT 4~6 : FFE Resistor select(value range 0~7) | ||
303 | * BIT 7: reserve. | ||
304 | */ | ||
305 | |||
306 | struct ffe_control ffe_ctl[8]; | ||
307 | /* Dword 32 -43 */ | ||
308 | u32 reserved2[12]; | ||
309 | |||
310 | /* Dword 44-45 */ | ||
311 | /* 8 bytes, 0: 1.5G, 1: 3.0G, should be 0x01 at first initial */ | ||
312 | u8 phy_rate[8]; | ||
313 | |||
314 | /* Dword 46-53 */ | ||
315 | /* 32 bytes, PHY tuning parameters for each PHY*/ | ||
316 | struct phy_tuning phy_tuning[8]; | ||
317 | |||
318 | /* Dword 54-63 */ | ||
319 | u32 reserved3[10]; | ||
320 | }; /* total 256 bytes */ | ||
321 | |||
251 | struct mvs_slot_info { | 322 | struct mvs_slot_info { |
252 | struct list_head entry; | 323 | struct list_head entry; |
253 | union { | 324 | union { |
@@ -263,9 +334,6 @@ struct mvs_slot_info { | |||
263 | */ | 334 | */ |
264 | void *buf; | 335 | void *buf; |
265 | dma_addr_t buf_dma; | 336 | dma_addr_t buf_dma; |
266 | #if _MV_DUMP | ||
267 | u32 cmd_size; | ||
268 | #endif | ||
269 | void *response; | 337 | void *response; |
270 | struct mvs_port *port; | 338 | struct mvs_port *port; |
271 | struct mvs_device *device; | 339 | struct mvs_device *device; |
@@ -319,12 +387,10 @@ struct mvs_info { | |||
319 | const struct mvs_chip_info *chip; | 387 | const struct mvs_chip_info *chip; |
320 | 388 | ||
321 | int tags_num; | 389 | int tags_num; |
322 | DECLARE_BITMAP(tags, MVS_SLOTS); | 390 | unsigned long *tags; |
323 | /* further per-slot information */ | 391 | /* further per-slot information */ |
324 | struct mvs_phy phy[MVS_MAX_PHYS]; | 392 | struct mvs_phy phy[MVS_MAX_PHYS]; |
325 | struct mvs_port port[MVS_MAX_PHYS]; | 393 | struct mvs_port port[MVS_MAX_PHYS]; |
326 | u32 irq; | ||
327 | u32 exp_req; | ||
328 | u32 id; | 394 | u32 id; |
329 | u64 sata_reg_set; | 395 | u64 sata_reg_set; |
330 | struct list_head *hba_list; | 396 | struct list_head *hba_list; |
@@ -336,12 +402,13 @@ struct mvs_info { | |||
336 | u32 flashsectSize; | 402 | u32 flashsectSize; |
337 | 403 | ||
338 | void *addon; | 404 | void *addon; |
405 | struct hba_info_page hba_info_param; | ||
339 | struct mvs_device devices[MVS_MAX_DEVICES]; | 406 | struct mvs_device devices[MVS_MAX_DEVICES]; |
340 | #ifndef DISABLE_HOTPLUG_DMA_FIX | ||
341 | void *bulk_buffer; | 407 | void *bulk_buffer; |
342 | dma_addr_t bulk_buffer_dma; | 408 | dma_addr_t bulk_buffer_dma; |
409 | void *bulk_buffer1; | ||
410 | dma_addr_t bulk_buffer_dma1; | ||
343 | #define TRASH_BUCKET_SIZE 0x20000 | 411 | #define TRASH_BUCKET_SIZE 0x20000 |
344 | #endif | ||
345 | void *dma_pool; | 412 | void *dma_pool; |
346 | struct mvs_slot_info slot_info[0]; | 413 | struct mvs_slot_info slot_info[0]; |
347 | }; | 414 | }; |
@@ -349,8 +416,10 @@ struct mvs_info { | |||
349 | struct mvs_prv_info{ | 416 | struct mvs_prv_info{ |
350 | u8 n_host; | 417 | u8 n_host; |
351 | u8 n_phy; | 418 | u8 n_phy; |
352 | u16 reserve; | 419 | u8 scan_finished; |
420 | u8 reserve; | ||
353 | struct mvs_info *mvi[2]; | 421 | struct mvs_info *mvi[2]; |
422 | struct tasklet_struct mv_tasklet; | ||
354 | }; | 423 | }; |
355 | 424 | ||
356 | struct mvs_wq { | 425 | struct mvs_wq { |
@@ -414,6 +483,6 @@ void mvs_do_release_task(struct mvs_info *mvi, int phy_no, | |||
414 | void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events); | 483 | void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events); |
415 | void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st); | 484 | void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st); |
416 | int mvs_int_rx(struct mvs_info *mvi, bool self_clear); | 485 | int mvs_int_rx(struct mvs_info *mvi, bool self_clear); |
417 | void mvs_hexdump(u32 size, u8 *data, u32 baseaddr); | 486 | struct mvs_device *mvs_find_dev_by_reg_set(struct mvs_info *mvi, u8 reg_set); |
418 | #endif | 487 | #endif |
419 | 488 | ||