Commit bc0b0b5c4bab02790937c9070a7701ee70feaac9

Authored by Bartlomiej Zolnierkiewicz
1 parent 070224339b

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 }