aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2007-10-11 23:53:58 +0200
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-10-11 23:53:58 +0200
commitb4e44369a380c1836d0983c2a5011099b7b26eb1 (patch)
treec7be9a68f98d908c7822d65dcec4b3c21d9d7955
parent7cfa7168f7a7730abf1aa2af4a7596d24edd4c21 (diff)
hpt366: MWDMA filter for SATA cards (take 2)
The Marvell bridge chips used on HighPoint SATA cards do not seem to support the MWDMA modes (at least that could be seen in their so-called drivers :-), so the driver needs to account for this -- to achieve this: - add mdma_filter() method from the original patch by Bartlomiej Zolnierkiewicz with his consent; - install the method for all chips to only return empty mask if a SATA drive is detected on HPT372{AN]/374 chips... Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r--drivers/ide/ide-dma.c9
-rw-r--r--drivers/ide/ide.c1
-rw-r--r--drivers/ide/pci/hpt366.c23
-rw-r--r--include/linux/ide.h1
4 files changed, 30 insertions, 4 deletions
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index ff644a5e12c..097d6e9865b 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -673,8 +673,13 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base)
mask &= 0x07;
break;
case XFER_MW_DMA_0:
- if (id->field_valid & 2)
- mask = id->dma_mword & hwif->mwdma_mask;
+ if ((id->field_valid & 2) == 0)
+ break;
+ if (hwif->mdma_filter)
+ mask = hwif->mdma_filter(drive);
+ else
+ mask = hwif->mwdma_mask;
+ mask &= id->dma_mword;
break;
case XFER_SW_DMA_0:
if (id->field_valid & 2) {
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 5e88a060df0..de54306789a 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -398,6 +398,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
hwif->tuneproc = tmp_hwif->tuneproc;
hwif->speedproc = tmp_hwif->speedproc;
+ hwif->mdma_filter = tmp_hwif->mdma_filter;
hwif->udma_filter = tmp_hwif->udma_filter;
hwif->selectproc = tmp_hwif->selectproc;
hwif->reset_poll = tmp_hwif->reset_poll;
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 39f1c89f7c8..3d8d6b2ee41 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/hpt366.c Version 1.12 Aug 19, 2007
+ * linux/drivers/ide/pci/hpt366.c Version 1.13 Sep 29, 2007
*
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
@@ -114,7 +114,7 @@
* unify HPT36x/37x timing setup code and the speedproc handlers by joining
* the register setting lists into the table indexed by the clock selected
* - set the correct hwif->ultra_mask for each individual chip
- * - add UltraDMA mode filtering for the HPT37[24] based SATA cards
+ * - add Ultra and MW DMA mode filtering for the HPT37[24] based SATA cards
* Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com>
*/
@@ -562,6 +562,24 @@ static u8 hpt3xx_udma_filter(ide_drive_t *drive)
return check_in_drive_list(drive, bad_ata33) ? 0x00 : mask;
}
+static u8 hpt3xx_mdma_filter(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ struct hpt_info *info = pci_get_drvdata(hwif->pci_dev);
+
+ switch (info->chip_type) {
+ case HPT372 :
+ case HPT372A:
+ case HPT372N:
+ case HPT374 :
+ if (ide_dev_is_sata(drive->id))
+ return 0x00;
+ /* Fall thru */
+ default:
+ return 0x07;
+ }
+}
+
static u32 get_speed_setting(u8 speed, struct hpt_info *info)
{
int i;
@@ -1257,6 +1275,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
hwif->busproc = &hpt3xx_busproc;
hwif->udma_filter = &hpt3xx_udma_filter;
+ hwif->mdma_filter = &hpt3xx_mdma_filter;
/*
* HPT3xxN chips have some complications:
diff --git a/include/linux/ide.h b/include/linux/ide.h
index b9f66c10caa..0665428356d 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -723,6 +723,7 @@ typedef struct hwif_s {
/* driver soft-power interface */
int (*busproc)(ide_drive_t *, int);
#endif
+ u8 (*mdma_filter)(ide_drive_t *);
u8 (*udma_filter)(ide_drive_t *);
void (*ata_input_data)(ide_drive_t *, void *, u32);