Commit bc0b0b5c4bab02790937c9070a7701ee70feaac9
1 parent
070224339b
Exists in
master
and in
7 other branches
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>
Showing 1 changed file with 17 additions and 23 deletions Side-by-side Diff
drivers/ide/pci/cs5535.c
... | ... | @@ -2,6 +2,7 @@ |
2 | 2 | * linux/drivers/ide/pci/cs5535.c |
3 | 3 | * |
4 | 4 | * Copyright (C) 2004-2005 Advanced Micro Devices, Inc. |
5 | + * Copyright (C) 2007 Bartlomiej Zolnierkiewicz | |
5 | 6 | * |
6 | 7 | * History: |
7 | 8 | * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com> |
8 | 9 | |
9 | 10 | |
... | ... | @@ -83,15 +84,18 @@ |
83 | 84 | |
84 | 85 | /* Set the PIO timings */ |
85 | 86 | if ((speed & XFER_MODE) == XFER_PIO) { |
86 | - u8 pioa; | |
87 | - u8 piob; | |
88 | - u8 cmd; | |
87 | + ide_drive_t *pair = &drive->hwif->drives[drive->dn ^ 1]; | |
88 | + u8 cmd, pioa; | |
89 | 89 | |
90 | - pioa = speed - XFER_PIO_0; | |
91 | - piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]), | |
92 | - 255, 4); | |
93 | - cmd = pioa < piob ? pioa : piob; | |
90 | + cmd = pioa = speed - XFER_PIO_0; | |
94 | 91 | |
92 | + if (pair->present) { | |
93 | + u8 piob = ide_get_best_pio_mode(pair, 255, 4); | |
94 | + | |
95 | + if (piob < cmd) | |
96 | + cmd = piob; | |
97 | + } | |
98 | + | |
95 | 99 | /* Write the speed of the current drive */ |
96 | 100 | reg = (cs5535_pio_cmd_timings[cmd] << 16) | |
97 | 101 | cs5535_pio_dta_timings[pioa]; |
98 | 102 | |
99 | 103 | |
100 | 104 | |
... | ... | @@ -151,32 +155,22 @@ |
151 | 155 | * |
152 | 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, | |
157 | - XFER_PIO_4 }; | |
158 | - | |
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); | |
160 | + pio = ide_get_best_pio_mode(drive, pio, 4); | |
161 | + ide_config_drive_speed(drive, XFER_PIO_0 + pio); | |
162 | + cs5535_set_speed(drive, XFER_PIO_0 + pio); | |
165 | 163 | } |
166 | 164 | |
167 | 165 | static int cs5535_dma_check(ide_drive_t *drive) |
168 | 166 | { |
169 | - u8 speed; | |
170 | - | |
171 | 167 | drive->init_speed = 0; |
172 | 168 | |
173 | 169 | if (ide_tune_dma(drive)) |
174 | 170 | return 0; |
175 | 171 | |
176 | - if (ide_use_fast_pio(drive)) { | |
177 | - speed = ide_get_best_pio_mode(drive, 255, 4); | |
178 | - cs5535_set_drive(drive, speed); | |
179 | - } | |
172 | + if (ide_use_fast_pio(drive)) | |
173 | + cs5535_tuneproc(drive, 255); | |
180 | 174 | |
181 | 175 | return -1; |
182 | 176 | } |