Commit 451dd094 authored by Jens Axboe's avatar Jens Axboe

[PATCH] enable ide to use bios timings

This is the 2nd version Torben did, basically the same as the one from
yesterday but with symbolic tune defines instead of more magic numbers.
I think the feature is good to have, and it would even allow good ide
performance even for an unsupported chipset as long as the bios sets the
timings right.

From Torben Mathiasen.
parent 9ed7542f
...@@ -1028,9 +1028,18 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p ...@@ -1028,9 +1028,18 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
if (hwif->chipset != ide_trm290) { if (hwif->chipset != ide_trm290) {
u8 dma_stat = hwif->INB(hwif->dma_status); u8 dma_stat = hwif->INB(hwif->dma_status);
printk(", BIOS settings: %s:%s, %s:%s", printk(", BIOS settings: %s:%s%s, %s:%s%s",
hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio", hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio",
hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio"); hwif->drives[0].autotune == IDE_TUNE_BIOS ?
" (used)" : "",
hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio",
hwif->drives[1].autotune == IDE_TUNE_BIOS ?
" (used)" : "");
if (hwif->drives[0].autotune == IDE_TUNE_BIOS)
hwif->drives[0].using_dma = (dma_stat & 0x20);
if (hwif->drives[1].autotune == IDE_TUNE_BIOS)
hwif->drives[1].using_dma = (dma_stat & 0x40);
} }
printk("\n"); printk("\n");
......
...@@ -434,7 +434,9 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -434,7 +434,9 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
if (hwif->INB(IDE_STATUS_REG) == (BUSY_STAT|READY_STAT)) if (hwif->INB(IDE_STATUS_REG) == (BUSY_STAT|READY_STAT))
return 4; return 4;
if (rc == 1 && cmd == WIN_PIDENTIFY && drive->autotune != 2) { if ((rc == 1 && cmd == WIN_PIDENTIFY) &&
((drive->autotune == IDE_TUNE_DEFAULT) ||
(drive->autotune == IDE_TUNE_AUTO))) {
unsigned long timeout; unsigned long timeout;
printk("%s: no response (status = 0x%02x), " printk("%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name, "resetting drive\n", drive->name,
...@@ -699,7 +701,8 @@ void probe_hwif (ide_hwif_t *hwif) ...@@ -699,7 +701,8 @@ void probe_hwif (ide_hwif_t *hwif)
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit]; ide_drive_t *drive = &hwif->drives[unit];
if (drive->present) { if (drive->present) {
if (hwif->tuneproc != NULL && drive->autotune == 1) if (hwif->tuneproc != NULL &&
drive->autotune == IDE_TUNE_AUTO)
/* auto-tune PIO mode */ /* auto-tune PIO mode */
hwif->tuneproc(drive, 255); hwif->tuneproc(drive, 255);
/* /*
...@@ -711,7 +714,9 @@ void probe_hwif (ide_hwif_t *hwif) ...@@ -711,7 +714,9 @@ void probe_hwif (ide_hwif_t *hwif)
* Move here to prevent module loading clashing. * Move here to prevent module loading clashing.
*/ */
// drive->autodma = hwif->autodma; // drive->autodma = hwif->autodma;
if ((drive->autotune != 2) && (hwif->ide_dma_check)) { if ((hwif->ide_dma_check) &&
((drive->autotune == IDE_TUNE_DEFAULT) ||
(drive->autotune == IDE_TUNE_AUTO))) {
/* /*
* Force DMAing for the beginning of the check. * Force DMAing for the beginning of the check.
* Some chipsets appear to do interesting * Some chipsets appear to do interesting
......
...@@ -2621,7 +2621,8 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m ...@@ -2621,7 +2621,8 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m
* Not fully supported by all chipset types, * Not fully supported by all chipset types,
* and quite likely to cause trouble with * and quite likely to cause trouble with
* older/odd IDE drives. * older/odd IDE drives.
* * "hdx=biostimings" : driver will NOT attempt to tune interface speed
* (DMA/PIO) but always honour BIOS timings.
* "hdx=slow" : insert a huge pause after each access to the data * "hdx=slow" : insert a huge pause after each access to the data
* port. Should be used only as a last resort. * port. Should be used only as a last resort.
* *
...@@ -2658,6 +2659,8 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m ...@@ -2658,6 +2659,8 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m
* "idex=noautotune" : driver will NOT attempt to tune interface speed * "idex=noautotune" : driver will NOT attempt to tune interface speed
* This is the default for most chipsets, * This is the default for most chipsets,
* except the cmd640. * except the cmd640.
* "idex=biostimings" : driver will NOT attempt to tune interface speed
* (DMA/PIO) but always honour BIOS timings.
* "idex=serialize" : do not overlap operations on idex and ide(x^1) * "idex=serialize" : do not overlap operations on idex and ide(x^1)
* "idex=four" : four drives on idex and ide(x^1) share same ports * "idex=four" : four drives on idex and ide(x^1) share same ports
* "idex=reset" : reset interface before first use * "idex=reset" : reset interface before first use
...@@ -2733,7 +2736,8 @@ int __init ide_setup (char *s) ...@@ -2733,7 +2736,8 @@ int __init ide_setup (char *s)
const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom", const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom",
"serialize", "autotune", "noautotune", "serialize", "autotune", "noautotune",
"slow", "swapdata", "bswap", "flash", "slow", "swapdata", "bswap", "flash",
"remap", "noremap", "scsi", NULL}; "remap", "noremap", "scsi", "biostimings",
NULL};
unit = s[2] - 'a'; unit = s[2] - 'a';
hw = unit / MAX_DRIVES; hw = unit / MAX_DRIVES;
unit = unit % MAX_DRIVES; unit = unit % MAX_DRIVES;
...@@ -2775,10 +2779,10 @@ int __init ide_setup (char *s) ...@@ -2775,10 +2779,10 @@ int __init ide_setup (char *s)
printk(" -- USE \"ide%d=serialize\" INSTEAD", hw); printk(" -- USE \"ide%d=serialize\" INSTEAD", hw);
goto do_serialize; goto do_serialize;
case -6: /* "autotune" */ case -6: /* "autotune" */
drive->autotune = 1; drive->autotune = IDE_TUNE_AUTO;
goto done; goto done;
case -7: /* "noautotune" */ case -7: /* "noautotune" */
drive->autotune = 2; drive->autotune = IDE_TUNE_NOAUTO;
goto done; goto done;
case -8: /* "slow" */ case -8: /* "slow" */
drive->slow = 1; drive->slow = 1;
...@@ -2804,6 +2808,9 @@ int __init ide_setup (char *s) ...@@ -2804,6 +2808,9 @@ int __init ide_setup (char *s)
drive->scsi = 0; drive->scsi = 0;
goto bad_option; goto bad_option;
#endif /* defined(CONFIG_BLK_DEV_IDESCSI) && defined(CONFIG_SCSI) */ #endif /* defined(CONFIG_BLK_DEV_IDESCSI) && defined(CONFIG_SCSI) */
case -15: /* "biostimings" */
drive->autotune = IDE_TUNE_BIOS;
goto done;
case 3: /* cyl,head,sect */ case 3: /* cyl,head,sect */
drive->media = ide_disk; drive->media = ide_disk;
drive->cyl = drive->bios_cyl = vals[0]; drive->cyl = drive->bios_cyl = vals[0];
...@@ -2841,9 +2848,10 @@ int __init ide_setup (char *s) ...@@ -2841,9 +2848,10 @@ int __init ide_setup (char *s)
* -8,-9,-10 : are reserved for future idex calls to ease the hardcoding. * -8,-9,-10 : are reserved for future idex calls to ease the hardcoding.
*/ */
const char *ide_words[] = { const char *ide_words[] = {
"noprobe", "serialize", "autotune", "noautotune", "reset", "dma", "ata66", "noprobe", "serialize", "autotune", "noautotune",
"minus8", "minus9", "minus10", "reset", "dma", "ata66", "minus8", "minus9", "minus10",
"four", "qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL }; "four", "qd65xx", "ht6560b", "cmd640_vlb", "dtc2278",
"umc8672", "ali14xx", "dc4030", "biostimings", NULL };
hw = s[3] - '0'; hw = s[3] - '0';
hwif = &ide_hwifs[hw]; hwif = &ide_hwifs[hw];
i = match_parm(&s[4], ide_words, vals, 3); i = match_parm(&s[4], ide_words, vals, 3);
...@@ -2862,6 +2870,10 @@ int __init ide_setup (char *s) ...@@ -2862,6 +2870,10 @@ int __init ide_setup (char *s)
} }
switch (i) { switch (i) {
case -19: /* "biostimings" */
hwif->drives[0].autotune = IDE_TUNE_BIOS;
hwif->drives[1].autotune = IDE_TUNE_BIOS;
goto done;
#ifdef CONFIG_BLK_DEV_PDC4030 #ifdef CONFIG_BLK_DEV_PDC4030
case -18: /* "dc4030" */ case -18: /* "dc4030" */
{ {
...@@ -2949,12 +2961,12 @@ int __init ide_setup (char *s) ...@@ -2949,12 +2961,12 @@ int __init ide_setup (char *s)
hwif->reset = 1; hwif->reset = 1;
goto done; goto done;
case -4: /* "noautotune" */ case -4: /* "noautotune" */
hwif->drives[0].autotune = 2; hwif->drives[0].autotune = IDE_TUNE_NOAUTO;
hwif->drives[1].autotune = 2; hwif->drives[1].autotune = IDE_TUNE_NOAUTO;
goto done; goto done;
case -3: /* "autotune" */ case -3: /* "autotune" */
hwif->drives[0].autotune = 1; hwif->drives[0].autotune = IDE_TUNE_AUTO;
hwif->drives[1].autotune = 1; hwif->drives[1].autotune = IDE_TUNE_AUTO;
goto done; goto done;
case -2: /* "serialize" */ case -2: /* "serialize" */
do_serialize: do_serialize:
...@@ -3211,7 +3223,8 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio ...@@ -3211,7 +3223,8 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio
spin_lock(&drives_lock); spin_lock(&drives_lock);
list_add(&drive->list, &driver->drives); list_add(&drive->list, &driver->drives);
spin_unlock(&drives_lock); spin_unlock(&drives_lock);
if (drive->autotune != 2) { if ((drive->autotune == IDE_TUNE_DEFAULT) ||
(drive->autotune == IDE_TUNE_AUTO)) {
/* DMA timings and setup moved to ide-probe.c */ /* DMA timings and setup moved to ide-probe.c */
if (!driver->supports_dma && HWIF(drive)->ide_dma_off_quietly) if (!driver->supports_dma && HWIF(drive)->ide_dma_off_quietly)
// HWIF(drive)->ide_dma_off_quietly(drive); // HWIF(drive)->ide_dma_off_quietly(drive);
......
...@@ -590,6 +590,7 @@ static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_ ...@@ -590,6 +590,7 @@ static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_
u32 port, at_least_one_hwif_enabled = 0, autodma = 0; u32 port, at_least_one_hwif_enabled = 0, autodma = 0;
int pciirq = 0; int pciirq = 0;
int tried_config = 0; int tried_config = 0;
int drive0_tune, drive1_tune;
ata_index_t index; ata_index_t index;
u8 tmp = 0; u8 tmp = 0;
ide_hwif_t *hwif, *mate = NULL; ide_hwif_t *hwif, *mate = NULL;
...@@ -698,11 +699,20 @@ static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_ ...@@ -698,11 +699,20 @@ static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_
ide_hwif_setup_dma(dev, d, hwif); ide_hwif_setup_dma(dev, d, hwif);
bypass_legacy_dma: bypass_legacy_dma:
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif /* CONFIG_BLK_DEV_IDEDMA */
drive0_tune = hwif->drives[0].autotune;
drive1_tune = hwif->drives[1].autotune;
if (d->init_hwif) if (d->init_hwif)
/* Call chipset-specific routine /* Call chipset-specific routine
* for each enabled hwif * for each enabled hwif
*/ */
d->init_hwif(hwif); d->init_hwif(hwif);
if (drive0_tune == IDE_TUNE_BIOS) /* biostimings */
hwif->drives[0].autotune = IDE_TUNE_BIOS;
if (drive1_tune == IDE_TUNE_BIOS)
hwif->drives[1].autotune = IDE_TUNE_BIOS;
mate = hwif; mate = hwif;
at_least_one_hwif_enabled = 1; at_least_one_hwif_enabled = 1;
......
...@@ -95,6 +95,14 @@ typedef unsigned char byte; /* used everywhere */ ...@@ -95,6 +95,14 @@ typedef unsigned char byte; /* used everywhere */
#define ERROR_RESET 3 /* Reset controller every 4th retry */ #define ERROR_RESET 3 /* Reset controller every 4th retry */
#define ERROR_RECAL 1 /* Recalibrate every 2nd retry */ #define ERROR_RECAL 1 /* Recalibrate every 2nd retry */
/*
* Tune flags
*/
#define IDE_TUNE_BIOS 3
#define IDE_TUNE_NOAUTO 2
#define IDE_TUNE_AUTO 1
#define IDE_TUNE_DEFAULT 0
/* /*
* state flags * state flags
*/ */
...@@ -743,7 +751,8 @@ typedef struct ide_drive_s { ...@@ -743,7 +751,8 @@ typedef struct ide_drive_s {
unsigned nice0 : 1; /* give obvious excess bandwidth */ unsigned nice0 : 1; /* give obvious excess bandwidth */
unsigned nice2 : 1; /* give a share in our own bandwidth */ unsigned nice2 : 1; /* give a share in our own bandwidth */
unsigned doorlocking : 1; /* for removable only: door lock/unlock works */ unsigned doorlocking : 1; /* for removable only: door lock/unlock works */
unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */ unsigned autotune : 3; /* 1=autotune, 2=noautotune,
3=biostimings, 0=default */
unsigned remap_0_to_1 : 2; /* 0=remap if ezdrive, 1=remap, 2=noremap */ unsigned remap_0_to_1 : 2; /* 0=remap if ezdrive, 1=remap, 2=noremap */
unsigned ata_flash : 1; /* 1=present, 0=default */ unsigned ata_flash : 1; /* 1=present, 0=default */
unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */ unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment