diff options
Diffstat (limited to 'drivers/ide/pci/cmd64x.c')
-rw-r--r-- | drivers/ide/pci/cmd64x.c | 45 |
1 files changed, 20 insertions, 25 deletions
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index b0d4825c56a9..561197f7b5bb 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 | 1 | /* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 |
2 | * | 2 | * |
3 | * linux/drivers/ide/pci/cmd64x.c Version 1.41 Feb 3, 2007 | 3 | * linux/drivers/ide/pci/cmd64x.c Version 1.42 Feb 8, 2007 |
4 | * | 4 | * |
5 | * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. | 5 | * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. |
6 | * Note, this driver is not used at all on other systems because | 6 | * Note, this driver is not used at all on other systems because |
@@ -189,6 +189,11 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) | |||
189 | 189 | ||
190 | #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */ | 190 | #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */ |
191 | 191 | ||
192 | static u8 quantize_timing(int timing, int quant) | ||
193 | { | ||
194 | return (timing + quant - 1) / quant; | ||
195 | } | ||
196 | |||
192 | /* | 197 | /* |
193 | * This routine writes the prepared setup/active/recovery counts | 198 | * This routine writes the prepared setup/active/recovery counts |
194 | * for a drive into the cmd646 chipset registers to active them. | 199 | * for a drive into the cmd646 chipset registers to active them. |
@@ -268,47 +273,37 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ | |||
268 | */ | 273 | */ |
269 | static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted) | 274 | static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted) |
270 | { | 275 | { |
271 | int setup_time, active_time, recovery_time; | 276 | int setup_time, active_time, cycle_time; |
272 | int clock_time, pio_mode, cycle_time; | 277 | u8 cycle_count, setup_count, active_count, recovery_count; |
273 | u8 recovery_count2, cycle_count; | 278 | u8 pio_mode; |
274 | int setup_count, active_count, recovery_count; | 279 | int clock_time = 1000 / system_bus_clock(); |
275 | int bus_speed = system_bus_clock(); | 280 | ide_pio_data_t pio; |
276 | ide_pio_data_t d; | ||
277 | 281 | ||
278 | pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &d); | 282 | pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &pio); |
279 | cycle_time = d.cycle_time; | 283 | cycle_time = pio.cycle_time; |
280 | 284 | ||
281 | /* | ||
282 | * I copied all this complicated stuff from cmd640.c and made a few | ||
283 | * minor changes. For now I am just going to pray that it is correct. | ||
284 | */ | ||
285 | setup_time = ide_pio_timings[pio_mode].setup_time; | 285 | setup_time = ide_pio_timings[pio_mode].setup_time; |
286 | active_time = ide_pio_timings[pio_mode].active_time; | 286 | active_time = ide_pio_timings[pio_mode].active_time; |
287 | recovery_time = cycle_time - (setup_time + active_time); | ||
288 | clock_time = 1000 / bus_speed; | ||
289 | cycle_count = (cycle_time + clock_time - 1) / clock_time; | ||
290 | |||
291 | setup_count = (setup_time + clock_time - 1) / clock_time; | ||
292 | 287 | ||
293 | active_count = (active_time + clock_time - 1) / clock_time; | 288 | setup_count = quantize_timing( setup_time, clock_time); |
289 | cycle_count = quantize_timing( cycle_time, clock_time); | ||
290 | active_count = quantize_timing(active_time, clock_time); | ||
294 | 291 | ||
295 | recovery_count = (recovery_time + clock_time - 1) / clock_time; | 292 | recovery_count = cycle_count - active_count; |
296 | recovery_count2 = cycle_count - (setup_count + active_count); | 293 | /* program_drive_counts() takes care of zero recovery cycles */ |
297 | if (recovery_count2 > recovery_count) | ||
298 | recovery_count = recovery_count2; | ||
299 | if (recovery_count > 16) { | 294 | if (recovery_count > 16) { |
300 | active_count += recovery_count - 16; | 295 | active_count += recovery_count - 16; |
301 | recovery_count = 16; | 296 | recovery_count = 16; |
302 | } | 297 | } |
303 | if (active_count > 16) | 298 | if (active_count > 16) |
304 | active_count = 16; /* maximum allowed by cmd646 */ | 299 | active_count = 16; /* maximum allowed by cmd64x */ |
305 | 300 | ||
306 | program_drive_counts (drive, setup_count, active_count, recovery_count); | 301 | program_drive_counts (drive, setup_count, active_count, recovery_count); |
307 | 302 | ||
308 | cmdprintk("%s: PIO mode wanted %d, selected %d (%dns)%s, " | 303 | cmdprintk("%s: PIO mode wanted %d, selected %d (%dns)%s, " |
309 | "clocks=%d/%d/%d\n", | 304 | "clocks=%d/%d/%d\n", |
310 | drive->name, mode_wanted, pio_mode, cycle_time, | 305 | drive->name, mode_wanted, pio_mode, cycle_time, |
311 | d.overridden ? " (overriding vendor mode)" : "", | 306 | pio.overridden ? " (overriding vendor mode)" : "", |
312 | setup_count, active_count, recovery_count); | 307 | setup_count, active_count, recovery_count); |
313 | 308 | ||
314 | return pio_mode; | 309 | return pio_mode; |