diff options
author | Xiangliang Yu <yuxiangl@marvell.com> | 2011-05-24 10:33:11 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-07-26 02:34:13 -0400 |
commit | 8882f081329a82737b7471b97e59ce8c407f6655 (patch) | |
tree | d65c5653d4d033c65c6c837002dba4463ef90de1 /drivers/scsi/mvsas | |
parent | 83c7b61cf49c2659829050fec240601415c7f9d9 (diff) |
[SCSI] mvsas: fix 94xx hotplug issue
Fix 94xx A0/B0 revision hotplug issue.
Remove unused macro: DISABLE_HOTPLUG_DMA_FIX
Signed-off-by: Xiangliang Yu <yuxiangl@marvell.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/mvsas')
-rw-r--r-- | drivers/scsi/mvsas/mv_64xx.c | 9 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_94xx.c | 16 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_init.c | 15 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_sas.c | 28 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_sas.h | 9 |
5 files changed, 42 insertions, 35 deletions
diff --git a/drivers/scsi/mvsas/mv_64xx.c b/drivers/scsi/mvsas/mv_64xx.c index c88b8a7ed398..b02dd800af38 100644 --- a/drivers/scsi/mvsas/mv_64xx.c +++ b/drivers/scsi/mvsas/mv_64xx.c | |||
@@ -744,11 +744,13 @@ int mvs_64xx_spi_waitdataready(struct mvs_info *mvi, u32 timeout) | |||
744 | return -1; | 744 | return -1; |
745 | } | 745 | } |
746 | 746 | ||
747 | #ifndef DISABLE_HOTPLUG_DMA_FIX | 747 | 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) | 748 | int buf_len, int from, void *prd) |
749 | { | 749 | { |
750 | int i; | 750 | int i; |
751 | struct mvs_prd *buf_prd = prd; | 751 | struct mvs_prd *buf_prd = prd; |
752 | dma_addr_t buf_dma = mvi->bulk_buffer_dma; | ||
753 | |||
752 | buf_prd += from; | 754 | buf_prd += from; |
753 | for (i = 0; i < MAX_SG_ENTRY - from; i++) { | 755 | for (i = 0; i < MAX_SG_ENTRY - from; i++) { |
754 | buf_prd->addr = cpu_to_le64(buf_dma); | 756 | buf_prd->addr = cpu_to_le64(buf_dma); |
@@ -756,7 +758,6 @@ void mvs_64xx_fix_dma(dma_addr_t buf_dma, int buf_len, int from, void *prd) | |||
756 | ++buf_prd; | 758 | ++buf_prd; |
757 | } | 759 | } |
758 | } | 760 | } |
759 | #endif | ||
760 | 761 | ||
761 | static void mvs_64xx_tune_interrupt(struct mvs_info *mvi, u32 time) | 762 | static void mvs_64xx_tune_interrupt(struct mvs_info *mvi, u32 time) |
762 | { | 763 | { |
@@ -830,9 +831,7 @@ const struct mvs_dispatch mvs_64xx_dispatch = { | |||
830 | mvs_64xx_spi_buildcmd, | 831 | mvs_64xx_spi_buildcmd, |
831 | mvs_64xx_spi_issuecmd, | 832 | mvs_64xx_spi_issuecmd, |
832 | mvs_64xx_spi_waitdataready, | 833 | mvs_64xx_spi_waitdataready, |
833 | #ifndef DISABLE_HOTPLUG_DMA_FIX | ||
834 | mvs_64xx_fix_dma, | 834 | mvs_64xx_fix_dma, |
835 | #endif | ||
836 | mvs_64xx_tune_interrupt, | 835 | mvs_64xx_tune_interrupt, |
837 | NULL, | 836 | NULL, |
838 | }; | 837 | }; |
diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c index e589f31cb2b4..ef3c9012df46 100644 --- a/drivers/scsi/mvsas/mv_94xx.c +++ b/drivers/scsi/mvsas/mv_94xx.c | |||
@@ -871,19 +871,27 @@ int mvs_94xx_spi_waitdataready(struct mvs_info *mvi, u32 timeout) | |||
871 | return -1; | 871 | return -1; |
872 | } | 872 | } |
873 | 873 | ||
874 | #ifndef DISABLE_HOTPLUG_DMA_FIX | 874 | void mvs_94xx_fix_dma(struct mvs_info *mvi, u32 phy_mask, |
875 | void mvs_94xx_fix_dma(dma_addr_t buf_dma, int buf_len, int from, void *prd) | 875 | int buf_len, int from, void *prd) |
876 | { | 876 | { |
877 | int i; | 877 | int i; |
878 | struct mvs_prd *buf_prd = prd; | 878 | struct mvs_prd *buf_prd = prd; |
879 | dma_addr_t buf_dma; | ||
879 | buf_prd += from; | 880 | buf_prd += from; |
881 | |||
882 | if ((mvi->pdev->revision == VANIR_A0_REV) || | ||
883 | (mvi->pdev->revision == VANIR_B0_REV)) | ||
884 | buf_dma = (phy_mask <= 0x08) ? | ||
885 | mvi->bulk_buffer_dma : mvi->bulk_buffer_dma1; | ||
886 | else | ||
887 | return; | ||
888 | |||
880 | for (i = 0; i < MAX_SG_ENTRY - from; i++) { | 889 | for (i = 0; i < MAX_SG_ENTRY - from; i++) { |
881 | buf_prd->addr = cpu_to_le64(buf_dma); | 890 | buf_prd->addr = cpu_to_le64(buf_dma); |
882 | buf_prd->im_len.len = cpu_to_le32(buf_len); | 891 | buf_prd->im_len.len = cpu_to_le32(buf_len); |
883 | ++buf_prd; | 892 | ++buf_prd; |
884 | } | 893 | } |
885 | } | 894 | } |
886 | #endif | ||
887 | 895 | ||
888 | /* | 896 | /* |
889 | * FIXME JEJB: temporary nop clear_srs_irq to make 94xx still work | 897 | * FIXME JEJB: temporary nop clear_srs_irq to make 94xx still work |
@@ -967,9 +975,7 @@ const struct mvs_dispatch mvs_94xx_dispatch = { | |||
967 | mvs_94xx_spi_buildcmd, | 975 | mvs_94xx_spi_buildcmd, |
968 | mvs_94xx_spi_issuecmd, | 976 | mvs_94xx_spi_issuecmd, |
969 | mvs_94xx_spi_waitdataready, | 977 | mvs_94xx_spi_waitdataready, |
970 | #ifndef DISABLE_HOTPLUG_DMA_FIX | ||
971 | mvs_94xx_fix_dma, | 978 | mvs_94xx_fix_dma, |
972 | #endif | ||
973 | mvs_94xx_tune_interrupt, | 979 | mvs_94xx_tune_interrupt, |
974 | mvs_94xx_non_spec_ncq_error, | 980 | mvs_94xx_non_spec_ncq_error, |
975 | }; | 981 | }; |
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index 531093ddc418..b111ae2ec489 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c | |||
@@ -153,11 +153,13 @@ static void mvs_free(struct mvs_info *mvi) | |||
153 | dma_free_coherent(mvi->dev, | 153 | dma_free_coherent(mvi->dev, |
154 | sizeof(*mvi->slot) * slot_nr, | 154 | sizeof(*mvi->slot) * slot_nr, |
155 | mvi->slot, mvi->slot_dma); | 155 | mvi->slot, mvi->slot_dma); |
156 | #ifndef DISABLE_HOTPLUG_DMA_FIX | 156 | |
157 | if (mvi->bulk_buffer) | 157 | if (mvi->bulk_buffer) |
158 | dma_free_coherent(mvi->dev, TRASH_BUCKET_SIZE, | 158 | dma_free_coherent(mvi->dev, TRASH_BUCKET_SIZE, |
159 | mvi->bulk_buffer, mvi->bulk_buffer_dma); | 159 | mvi->bulk_buffer, mvi->bulk_buffer_dma); |
160 | #endif | 160 | if (mvi->bulk_buffer1) |
161 | dma_free_coherent(mvi->dev, TRASH_BUCKET_SIZE, | ||
162 | mvi->bulk_buffer1, mvi->bulk_buffer_dma1); | ||
161 | 163 | ||
162 | MVS_CHIP_DISP->chip_iounmap(mvi); | 164 | MVS_CHIP_DISP->chip_iounmap(mvi); |
163 | if (mvi->shost) | 165 | if (mvi->shost) |
@@ -278,13 +280,18 @@ static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost) | |||
278 | goto err_out; | 280 | goto err_out; |
279 | memset(mvi->slot, 0, sizeof(*mvi->slot) * slot_nr); | 281 | memset(mvi->slot, 0, sizeof(*mvi->slot) * slot_nr); |
280 | 282 | ||
281 | #ifndef DISABLE_HOTPLUG_DMA_FIX | ||
282 | mvi->bulk_buffer = dma_alloc_coherent(mvi->dev, | 283 | mvi->bulk_buffer = dma_alloc_coherent(mvi->dev, |
283 | TRASH_BUCKET_SIZE, | 284 | TRASH_BUCKET_SIZE, |
284 | &mvi->bulk_buffer_dma, GFP_KERNEL); | 285 | &mvi->bulk_buffer_dma, GFP_KERNEL); |
285 | if (!mvi->bulk_buffer) | 286 | if (!mvi->bulk_buffer) |
286 | goto err_out; | 287 | goto err_out; |
287 | #endif | 288 | |
289 | mvi->bulk_buffer1 = dma_alloc_coherent(mvi->dev, | ||
290 | TRASH_BUCKET_SIZE, | ||
291 | &mvi->bulk_buffer_dma1, GFP_KERNEL); | ||
292 | if (!mvi->bulk_buffer1) | ||
293 | goto err_out; | ||
294 | |||
288 | sprintf(pool_name, "%s%d", "mvs_dma_pool", mvi->id); | 295 | sprintf(pool_name, "%s%d", "mvs_dma_pool", mvi->id); |
289 | mvi->dma_pool = pci_pool_create(pool_name, mvi->pdev, MVS_SLOT_BUF_SZ, 16, 0); | 296 | mvi->dma_pool = pci_pool_create(pool_name, mvi->pdev, MVS_SLOT_BUF_SZ, 16, 0); |
290 | if (!mvi->dma_pool) { | 297 | if (!mvi->dma_pool) { |
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index aaa475a3eda6..4585dc018ad1 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c | |||
@@ -630,14 +630,11 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, | |||
630 | (mvi_dev->taskfileset << TXQ_SRS_SHIFT); | 630 | (mvi_dev->taskfileset << TXQ_SRS_SHIFT); |
631 | mvi->tx[mvi->tx_prod] = cpu_to_le32(del_q); | 631 | mvi->tx[mvi->tx_prod] = cpu_to_le32(del_q); |
632 | 632 | ||
633 | #ifndef DISABLE_HOTPLUG_DMA_FIX | ||
634 | if (task->data_dir == DMA_FROM_DEVICE) | 633 | if (task->data_dir == DMA_FROM_DEVICE) |
635 | flags = (MVS_CHIP_DISP->prd_count() << MCH_PRD_LEN_SHIFT); | 634 | flags = (MVS_CHIP_DISP->prd_count() << MCH_PRD_LEN_SHIFT); |
636 | else | 635 | else |
637 | flags = (tei->n_elem << MCH_PRD_LEN_SHIFT); | 636 | flags = (tei->n_elem << MCH_PRD_LEN_SHIFT); |
638 | #else | 637 | |
639 | flags = (tei->n_elem << MCH_PRD_LEN_SHIFT); | ||
640 | #endif | ||
641 | if (task->ata_task.use_ncq) | 638 | if (task->ata_task.use_ncq) |
642 | flags |= MCH_FPDMA; | 639 | flags |= MCH_FPDMA; |
643 | if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) { | 640 | if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) { |
@@ -729,11 +726,11 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, | |||
729 | 726 | ||
730 | /* fill in PRD (scatter/gather) table, if any */ | 727 | /* fill in PRD (scatter/gather) table, if any */ |
731 | MVS_CHIP_DISP->make_prd(task->scatter, tei->n_elem, buf_prd); | 728 | MVS_CHIP_DISP->make_prd(task->scatter, tei->n_elem, buf_prd); |
732 | #ifndef DISABLE_HOTPLUG_DMA_FIX | 729 | |
733 | if (task->data_dir == DMA_FROM_DEVICE) | 730 | if (task->data_dir == DMA_FROM_DEVICE) |
734 | MVS_CHIP_DISP->dma_fix(mvi->bulk_buffer_dma, | 731 | MVS_CHIP_DISP->dma_fix(mvi, sas_port->phy_mask, |
735 | TRASH_BUCKET_SIZE, tei->n_elem, buf_prd); | 732 | TRASH_BUCKET_SIZE, tei->n_elem, buf_prd); |
736 | #endif | 733 | |
737 | return 0; | 734 | return 0; |
738 | } | 735 | } |
739 | 736 | ||
@@ -1283,6 +1280,13 @@ static u32 mvs_is_sig_fis_received(u32 irq_status) | |||
1283 | return irq_status & PHYEV_SIG_FIS; | 1280 | return irq_status & PHYEV_SIG_FIS; |
1284 | } | 1281 | } |
1285 | 1282 | ||
1283 | static void mvs_sig_remove_timer(struct mvs_phy *phy) | ||
1284 | { | ||
1285 | if (phy->timer.function) | ||
1286 | del_timer(&phy->timer); | ||
1287 | phy->timer.function = NULL; | ||
1288 | } | ||
1289 | |||
1286 | void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) | 1290 | void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) |
1287 | { | 1291 | { |
1288 | struct mvs_phy *phy = &mvi->phy[i]; | 1292 | struct mvs_phy *phy = &mvi->phy[i]; |
@@ -1305,6 +1309,7 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) | |||
1305 | if (phy->phy_type & PORT_TYPE_SATA) { | 1309 | if (phy->phy_type & PORT_TYPE_SATA) { |
1306 | phy->identify.target_port_protocols = SAS_PROTOCOL_STP; | 1310 | phy->identify.target_port_protocols = SAS_PROTOCOL_STP; |
1307 | if (mvs_is_sig_fis_received(phy->irq_status)) { | 1311 | if (mvs_is_sig_fis_received(phy->irq_status)) { |
1312 | mvs_sig_remove_timer(phy); | ||
1308 | phy->phy_attached = 1; | 1313 | phy->phy_attached = 1; |
1309 | phy->att_dev_sas_addr = | 1314 | phy->att_dev_sas_addr = |
1310 | i + mvi->id * mvi->chip->n_phy; | 1315 | i + mvi->id * mvi->chip->n_phy; |
@@ -1322,7 +1327,6 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) | |||
1322 | tmp | PHYEV_SIG_FIS); | 1327 | tmp | PHYEV_SIG_FIS); |
1323 | phy->phy_attached = 0; | 1328 | phy->phy_attached = 0; |
1324 | phy->phy_type &= ~PORT_TYPE_SATA; | 1329 | phy->phy_type &= ~PORT_TYPE_SATA; |
1325 | MVS_CHIP_DISP->phy_reset(mvi, i, 0); | ||
1326 | goto out_done; | 1330 | goto out_done; |
1327 | } | 1331 | } |
1328 | } else if (phy->phy_type & PORT_TYPE_SAS | 1332 | } else if (phy->phy_type & PORT_TYPE_SAS |
@@ -2193,13 +2197,6 @@ static void mvs_sig_time_out(unsigned long tphy) | |||
2193 | } | 2197 | } |
2194 | } | 2198 | } |
2195 | 2199 | ||
2196 | static void mvs_sig_remove_timer(struct mvs_phy *phy) | ||
2197 | { | ||
2198 | if (phy->timer.function) | ||
2199 | del_timer(&phy->timer); | ||
2200 | phy->timer.function = NULL; | ||
2201 | } | ||
2202 | |||
2203 | void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | 2200 | void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) |
2204 | { | 2201 | { |
2205 | u32 tmp; | 2202 | u32 tmp; |
@@ -2263,7 +2260,6 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) | |||
2263 | } | 2260 | } |
2264 | if (phy->irq_status & (PHYEV_SIG_FIS | PHYEV_ID_DONE)) { | 2261 | if (phy->irq_status & (PHYEV_SIG_FIS | PHYEV_ID_DONE)) { |
2265 | phy->phy_status = mvs_is_phy_ready(mvi, phy_no); | 2262 | phy->phy_status = mvs_is_phy_ready(mvi, phy_no); |
2266 | mvs_sig_remove_timer(phy); | ||
2267 | mv_dprintk("notify plug in on phy[%d]\n", phy_no); | 2263 | mv_dprintk("notify plug in on phy[%d]\n", phy_no); |
2268 | if (phy->phy_status) { | 2264 | if (phy->phy_status) { |
2269 | mdelay(10); | 2265 | mdelay(10); |
diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h index 089ef1ef3865..5cfa4cc18f2d 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h | |||
@@ -168,9 +168,8 @@ struct mvs_dispatch { | |||
168 | ); | 168 | ); |
169 | int (*spi_issuecmd)(struct mvs_info *mvi, u32 cmd); | 169 | int (*spi_issuecmd)(struct mvs_info *mvi, u32 cmd); |
170 | int (*spi_waitdataready)(struct mvs_info *mvi, u32 timeout); | 170 | int (*spi_waitdataready)(struct mvs_info *mvi, u32 timeout); |
171 | #ifndef DISABLE_HOTPLUG_DMA_FIX | 171 | void (*dma_fix)(struct mvs_info *mvi, u32 phy_mask, |
172 | void (*dma_fix)(dma_addr_t buf_dma, int buf_len, int from, void *prd); | 172 | int buf_len, int from, void *prd); |
173 | #endif | ||
174 | void (*tune_interrupt)(struct mvs_info *mvi, u32 time); | 173 | void (*tune_interrupt)(struct mvs_info *mvi, u32 time); |
175 | void (*non_spec_ncq_error)(struct mvs_info *mvi); | 174 | void (*non_spec_ncq_error)(struct mvs_info *mvi); |
176 | 175 | ||
@@ -409,11 +408,11 @@ struct mvs_info { | |||
409 | void *addon; | 408 | void *addon; |
410 | struct hba_info_page hba_info_param; | 409 | struct hba_info_page hba_info_param; |
411 | struct mvs_device devices[MVS_MAX_DEVICES]; | 410 | struct mvs_device devices[MVS_MAX_DEVICES]; |
412 | #ifndef DISABLE_HOTPLUG_DMA_FIX | ||
413 | void *bulk_buffer; | 411 | void *bulk_buffer; |
414 | dma_addr_t bulk_buffer_dma; | 412 | dma_addr_t bulk_buffer_dma; |
413 | void *bulk_buffer1; | ||
414 | dma_addr_t bulk_buffer_dma1; | ||
415 | #define TRASH_BUCKET_SIZE 0x20000 | 415 | #define TRASH_BUCKET_SIZE 0x20000 |
416 | #endif | ||
417 | void *dma_pool; | 416 | void *dma_pool; |
418 | struct mvs_slot_info slot_info[0]; | 417 | struct mvs_slot_info slot_info[0]; |
419 | }; | 418 | }; |