diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-08-01 17:46:45 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-08-01 17:46:45 -0400 |
commit | bc0b0b5c4bab02790937c9070a7701ee70feaac9 (patch) | |
tree | 3dc9de74ba1c70df025ab8824fe1fcc79101380b /drivers/ide/pci/cs5535.c | |
parent | 070224339b52f0e4f8e6c991a5ad9630a7a9e6da (diff) |
cs5535: PIO fixes
* Fix cs5535_tuneproc() to pass PIO transfer mode value instead of PIO mode
number to cs5535_set_speed() (fixes random PIO timings being programmed
and a possible OOPS). Do a little cleanup while at it.
* Fix cs5535_set_speed() to check if the mate device is present (fixes PIO0
taskfile timings being used if there is no other device on the cable).
* Use cs5535_tuneproc() in cs5535_dma_check(). The old code had the same
issue as cs5535_tuneproc() and add additionally caused 0x00-0x04 transfer
mode values (== default PIO, default PIO w/ IORDY + two invalid values)
being set on the device instead of values 0x08-0x0c (XFER_PIO_[0,4]).
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/pci/cs5535.c')
-rw-r--r-- | drivers/ide/pci/cs5535.c | 40 |
1 files changed, 17 insertions, 23 deletions
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index 9bd526db03cf..082ca7da2cbc 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * linux/drivers/ide/pci/cs5535.c | 2 | * linux/drivers/ide/pci/cs5535.c |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2005 Advanced Micro Devices, Inc. | 4 | * Copyright (C) 2004-2005 Advanced Micro Devices, Inc. |
5 | * Copyright (C) 2007 Bartlomiej Zolnierkiewicz | ||
5 | * | 6 | * |
6 | * History: | 7 | * History: |
7 | * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com> | 8 | * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com> |
@@ -83,14 +84,17 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed) | |||
83 | 84 | ||
84 | /* Set the PIO timings */ | 85 | /* Set the PIO timings */ |
85 | if ((speed & XFER_MODE) == XFER_PIO) { | 86 | if ((speed & XFER_MODE) == XFER_PIO) { |
86 | u8 pioa; | 87 | ide_drive_t *pair = &drive->hwif->drives[drive->dn ^ 1]; |
87 | u8 piob; | 88 | u8 cmd, pioa; |
88 | u8 cmd; | ||
89 | 89 | ||
90 | pioa = speed - XFER_PIO_0; | 90 | cmd = pioa = speed - XFER_PIO_0; |
91 | piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]), | 91 | |
92 | 255, 4); | 92 | if (pair->present) { |
93 | cmd = pioa < piob ? pioa : piob; | 93 | u8 piob = ide_get_best_pio_mode(pair, 255, 4); |
94 | |||
95 | if (piob < cmd) | ||
96 | cmd = piob; | ||
97 | } | ||
94 | 98 | ||
95 | /* Write the speed of the current drive */ | 99 | /* Write the speed of the current drive */ |
96 | reg = (cs5535_pio_cmd_timings[cmd] << 16) | | 100 | reg = (cs5535_pio_cmd_timings[cmd] << 16) | |
@@ -151,32 +155,22 @@ static int cs5535_set_drive(ide_drive_t *drive, u8 speed) | |||
151 | * | 155 | * |
152 | * A callback from the upper layers for PIO-only tuning. | 156 | * A callback from the upper layers for PIO-only tuning. |
153 | */ | 157 | */ |
154 | static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed) | 158 | static void cs5535_tuneproc(ide_drive_t *drive, u8 pio) |
155 | { | 159 | { |
156 | u8 modes[] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, | 160 | pio = ide_get_best_pio_mode(drive, pio, 4); |
157 | XFER_PIO_4 }; | 161 | ide_config_drive_speed(drive, XFER_PIO_0 + pio); |
158 | 162 | cs5535_set_speed(drive, XFER_PIO_0 + pio); | |
159 | /* cs5535 max pio is pio 4, best_pio will check the blacklist. | ||
160 | i think we don't need to rate_filter the incoming xferspeed | ||
161 | since we know we're only going to choose pio */ | ||
162 | xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4); | ||
163 | ide_config_drive_speed(drive, modes[xferspeed]); | ||
164 | cs5535_set_speed(drive, xferspeed); | ||
165 | } | 163 | } |
166 | 164 | ||
167 | static int cs5535_dma_check(ide_drive_t *drive) | 165 | static int cs5535_dma_check(ide_drive_t *drive) |
168 | { | 166 | { |
169 | u8 speed; | ||
170 | |||
171 | drive->init_speed = 0; | 167 | drive->init_speed = 0; |
172 | 168 | ||
173 | if (ide_tune_dma(drive)) | 169 | if (ide_tune_dma(drive)) |
174 | return 0; | 170 | return 0; |
175 | 171 | ||
176 | if (ide_use_fast_pio(drive)) { | 172 | if (ide_use_fast_pio(drive)) |
177 | speed = ide_get_best_pio_mode(drive, 255, 4); | 173 | cs5535_tuneproc(drive, 255); |
178 | cs5535_set_drive(drive, speed); | ||
179 | } | ||
180 | 174 | ||
181 | return -1; | 175 | return -1; |
182 | } | 176 | } |