diff options
Diffstat (limited to 'drivers/ide/pci/piix.c')
-rw-r--r-- | drivers/ide/pci/piix.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index 569822f4cf55..061d300ab8be 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c | |||
@@ -1,10 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/piix.c Version 0.46 December 3, 2006 | 2 | * linux/drivers/ide/pci/piix.c Version 0.47 February 8, 2007 |
3 | * | 3 | * |
4 | * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer | 4 | * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer |
5 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> | 5 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> |
6 | * Copyright (C) 2003 Red Hat Inc <alan@redhat.com> | 6 | * Copyright (C) 2003 Red Hat Inc <alan@redhat.com> |
7 | * Copyright (C) 2006 MontaVista Software, Inc. <source@mvista.com> | 7 | * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> |
8 | * | 8 | * |
9 | * May be copied or modified under the terms of the GNU General Public License | 9 | * May be copied or modified under the terms of the GNU General Public License |
10 | * | 10 | * |
@@ -205,14 +205,13 @@ static u8 piix_dma_2_pio (u8 xfer_rate) { | |||
205 | } | 205 | } |
206 | 206 | ||
207 | /** | 207 | /** |
208 | * piix_tune_drive - tune a drive attached to a PIIX | 208 | * piix_tune_pio - tune PIIX for PIO mode |
209 | * @drive: drive to tune | 209 | * @drive: drive to tune |
210 | * @pio: desired PIO mode | 210 | * @pio: desired PIO mode |
211 | * | 211 | * |
212 | * Set the interface PIO mode based upon the settings done by AMI BIOS | 212 | * Set the interface PIO mode based upon the settings done by AMI BIOS. |
213 | * (might be useful if drive is not registered in CMOS for any reason). | ||
214 | */ | 213 | */ |
215 | static void piix_tune_drive (ide_drive_t *drive, u8 pio) | 214 | static void piix_tune_pio (ide_drive_t *drive, u8 pio) |
216 | { | 215 | { |
217 | ide_hwif_t *hwif = HWIF(drive); | 216 | ide_hwif_t *hwif = HWIF(drive); |
218 | struct pci_dev *dev = hwif->pci_dev; | 217 | struct pci_dev *dev = hwif->pci_dev; |
@@ -233,8 +232,6 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) | |||
233 | { 2, 1 }, | 232 | { 2, 1 }, |
234 | { 2, 3 }, }; | 233 | { 2, 3 }, }; |
235 | 234 | ||
236 | pio = ide_get_best_pio_mode(drive, pio, 4, NULL); | ||
237 | |||
238 | /* | 235 | /* |
239 | * Master vs slave is synchronized above us but the slave register is | 236 | * Master vs slave is synchronized above us but the slave register is |
240 | * shared by the two hwifs so the corner case of two slave timeouts in | 237 | * shared by the two hwifs so the corner case of two slave timeouts in |
@@ -253,19 +250,20 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) | |||
253 | master_data |= 0x4000; | 250 | master_data |= 0x4000; |
254 | master_data &= ~0x0070; | 251 | master_data &= ~0x0070; |
255 | if (pio > 1) { | 252 | if (pio > 1) { |
256 | /* enable PPE, IE and TIME */ | 253 | /* Set PPE, IE and TIME */ |
257 | master_data = master_data | (control << 4); | 254 | master_data |= control << 4; |
258 | } | 255 | } |
259 | pci_read_config_byte(dev, slave_port, &slave_data); | 256 | pci_read_config_byte(dev, slave_port, &slave_data); |
260 | slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0); | 257 | slave_data &= hwif->channel ? 0x0f : 0xf0; |
261 | slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0)); | 258 | slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << |
259 | (hwif->channel ? 4 : 0); | ||
262 | } else { | 260 | } else { |
263 | master_data &= ~0x3307; | 261 | master_data &= ~0x3307; |
264 | if (pio > 1) { | 262 | if (pio > 1) { |
265 | /* enable PPE, IE and TIME */ | 263 | /* enable PPE, IE and TIME */ |
266 | master_data = master_data | control; | 264 | master_data |= control; |
267 | } | 265 | } |
268 | master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8); | 266 | master_data |= (timings[pio][0] << 12) | (timings[pio][1] << 8); |
269 | } | 267 | } |
270 | pci_write_config_word(dev, master_port, master_data); | 268 | pci_write_config_word(dev, master_port, master_data); |
271 | if (is_slave) | 269 | if (is_slave) |
@@ -274,6 +272,21 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) | |||
274 | } | 272 | } |
275 | 273 | ||
276 | /** | 274 | /** |
275 | * piix_tune_drive - tune a drive attached to PIIX | ||
276 | * @drive: drive to tune | ||
277 | * @pio: desired PIO mode | ||
278 | * | ||
279 | * Set the drive's PIO mode (might be useful if drive is not registered | ||
280 | * in CMOS for any reason). | ||
281 | */ | ||
282 | static void piix_tune_drive (ide_drive_t *drive, u8 pio) | ||
283 | { | ||
284 | pio = ide_get_best_pio_mode(drive, pio, 4, NULL); | ||
285 | piix_tune_pio(drive, pio); | ||
286 | (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); | ||
287 | } | ||
288 | |||
289 | /** | ||
277 | * piix_tune_chipset - tune a PIIX interface | 290 | * piix_tune_chipset - tune a PIIX interface |
278 | * @drive: IDE drive to tune | 291 | * @drive: IDE drive to tune |
279 | * @xferspeed: speed to configure | 292 | * @xferspeed: speed to configure |
@@ -348,8 +361,8 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
348 | pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); | 361 | pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); |
349 | } | 362 | } |
350 | 363 | ||
351 | piix_tune_drive(drive, piix_dma_2_pio(speed)); | 364 | piix_tune_pio(drive, piix_dma_2_pio(speed)); |
352 | return (ide_config_drive_speed(drive, speed)); | 365 | return ide_config_drive_speed(drive, speed); |
353 | } | 366 | } |
354 | 367 | ||
355 | /** | 368 | /** |
@@ -392,9 +405,7 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive) | |||
392 | return 0; | 405 | return 0; |
393 | 406 | ||
394 | if (ide_use_fast_pio(drive)) | 407 | if (ide_use_fast_pio(drive)) |
395 | /* Find best PIO mode. */ | 408 | piix_tune_drive(drive, 255); |
396 | piix_tune_chipset(drive, XFER_PIO_0 + | ||
397 | ide_get_best_pio_mode(drive, 255, 4, NULL)); | ||
398 | 409 | ||
399 | return -1; | 410 | return -1; |
400 | } | 411 | } |