diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-11 22:20:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-11 22:20:44 -0400 |
commit | 19f71153b9be219756c6b2757921433a69b7975c (patch) | |
tree | cc2c5c290a88d61df16848f733aed8708e82c119 /drivers/ide/ide-lib.c | |
parent | e6005a85acb9609326512ecc784859831cfb24a3 (diff) | |
parent | 8f4dd2e42637fd61a6366d2cace69091926eaa15 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (24 commits)
ide: use only ->set_pio_mode method for programming PIO modes (take 2)
sis5513: don't change UDMA settings when programming PIO
it8213/piix/slc90e66: don't change DMA settings when programming PIO
alim15x3: PIO mode setup fixes
siimage: fix ->set_pio_mode method to select PIO data transfer
cs5520: don't enable VDMA in ->speedproc
sc1200: remove redundant warning message from sc1200_tune_chipset()
ide-pmac: PIO mode setup fixes (take 3)
icside: fix ->speedproc to return on unsupported modes (take 5)
sgiioc4: use ide_tune_dma()
amd74xx/via82cxxx: use ide_tune_dma()
ide: add ide_set{_max}_pio() (take 4)
ide: Kconfig face-lift
ide: move ide_rate_filter() calls to the upper layer (take 2)
sis5513: add ->udma_filter method for chipset_family >= ATA_133
ide: mode limiting fixes for user requested speed changes
ide: add missing ide_rate_filter() calls to ->speedproc()-s
ide: call udma_filter() before resorting to the UltraDMA mask
ide: make jmicron match vendor and device class
pdc202xx_new: switch to using pci_get_slot() (take 2)
...
Diffstat (limited to 'drivers/ide/ide-lib.c')
-rw-r--r-- | drivers/ide/ide-lib.c | 85 |
1 files changed, 56 insertions, 29 deletions
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 92a6c7bcf527..d97390c0543b 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
@@ -76,41 +76,26 @@ EXPORT_SYMBOL(ide_xfer_verbose); | |||
76 | * Given the available transfer modes this function returns | 76 | * Given the available transfer modes this function returns |
77 | * the best available speed at or below the speed requested. | 77 | * the best available speed at or below the speed requested. |
78 | * | 78 | * |
79 | * FIXME: filter also PIO/SWDMA/MWDMA modes | 79 | * TODO: check device PIO capabilities |
80 | */ | 80 | */ |
81 | 81 | ||
82 | u8 ide_rate_filter(ide_drive_t *drive, u8 speed) | 82 | static u8 ide_rate_filter(ide_drive_t *drive, u8 speed) |
83 | { | 83 | { |
84 | #ifdef CONFIG_BLK_DEV_IDEDMA | ||
85 | ide_hwif_t *hwif = drive->hwif; | 84 | ide_hwif_t *hwif = drive->hwif; |
86 | u8 mask = hwif->ultra_mask, mode = XFER_MW_DMA_2; | 85 | u8 mode = ide_find_dma_mode(drive, speed); |
87 | 86 | ||
88 | if (hwif->udma_filter) | 87 | if (mode == 0) { |
89 | mask = hwif->udma_filter(drive); | 88 | if (hwif->pio_mask) |
90 | 89 | mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0; | |
91 | /* | 90 | else |
92 | * TODO: speed > XFER_UDMA_2 extra check is needed to avoid false | 91 | mode = XFER_PIO_4; |
93 | * cable warning from eighty_ninty_three(), moving ide_rate_filter() | ||
94 | * calls from ->speedproc to core code will make this hack go away | ||
95 | */ | ||
96 | if (speed > XFER_UDMA_2) { | ||
97 | if ((mask & 0x78) && (eighty_ninty_three(drive) == 0)) | ||
98 | mask &= 0x07; | ||
99 | } | 92 | } |
100 | 93 | ||
101 | if (mask) | ||
102 | mode = fls(mask) - 1 + XFER_UDMA_0; | ||
103 | |||
104 | // printk("%s: mode 0x%02x, speed 0x%02x\n", __FUNCTION__, mode, speed); | 94 | // printk("%s: mode 0x%02x, speed 0x%02x\n", __FUNCTION__, mode, speed); |
105 | 95 | ||
106 | return min(speed, mode); | 96 | return min(speed, mode); |
107 | #else /* !CONFIG_BLK_DEV_IDEDMA */ | ||
108 | return min(speed, (u8)XFER_PIO_4); | ||
109 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | ||
110 | } | 97 | } |
111 | 98 | ||
112 | EXPORT_SYMBOL(ide_rate_filter); | ||
113 | |||
114 | int ide_use_fast_pio(ide_drive_t *drive) | 99 | int ide_use_fast_pio(ide_drive_t *drive) |
115 | { | 100 | { |
116 | struct hd_driveid *id = drive->id; | 101 | struct hd_driveid *id = drive->id; |
@@ -340,6 +325,35 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode) | |||
340 | 325 | ||
341 | EXPORT_SYMBOL_GPL(ide_get_best_pio_mode); | 326 | EXPORT_SYMBOL_GPL(ide_get_best_pio_mode); |
342 | 327 | ||
328 | /* req_pio == "255" for auto-tune */ | ||
329 | void ide_set_pio(ide_drive_t *drive, u8 req_pio) | ||
330 | { | ||
331 | ide_hwif_t *hwif = drive->hwif; | ||
332 | u8 host_pio, pio; | ||
333 | |||
334 | if (hwif->set_pio_mode == NULL) | ||
335 | return; | ||
336 | |||
337 | BUG_ON(hwif->pio_mask == 0x00); | ||
338 | |||
339 | host_pio = fls(hwif->pio_mask) - 1; | ||
340 | |||
341 | pio = ide_get_best_pio_mode(drive, req_pio, host_pio); | ||
342 | |||
343 | /* | ||
344 | * TODO: | ||
345 | * - report device max PIO mode | ||
346 | * - check req_pio != 255 against device max PIO mode | ||
347 | */ | ||
348 | printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n", | ||
349 | drive->name, host_pio, req_pio, | ||
350 | req_pio == 255 ? "(auto-tune)" : "", pio); | ||
351 | |||
352 | hwif->set_pio_mode(drive, pio); | ||
353 | } | ||
354 | |||
355 | EXPORT_SYMBOL_GPL(ide_set_pio); | ||
356 | |||
343 | /** | 357 | /** |
344 | * ide_toggle_bounce - handle bounce buffering | 358 | * ide_toggle_bounce - handle bounce buffering |
345 | * @drive: drive to update | 359 | * @drive: drive to update |
@@ -377,13 +391,26 @@ void ide_toggle_bounce(ide_drive_t *drive, int on) | |||
377 | 391 | ||
378 | int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) | 392 | int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) |
379 | { | 393 | { |
380 | #ifndef CONFIG_BLK_DEV_IDEDMA | 394 | ide_hwif_t *hwif = drive->hwif; |
381 | rate = min(rate, (u8) XFER_PIO_4); | 395 | |
382 | #endif | 396 | if (hwif->speedproc == NULL) |
383 | if(HWIF(drive)->speedproc) | ||
384 | return HWIF(drive)->speedproc(drive, rate); | ||
385 | else | ||
386 | return -1; | 397 | return -1; |
398 | |||
399 | rate = ide_rate_filter(drive, rate); | ||
400 | |||
401 | if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) { | ||
402 | if (hwif->set_pio_mode) | ||
403 | hwif->set_pio_mode(drive, rate - XFER_PIO_0); | ||
404 | |||
405 | /* | ||
406 | * FIXME: this is incorrect to return zero here but | ||
407 | * since all users of ide_set_xfer_rate() ignore | ||
408 | * the return value it is not a problem currently | ||
409 | */ | ||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | return hwif->speedproc(drive, rate); | ||
387 | } | 414 | } |
388 | 415 | ||
389 | static void ide_dump_opcode(ide_drive_t *drive) | 416 | static void ide_dump_opcode(ide_drive_t *drive) |