diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2007-02-07 12:18:34 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-02-07 12:18:34 -0500 |
commit | 24e6458d9c0c445141488b70e1a01fa31ed86c8d (patch) | |
tree | 7ea8cf6d1cb1623d8e4e090d58d59a9d42c9b51e /drivers/ide/pci | |
parent | 30dfd12f5384d30c0d0de05eb34d0e26352a20ff (diff) |
slc90e66: carry over fixes from piix driver
Synchronize with version 0.46 of the Intel PIIX/ICH driver:
- carry over Alan's and my own fixes in the tuneproc() method and my cleanups
both there and in the ratemask() method;
- SLC90E66 only supports MW DMA modes 1/2 and SW DMA mode 2 (just like Intel
chips), so don't claim support for other MW/SW DMA modes;
- don't check dor non-NULL drive->id in the ide_dma_check() method -- this is
assumed to be true in all other drivers;
- do some coding/formatting cleanups while at it...
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/pci')
-rw-r--r-- | drivers/ide/pci/slc90e66.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 90e79c0844d2..2663ddbd9b67 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/slc90e66.c Version 0.12 May 12, 2006 | 2 | * linux/drivers/ide/pci/slc90e66.c Version 0.13 December 30, 2006 |
3 | * | 3 | * |
4 | * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> | 4 | * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> |
5 | * Copyright (C) 2006 MontaVista Software, Inc. <source@mvista.com> | 5 | * Copyright (C) 2006 MontaVista Software, Inc. <source@mvista.com> |
@@ -26,7 +26,7 @@ static u8 slc90e66_ratemask (ide_drive_t *drive) | |||
26 | u8 mode = 2; | 26 | u8 mode = 2; |
27 | 27 | ||
28 | if (!eighty_ninty_three(drive)) | 28 | if (!eighty_ninty_three(drive)) |
29 | mode = min(mode, (u8)1); | 29 | mode = min_t(u8, mode, 1); |
30 | return mode; | 30 | return mode; |
31 | } | 31 | } |
32 | 32 | ||
@@ -65,36 +65,47 @@ static void slc90e66_tune_drive (ide_drive_t *drive, u8 pio) | |||
65 | { | 65 | { |
66 | ide_hwif_t *hwif = HWIF(drive); | 66 | ide_hwif_t *hwif = HWIF(drive); |
67 | struct pci_dev *dev = hwif->pci_dev; | 67 | struct pci_dev *dev = hwif->pci_dev; |
68 | int is_slave = (&hwif->drives[1] == drive); | 68 | int is_slave = drive->dn & 1; |
69 | int master_port = hwif->channel ? 0x42 : 0x40; | 69 | int master_port = hwif->channel ? 0x42 : 0x40; |
70 | int slave_port = 0x44; | 70 | int slave_port = 0x44; |
71 | unsigned long flags; | 71 | unsigned long flags; |
72 | u16 master_data; | 72 | u16 master_data; |
73 | u8 slave_data; | 73 | u8 slave_data; |
74 | /* ISP RTC */ | 74 | int control = 0; |
75 | /* ISP RTC */ | ||
75 | static const u8 timings[][2]= { | 76 | static const u8 timings[][2]= { |
76 | { 0, 0 }, | 77 | { 0, 0 }, |
77 | { 0, 0 }, | 78 | { 0, 0 }, |
78 | { 1, 0 }, | 79 | { 1, 0 }, |
79 | { 2, 1 }, | 80 | { 2, 1 }, |
80 | { 2, 3 }, }; | 81 | { 2, 3 }, }; |
81 | 82 | ||
82 | pio = ide_get_best_pio_mode(drive, pio, 5, NULL); | 83 | pio = ide_get_best_pio_mode(drive, pio, 4, NULL); |
83 | spin_lock_irqsave(&ide_lock, flags); | 84 | spin_lock_irqsave(&ide_lock, flags); |
84 | pci_read_config_word(dev, master_port, &master_data); | 85 | pci_read_config_word(dev, master_port, &master_data); |
86 | |||
87 | if (pio > 1) | ||
88 | control |= 1; /* Programmable timing on */ | ||
89 | if (drive->media == ide_disk) | ||
90 | control |= 4; /* Prefetch, post write */ | ||
91 | if (pio > 2) | ||
92 | control |= 2; /* IORDY */ | ||
85 | if (is_slave) { | 93 | if (is_slave) { |
86 | master_data = master_data | 0x4000; | 94 | master_data |= 0x4000; |
87 | if (pio > 1) | 95 | master_data &= ~0x0070; |
96 | if (pio > 1) { | ||
88 | /* enable PPE, IE and TIME */ | 97 | /* enable PPE, IE and TIME */ |
89 | master_data = master_data | 0x0070; | 98 | master_data = master_data | (control << 4); |
99 | } | ||
90 | pci_read_config_byte(dev, slave_port, &slave_data); | 100 | pci_read_config_byte(dev, slave_port, &slave_data); |
91 | slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0); | 101 | slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0); |
92 | slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0)); | 102 | slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0)); |
93 | } else { | 103 | } else { |
94 | master_data = master_data & 0xccf8; | 104 | master_data &= ~0x3307; |
95 | if (pio > 1) | 105 | if (pio > 1) { |
96 | /* enable PPE, IE and TIME */ | 106 | /* enable PPE, IE and TIME */ |
97 | master_data = master_data | 0x0007; | 107 | master_data = master_data | control; |
108 | } | ||
98 | master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8); | 109 | master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8); |
99 | } | 110 | } |
100 | pci_write_config_word(dev, master_port, master_data); | 111 | pci_write_config_word(dev, master_port, master_data); |
@@ -173,7 +184,7 @@ static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) | |||
173 | 184 | ||
174 | drive->init_speed = 0; | 185 | drive->init_speed = 0; |
175 | 186 | ||
176 | if (id && (id->capability & 1) && drive->autodma) { | 187 | if ((id->capability & 1) && drive->autodma) { |
177 | 188 | ||
178 | if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive)) | 189 | if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive)) |
179 | return hwif->ide_dma_on(drive); | 190 | return hwif->ide_dma_on(drive); |
@@ -201,7 +212,7 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) | |||
201 | hwif->irq = hwif->channel ? 15 : 14; | 212 | hwif->irq = hwif->channel ? 15 : 14; |
202 | 213 | ||
203 | hwif->speedproc = &slc90e66_tune_chipset; | 214 | hwif->speedproc = &slc90e66_tune_chipset; |
204 | hwif->tuneproc = &slc90e66_tune_drive; | 215 | hwif->tuneproc = &slc90e66_tune_drive; |
205 | 216 | ||
206 | pci_read_config_byte(hwif->pci_dev, 0x47, ®47); | 217 | pci_read_config_byte(hwif->pci_dev, 0x47, ®47); |
207 | 218 | ||
@@ -213,14 +224,16 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) | |||
213 | 224 | ||
214 | hwif->atapi_dma = 1; | 225 | hwif->atapi_dma = 1; |
215 | hwif->ultra_mask = 0x1f; | 226 | hwif->ultra_mask = 0x1f; |
216 | hwif->mwdma_mask = 0x07; | 227 | hwif->mwdma_mask = 0x06; |
217 | hwif->swdma_mask = 0x07; | 228 | hwif->swdma_mask = 0x04; |
218 | 229 | ||
219 | if (!(hwif->udma_four)) | 230 | if (!hwif->udma_four) { |
220 | /* bit[0(1)]: 0:80, 1:40 */ | 231 | /* bit[0(1)]: 0:80, 1:40 */ |
221 | hwif->udma_four = (reg47 & mask) ? 0 : 1; | 232 | hwif->udma_four = (reg47 & mask) ? 0 : 1; |
233 | } | ||
222 | 234 | ||
223 | hwif->ide_dma_check = &slc90e66_config_drive_xfer_rate; | 235 | hwif->ide_dma_check = &slc90e66_config_drive_xfer_rate; |
236 | |||
224 | if (!noautodma) | 237 | if (!noautodma) |
225 | hwif->autodma = 1; | 238 | hwif->autodma = 1; |
226 | hwif->drives[0].autodma = hwif->autodma; | 239 | hwif->drives[0].autodma = hwif->autodma; |