diff options
author | Thomas Bushnell <thomas@gnu.org> | 1999-04-26 05:58:44 +0000 |
---|---|---|
committer | Thomas Bushnell <thomas@gnu.org> | 1999-04-26 05:58:44 +0000 |
commit | 86297c41a26f18d924e64fc93321c59cbc4c48dd (patch) | |
tree | 376954c6b95b735d361875319a1a2a9db6a27527 /linux/src/drivers/block/ide_modes.h | |
parent | 851137902d3e7ad87af177487df3eea53e940a1c (diff) | |
download | gnumach-86297c41a26f18d924e64fc93321c59cbc4c48dd.tar.gz gnumach-86297c41a26f18d924e64fc93321c59cbc4c48dd.tar.bz2 gnumach-86297c41a26f18d924e64fc93321c59cbc4c48dd.zip |
1998-11-30 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
Clean up linux emulation code to make it architecture-independent
as much as possible.
* linux: Renamed from linuxdev.
* Makefile.in (objfiles): Add linux.o instead of linuxdev.o.
(MAKE): New variable. Used for the linux.o target.
* configure.in: Add AC_CHECK_TOOL(MAKE, make).
* i386/i386/spl.h: Include <i386/ipl.h>, for compatibility with
OSF Mach 3.0. Suggested by Elgin Lee <ehl@funghi.com>.
* linux/src: Renamed from linux/linux.
* linux/dev: Renamed from linux/mach.
* linux/Drivers.in (AC_INIT): Use dev/include/linux/autoconf.h,
instead of mach/include/linux/autoconf.h.
* Makefile.in (all): Target ../linux.o instead of ../linuxdev.o.
* linux/dev/drivers/block/genhd.c: Include <machine/spl.h> instead
of <i386/ipl.h>.
* linux/dev/drivers/net/auto_irq.c: Remove unneeded header files,
<i386/ipl.h> and <i386/pic.h>.
* linux/dev/init/main.c: Many i386-dependent codes moved to ...
* linux/dev/arch/i386/irq.c: ... here.
* linux/dev/arch/i386/setup.c: New file.
* linux/dev/arch/i386/linux_emul.h: Likewise.
* linux/dev/arch/i386/glue/timer.c: Merged into sched.c.
* linux/dev/arch/i386/glue/sched.c: Include <machine/spl.h> instead
of <i386/ipl.h>, and moved to ...
* linux/dev/kernel/sched.c: ... here.
* linux/dev/arch/i386/glue/block.c: Include <machine/spl.h> and
<linux_emul.h>, instead of i386-dependent header files, and
moved to ...
* linux/dev/glue/blocl.c: ... here.
* linux/dev/arch/i386/glue/net.c: Include <machine/spl.h> and
<linux_emul.h>, instead of i386-dependent header files, and
moved to ...
* linux/dev/glue/net.c: ... here.
* linux/dev/arch/i386/glue/misc.c: Remove `x86' and moved to ...
* linux/dev/glue/misc.c: ... here.
* linux/dev/arch/i386/glue/kmem.c: Moved to ...
* linux/dev/glue/kmem.c: ... here.
Diffstat (limited to 'linux/src/drivers/block/ide_modes.h')
-rw-r--r-- | linux/src/drivers/block/ide_modes.h | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/linux/src/drivers/block/ide_modes.h b/linux/src/drivers/block/ide_modes.h new file mode 100644 index 00000000..589fbfaa --- /dev/null +++ b/linux/src/drivers/block/ide_modes.h @@ -0,0 +1,226 @@ +#ifndef _IDE_MODES_H +#define _IDE_MODES_H +/* + * linux/drivers/block/ide_modes.h + * + * Copyright (C) 1996 Linus Torvalds, Igor Abramov, and Mark Lord + */ + +#include <linux/config.h> + +/* + * Shared data/functions for determining best PIO mode for an IDE drive. + * Most of this stuff originally lived in cmd640.c, and changes to the + * ide_pio_blacklist[] table should be made with EXTREME CAUTION to avoid + * breaking the fragile cmd640.c support. + */ + +#if defined(CONFIG_BLK_DEV_CMD640) || defined(CONFIG_IDE_CHIPSETS) + +/* + * Standard (generic) timings for PIO modes, from ATA2 specification. + * These timings are for access to the IDE data port register *only*. + * Some drives may specify a mode, while also specifying a different + * value for cycle_time (from drive identification data). + */ +typedef struct ide_pio_timings_s { + int setup_time; /* Address setup (ns) minimum */ + int active_time; /* Active pulse (ns) minimum */ + int cycle_time; /* Cycle time (ns) minimum = (setup + active + recovery) */ +} ide_pio_timings_t; + +typedef struct ide_pio_data_s { + byte pio_mode; + byte use_iordy; + byte overridden; + byte blacklisted; + unsigned int cycle_time; +} ide_pio_data_t; + +#ifndef _IDE_C + +int ide_scan_pio_blacklist (char *model); +byte ide_get_best_pio_mode (ide_drive_t *drive, byte mode_wanted, byte max_mode, ide_pio_data_t *d); +extern const ide_pio_timings_t ide_pio_timings[6]; + +#else /* _IDE_C */ + +const ide_pio_timings_t ide_pio_timings[6] = { + { 70, 165, 600 }, /* PIO Mode 0 */ + { 50, 125, 383 }, /* PIO Mode 1 */ + { 30, 100, 240 }, /* PIO Mode 2 */ + { 30, 80, 180 }, /* PIO Mode 3 with IORDY */ + { 25, 70, 120 }, /* PIO Mode 4 with IORDY */ + { 20, 50, 100 } /* PIO Mode 5 with IORDY (nonstandard) */ +}; + +/* + * Black list. Some drives incorrectly report their maximal PIO mode, + * at least in respect to CMD640. Here we keep info on some known drives. + */ +static struct ide_pio_info { + const char *name; + int pio; +} ide_pio_blacklist [] = { +/* { "Conner Peripherals 1275MB - CFS1275A", 4 }, */ + { "Conner Peripherals 540MB - CFS540A", 3 }, + + { "WDC AC2700", 3 }, + { "WDC AC2540", 3 }, + { "WDC AC2420", 3 }, + { "WDC AC2340", 3 }, + { "WDC AC2250", 0 }, + { "WDC AC2200", 0 }, + { "WDC AC21200", 4 }, + { "WDC AC2120", 0 }, + { "WDC AC2850", 3 }, + { "WDC AC1270", 3 }, + { "WDC AC1170", 1 }, + { "WDC AC1210", 1 }, + { "WDC AC280", 0 }, +/* { "WDC AC21000", 4 }, */ + { "WDC AC31000", 3 }, + { "WDC AC31200", 3 }, +/* { "WDC AC31600", 4 }, */ + + { "Maxtor 7131 AT", 1 }, + { "Maxtor 7171 AT", 1 }, + { "Maxtor 7213 AT", 1 }, + { "Maxtor 7245 AT", 1 }, + { "Maxtor 7345 AT", 1 }, + { "Maxtor 7546 AT", 3 }, + { "Maxtor 7540 AV", 3 }, + + { "SAMSUNG SHD-3121A", 1 }, + { "SAMSUNG SHD-3122A", 1 }, + { "SAMSUNG SHD-3172A", 1 }, + +/* { "ST51080A", 4 }, + * { "ST51270A", 4 }, + * { "ST31220A", 4 }, + * { "ST31640A", 4 }, + * { "ST32140A", 4 }, + * { "ST3780A", 4 }, + */ + { "ST5660A", 3 }, + { "ST3660A", 3 }, + { "ST3630A", 3 }, + { "ST3655A", 3 }, + { "ST3391A", 3 }, + { "ST3390A", 1 }, + { "ST3600A", 1 }, + { "ST3290A", 0 }, + { "ST3144A", 0 }, + + { "QUANTUM ELS127A", 0 }, + { "QUANTUM ELS170A", 0 }, + { "QUANTUM LPS240A", 0 }, + { "QUANTUM LPS210A", 3 }, + { "QUANTUM LPS270A", 3 }, + { "QUANTUM LPS365A", 3 }, + { "QUANTUM LPS540A", 3 }, + { "QUANTUM LIGHTNING 540A", 3 }, + { "QUANTUM LIGHTNING 730A", 3 }, + { "QUANTUM FIREBALL", 3 }, /* For models 540/640/1080/1280 */ + /* 1080A works fine in mode4 with triton */ + { NULL, 0 } +}; + +/* + * This routine searches the ide_pio_blacklist for an entry + * matching the start/whole of the supplied model name. + * + * Returns -1 if no match found. + * Otherwise returns the recommended PIO mode from ide_pio_blacklist[]. + */ +int ide_scan_pio_blacklist (char *model) +{ + struct ide_pio_info *p; + + for (p = ide_pio_blacklist; p->name != NULL; p++) { + if (strncmp(p->name, model, strlen(p->name)) == 0) + return p->pio; + } + return -1; +} + +/* + * This routine returns the recommended PIO settings for a given drive, + * based on the drive->id information and the ide_pio_blacklist[]. + * This is used by most chipset support modules when "auto-tuning". + */ + +/* + * Drive PIO mode auto selection + */ +byte ide_get_best_pio_mode (ide_drive_t *drive, byte mode_wanted, byte max_mode, ide_pio_data_t *d) +{ + int pio_mode; + int cycle_time = 0; + int use_iordy = 0; + struct hd_driveid* id = drive->id; + int overridden = 0; + int blacklisted = 0; + + if (mode_wanted != 255) { + pio_mode = mode_wanted; + } else if (!drive->id) { + pio_mode = 0; + } else if ((pio_mode = ide_scan_pio_blacklist(id->model)) != -1) { + overridden = 1; + blacklisted = 1; + use_iordy = (pio_mode > 2); + } else { + pio_mode = id->tPIO; + if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */ + pio_mode = 2; + overridden = 1; + } + if (id->field_valid & 2) { /* drive implements ATA2? */ + if (id->capability & 8) { /* drive supports use_iordy? */ + use_iordy = 1; + cycle_time = id->eide_pio_iordy; + if (id->eide_pio_modes & 7) { + overridden = 0; + if (id->eide_pio_modes & 4) + pio_mode = 5; + else if (id->eide_pio_modes & 2) + pio_mode = 4; + else + pio_mode = 3; + } + } else { + cycle_time = id->eide_pio; + } + } + + /* + * Conservative "downgrade" for all pre-ATA2 drives + */ + if (pio_mode && pio_mode < 4) { + pio_mode--; + overridden = 1; +#if 0 + use_iordy = (pio_mode > 2); +#endif + if (cycle_time && cycle_time < ide_pio_timings[pio_mode].cycle_time) + cycle_time = 0; /* use standard timing */ + } + } + if (pio_mode > max_mode) { + pio_mode = max_mode; + cycle_time = 0; + } + if (d) { + d->pio_mode = pio_mode; + d->cycle_time = cycle_time ? cycle_time : ide_pio_timings[pio_mode].cycle_time; + d->use_iordy = use_iordy; + d->overridden = overridden; + d->blacklisted = blacklisted; + } + return pio_mode; +} + +#endif /* _IDE_C */ +#endif /* defined(CONFIG_BLK_DEV_CMD640) || defined(CONFIG_IDE_CHIPSETS) */ +#endif /* _IDE_MODES_H */ |