aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-lib.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 22:20:44 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 22:20:44 -0400
commit19f71153b9be219756c6b2757921433a69b7975c (patch)
treecc2c5c290a88d61df16848f733aed8708e82c119 /drivers/ide/ide-lib.c
parente6005a85acb9609326512ecc784859831cfb24a3 (diff)
parent8f4dd2e42637fd61a6366d2cace69091926eaa15 (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.c85
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
82u8 ide_rate_filter(ide_drive_t *drive, u8 speed) 82static 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
112EXPORT_SYMBOL(ide_rate_filter);
113
114int ide_use_fast_pio(ide_drive_t *drive) 99int 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
341EXPORT_SYMBOL_GPL(ide_get_best_pio_mode); 326EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
342 327
328/* req_pio == "255" for auto-tune */
329void 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
355EXPORT_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
378int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) 392int 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
389static void ide_dump_opcode(ide_drive_t *drive) 416static void ide_dump_opcode(ide_drive_t *drive)