patch-2.0.37 linux/drivers/block/triton.c
Next file: linux/drivers/cdrom/sbpcd.c
Previous file: linux/drivers/block/proc_array.c
Back to the patch index
Back to the overall index
- Lines: 676
- Date:
Sun Jun 13 10:21:00 1999
- Orig file:
v2.0.36/linux/drivers/block/triton.c
- Orig date:
Sun Nov 15 10:49:32 1998
diff -u --recursive --new-file v2.0.36/linux/drivers/block/triton.c linux/drivers/block/triton.c
@@ -1,107 +1,18 @@
/*
* linux/drivers/block/triton.c Version 1.13 Aug 12, 1996
+ * Version 1.13a June 1998 - new chipsets
+ * Version 1.13b July 1998 - DMA blacklist
*
* Copyright (c) 1995-1996 Mark Lord
* May be copied or modified under the terms of the GNU General Public License
*/
/*
- * This module provides support for the Bus Master IDE DMA function
- * of the Intel PCI Triton I/II chipsets (i82371FB or i82371SB).
- *
- * Pretty much the same code will work for the OPTi "Viper" chipset.
- * Look for DMA support for this in linux kernel 2.1.xx, when it appears.
- *
- * DMA is currently supported only for hard disk drives (not cdroms).
- *
- * Support for cdroms will likely be added at a later date,
- * after broader experience has been obtained with hard disks.
- *
- * Up to four drives may be enabled for DMA, and the Triton chipset will
- * (hopefully) arbitrate the PCI bus among them. Note that the i82371 chip
- * provides a single "line buffer" for the BM IDE function, so performance of
- * multiple (two) drives doing DMA simultaneously will suffer somewhat,
- * as they contest for that resource bottleneck. This is handled transparently
- * inside the i82371 chip.
- *
- * By default, DMA support is prepared for use, but is currently enabled only
- * for drives which support multi-word DMA mode2 (mword2), or which are
- * recognized as "good" (see table below). Drives with only mode0 or mode1
- * (single or multi) DMA should also work with this chipset/driver (eg. MC2112A)
- * but are not enabled by default. Use "hdparm -i" to view modes supported
- * by a given drive.
- *
- * The hdparm-2.4 (or later) utility can be used for manually enabling/disabling
- * DMA support, but must be (re-)compiled against this kernel version or later.
- *
- * To enable DMA, use "hdparm -d1 /dev/hd?" on a per-drive basis after booting.
- * If problems arise, ide.c will disable DMA operation after a few retries.
- * This error recovery mechanism works and has been extremely well exercised.
- *
- * IDE drives, depending on their vintage, may support several different modes
- * of DMA operation. The boot-time modes are indicated with a "*" in
- * the "hdparm -i" listing, and can be changed with *knowledgeable* use of
- * the "hdparm -X" feature. There is seldom a need to do this, as drives
- * normally power-up with their "best" PIO/DMA modes enabled.
- *
- * Testing was done with an ASUS P55TP4XE/100 system and the following drives:
- *
- * Quantum Fireball 1080A (1Gig w/83kB buffer), DMA mode2, PIO mode4.
- * - DMA mode2 works well (7.4MB/sec), despite the tiny on-drive buffer.
- * - This drive also does PIO mode4, at about the same speed as DMA mode2.
- * An awesome drive for the price!
- *
- * Fujitsu M1606TA (1Gig w/256kB buffer), DMA mode2, PIO mode4.
- * - DMA mode2 gives horrible performance (1.6MB/sec), despite the good
- * size of the on-drive buffer and a boasted 10ms average access time.
- * - PIO mode4 was better, but peaked at a mere 4.5MB/sec.
- *
- * Micropolis MC2112A (1Gig w/508kB buffer), drive pre-dates EIDE and ATA2.
- * - DMA works fine (2.2MB/sec), probably due to the large on-drive buffer.
- * - This older drive can also be tweaked for fastPIO (3.7MB/sec) by using
- * maximum clock settings (5,4) and setting all flags except prefetch.
- *
- * Western Digital AC31000H (1Gig w/128kB buffer), DMA mode1, PIO mode3.
- * - DMA does not work reliably. The drive appears to be somewhat tardy
- * in deasserting DMARQ at the end of a sector. This is evident in
- * the observation that WRITEs work most of the time, depending on
- * cache-buffer occupancy, but multi-sector reads seldom work.
- *
- * Testing was done with a Gigabyte GA-586 ATE system and the following drive:
- * (Uwe Bonnes - bon@elektron.ikp.physik.th-darmstadt.de)
- *
- * Western Digital AC31600H (1.6Gig w/128kB buffer), DMA mode2, PIO mode4.
- * - much better than its 1Gig cousin, this drive is reported to work
- * very well with DMA (7.3MB/sec).
- *
- * Other drives:
- *
- * Maxtor 7540AV (515Meg w/32kB buffer), DMA modes mword0/sword2, PIO mode3.
- * - a budget drive, with budget performance, around 3MB/sec.
- *
- * Western Digital AC2850F (814Meg w/64kB buffer), DMA mode1, PIO mode3.
- * - another "caviar" drive, similar to the AC31000, except that this one
- * worked with DMA in at least one system. Throughput is about 3.8MB/sec
- * for both DMA and PIO.
- *
- * Conner CFS850A (812Meg w/64kB buffer), DMA mode2, PIO mode4.
- * - like most Conner models, this drive proves that even a fast interface
- * cannot improve slow media. Both DMA and PIO peak around 3.5MB/sec.
- *
- * Maxtor 71260AT (1204Meg w/256kB buffer), DMA mword0/sword2, PIO mode3.
- * - works with DMA, on some systems (but not always on others, eg. Dell),
- * giving 3-4MB/sec performance, about the same as mode3.
- *
- * If you have any drive models to add, email your results to: mlord@pobox.com
- * Keep an eye on /var/adm/messages for "DMA disabled" messages.
- *
- * Some people have reported trouble with Intel Zappa motherboards.
- * This can be fixed by upgrading the AMI BIOS to version 1.00.04.BS0,
- * available from ftp://ftp.intel.com/pub/bios/10004bs0.exe
- * (thanks to Glen Morrell <glen@spin.Stanford.edu> for researching this).
- *
- * And, yes, Intel Zappa boards really *do* use the Triton IDE ports.
+ * This module provides support for Bus Master IDE DMA functions in various
+ * motherboard chipsets and PCI controller cards.
+ * Please check /Documentation/ide.txt and /Documentation/udma.txt for details.
*/
+
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -120,6 +31,13 @@
#include "ide.h"
#undef DISPLAY_TRITON_TIMINGS /* define this to display timings */
+#undef DISPLAY_APOLLO_TIMINGS /* define this for extensive debugging information */
+
+#if defined(CONFIG_PROC_FS) && defined(DISPLAY_APOLLO_TIMINGS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+#include <linux/via_ide_dma.h>
+#endif
/*
* good_dma_drives() lists the model names (from "hdparm -i")
@@ -132,6 +50,27 @@
NULL};
/*
+ * bad_dma_drives() lists the model names (from "hdparm -i")
+ * of drives which supposedly support (U)DMA but which are
+ * known to corrupt data with this interface under Linux.
+ *
+ * Note: the list was generated by statistical analysis of problem
+ * reports. It's not clear if there are problems with the drives,
+ * or with some combination of drive/controller or what.
+ *
+ * You can forcibly override this if you wish. This is the kernel
+ * 'Tread carefully' list.
+ *
+ * Finally see http://www.wdc.com/quality/err-rec.html if you have
+ * one of the listed drives.
+ */
+const char *bad_dma_drives[] = {"WDC AC11000H",
+ "WDC AC22100H",
+ "WDC AC32500H",
+ "WDC AC33100H",
+ NULL};
+
+/*
* Our Physical Region Descriptor (PRD) table should be large enough
* to handle the biggest I/O request we are likely to see. Since requests
* can have no more than 256 sectors, and since the typical blocksize is
@@ -150,6 +89,7 @@
#define PRD_BYTES 8
#define PRD_ENTRIES (PAGE_SIZE / (2 * PRD_BYTES))
#define DEFAULT_BMIBA 0xe800 /* in case BIOS did not init it */
+#define DEFAULT_BMCRBA 0xcc00 /* VIA's default value */
/*
* dma_intr() is the handler for disk read/write DMA interrupts
@@ -161,8 +101,8 @@
struct request *rq = HWGROUP(drive)->rq;
unsigned short dma_base = HWIF(drive)->dma_base;
- dma_stat = inb(dma_base+2); /* get DMA status */
outb(inb(dma_base)&~1, dma_base); /* stop DMA operation */
+ dma_stat = inb(dma_base+2); /* get DMA status */
stat = GET_STAT(); /* get drive status */
if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
if ((dma_stat & 7) == 4) { /* verify good DMA status */
@@ -244,23 +184,37 @@
return 1; /* let the PIO routines handle this weirdness */
}
+/*
+ * We will only enable drives with multi-word (mode2) (U)DMA capabilities,
+ * and ignore the very rare cases of drives that can only do single-word
+ * (modes 0 & 1) (U)DMA transfers. We also discard "blacklisted" hard disks.
+ */
static int config_drive_for_dma (ide_drive_t *drive)
{
const char **list;
struct hd_driveid *id = drive->id;
if (id && (id->capability & 1)) {
- /* Enable DMA on any drive that has UltraDMA (mode 0/1/2) enabled */
+ /* Consult the list of known "bad" drives */
+ list = bad_dma_drives;
+ while (*list) {
+ if (!strcmp(*list++,id->model)) {
+ drive->using_dma = 0; /* no DMA */
+ printk("ide: Disabling DMA modes on %s drive (%s).\n", drive->name, id->model);
+ return 1; /* DMA disabled */
+ }
+ }
+ /* Enable DMA on any drive that has mode 2 UltraDMA enabled */
if (id->field_valid & 4) /* UltraDMA */
- if ((id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
+ if ((id->dma_ultra & 0x404) == 0x404) {
drive->using_dma = 1;
- return 0; /* dma enabled */
+ return 0; /* DMA enabled */
}
- /* Enable DMA on any drive that has mode2 DMA (multi or single) enabled */
+ /* Enable DMA on any drive that has mode2 DMA enabled */
if (id->field_valid & 2) /* regular DMA */
- if ((id->dma_mword & 0x404) == 0x404 || (id->dma_1word & 0x404) == 0x404) {
+ if ((id->dma_mword & 0x404) == 0x404) {
drive->using_dma = 1;
- return 0; /* dma enabled */
+ return 0; /* DMA enabled */
}
/* Consult the list of known "good" drives */
list = good_dma_drives;
@@ -387,22 +341,135 @@
}
/*
+ * Set VIA Chipset Timings for (U)DMA modes enabled.
+ */
+static int set_via_timings (byte bus, byte fn, byte post, byte flush)
+{
+ byte via_config = 0;
+ int rc = 0;
+
+ /* setting IDE read prefetch buffer and IDE post write buffer */
+ if ((rc = pcibios_read_config_byte(bus, fn, 0x41, &via_config)))
+ return (1);
+ if ((rc = pcibios_write_config_byte(bus, fn, 0x41, via_config | post)))
+ return (1);
+
+ /* setting Channel read and End-of-sector FIFO flush: */
+ if ((rc = pcibios_read_config_byte(bus, fn, 0x46, &via_config)))
+ return (1);
+ if ((rc = pcibios_write_config_byte(bus, fn, 0x46, via_config | flush)))
+ return (1);
+
+ return (0);
+}
+
+/*
* ide_init_triton() prepares the IDE driver for DMA operation.
* This routine is called once, from ide.c during driver initialization,
- * for each triton chipset which is found (unlikely to be more than one).
+ * for each BM-DMA chipset which is found (rarely more than one).
*/
void ide_init_triton (byte bus, byte fn)
{
int rc = 0, h;
int dma_enabled = 0;
- unsigned short pcicmd;
- unsigned int bmiba, timings;
+ unsigned short io[6], count = 0, step_count = 0;
+ unsigned short pcicmd, vendor, device, class;
+ unsigned int bmiba, timings, reg, tmp;
+ unsigned int addressbios = 0;
+
+#ifdef DISPLAY_APOLLO_TIMINGS
+ bmide_bus = bus;
+ bmide_fn = fn;
+#endif /* DISPLAY_APOLLO_TIMINGS */
+
+/*
+ * We pick up the vendor, device, and class info for selecting the correct
+ * controller that is supported. Since we can access this routine more than
+ * once with the use of onboard and off-board EIDE controllers, a method
+ * of determining "who is who for what" is needed.
+ */
+
+ pcibios_read_config_word (bus, fn, PCI_VENDOR_ID, &vendor);
+ pcibios_read_config_word (bus, fn, PCI_DEVICE_ID, &device);
+ pcibios_read_config_word (bus, fn, PCI_CLASS_DEVICE, &class);
+
+ switch(vendor) {
+ case PCI_VENDOR_ID_INTEL:
+ printk("ide: Intel 82371 (single FIFO) DMA Bus Mastering IDE ");
+ break;
+ case PCI_VENDOR_ID_SI:
+ printk("ide: SiS 5513 (dual FIFO) DMA Bus Mastering IDE ");
+ break;
+ case PCI_VENDOR_ID_VIA:
+ printk("ide: VIA VT82C586B (split FIFO) UDMA Bus Mastering IDE ");
+ break;
+ case PCI_VENDOR_ID_PROMISE:
+ /* PCI_CLASS_STORAGE_RAID == class */
+ /*
+ * I have been able to make my Promise Ultra33 UDMA card change class.
+ * It has reported as both PCI_CLASS_STORAGE_RAID and PCI_CLASS_STORAGE_IDE.
+ * Since the PCI_CLASS_STORAGE_RAID mode should automatically mirror the
+ * two halves of the PCI_CONFIG register data, but sometimes it forgets.
+ * Thus we guarantee that they are identical, with a quick check and
+ * correction if needed.
+ * PDC20246 (primary) PDC20247 (secondary) IDE hwif's.
+ *
+ * Note that Promise "stories,fibs,..." about this device not being
+ * capable of ATAPI and AT devices.
+ */
+ if (PCI_CLASS_STORAGE_RAID == class) {
+ unsigned char irq1 = 0, irq2 = 0;
+ pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &irq1);
+ pcibios_read_config_byte (bus, fn, (PCI_INTERRUPT_LINE)|0x80, &irq2);
+ if (irq1 != irq2) {
+ pcibios_write_config_byte(bus, fn, (PCI_INTERRUPT_LINE)|0x80, irq1);
+ }
+ }
+ case PCI_VENDOR_ID_ARTOP:
+ /* PCI_CLASS_STORAGE_SCSI == class */
+ /*
+ * I have found that by stroking rom_enable_bit on both the AEC6210U/UF and
+ * PDC20246 controller cards, the features desired are almost guaranteed
+ * to be enabled and compatible. This ROM may not be registered in the
+ * config data, but it can be turned on. Registration failure has only
+ * been observed if and only if Linux sets up the pci_io_address in the
+ * 0x6000 range. If they are setup in the 0xef00 range it is reported.
+ * WHY??? got me.........
+ */
+ printk("ide: %s UDMA Bus Mastering ",
+ (vendor == PCI_VENDOR_ID_ARTOP) ? "AEC6210" : "PDC20246");
+ pcibios_read_config_dword(bus, fn, PCI_ROM_ADDRESS, &addressbios);
+ if (addressbios) {
+ pcibios_write_config_byte(bus, fn, PCI_ROM_ADDRESS, addressbios | PCI_ROM_ADDRESS_ENABLE);
+ printk("with ROM enabled at 0x%08x", addressbios);
+ }
+ /*
+ * This was stripped out of 2.1.XXX kernel code and parts from a patch called
+ * promise_update. This finds the PCI_BASE_ADDRESS spaces and makes them
+ * available for configuration later.
+ * PCI_BASE_ADDRESS_0 hwif0->io_base
+ * PCI_BASE_ADDRESS_1 hwif0->ctl_port
+ * PCI_BASE_ADDRESS_2 hwif1->io_base
+ * PCI_BASE_ADDRESS_3 hwif1->ctl_port
+ * PCI_BASE_ADDRESS_4 bmiba
+ */
+ memset(io, 0, 6 * sizeof(unsigned short));
+ for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
+ pcibios_read_config_dword(bus, fn, reg, &tmp);
+ if (tmp & PCI_BASE_ADDRESS_SPACE_IO)
+ io[count++] = tmp & PCI_BASE_ADDRESS_IO_MASK;
+ }
+ break;
+ default:
+ return;
+ }
+
+ printk("\n Controller on PCI bus %d function %d\n", bus, fn);
- printk("ide: i82371 PIIX (Triton) on PCI bus %d function %d\n", bus, fn);
/*
* See if IDE and BM-DMA features are enabled:
*/
- if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)))
+ if ((rc = pcibios_read_config_word(bus, fn, PCI_COMMAND, &pcicmd)))
goto quit;
if ((pcicmd & 1) == 0) {
printk("ide: ports are not enabled (BIOS)\n");
@@ -416,21 +483,21 @@
*/
int try_again = 1;
do {
- if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba)))
+ if ((rc = pcibios_read_config_dword(bus, fn, PCI_BASE_ADDRESS_4, &bmiba)))
goto quit;
bmiba &= 0xfff0; /* extract port base address */
if (bmiba) {
dma_enabled = 1;
break;
} else {
- printk("ide: BM-DMA base register is invalid (0x%04x, PnP BIOS problem)\n", bmiba);
- if (inb(DEFAULT_BMIBA) != 0xff || !try_again)
+ printk("ide: BM-DMA base register is invalid (0x%04x, PnP BIOS problem)\n", bmiba);
+ if (inb(((vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA : DEFAULT_BMIBA)) != 0xff || !try_again)
break;
- printk("ide: setting BM-DMA base register to 0x%04x\n", DEFAULT_BMIBA);
- if ((rc = pcibios_write_config_word(bus, fn, 0x04, pcicmd&~1)))
+ printk("ide: setting BM-DMA base register to 0x%04x\n", ((vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA : DEFAULT_BMIBA));
+ if ((rc = pcibios_write_config_word(bus, fn, PCI_COMMAND, pcicmd&~1)))
goto quit;
- rc = pcibios_write_config_dword(bus, fn, 0x20, DEFAULT_BMIBA|1);
- if (pcibios_write_config_word(bus, fn, 0x04, pcicmd|5) || rc)
+ rc = pcibios_write_config_dword(bus, fn, 0x20, ((vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA : DEFAULT_BMIBA)|1);
+ if (pcibios_write_config_word(bus, fn, PCI_COMMAND, pcicmd|5) || rc)
goto quit;
}
} while (try_again--);
@@ -439,89 +506,218 @@
/*
* See if ide port(s) are enabled
*/
- if ((rc = pcibios_read_config_dword(bus, fn, 0x40, &timings)))
- goto quit;
- if (!(timings & 0x80008000)) {
- printk("ide: neither port is enabled\n");
+ if ((rc = pcibios_read_config_dword(bus, fn,
+ (vendor == PCI_VENDOR_ID_PROMISE) ? 0x50 :
+ (vendor == PCI_VENDOR_ID_ARTOP) ? 0x54 :
+ 0x40, &timings)))
goto quit;
- }
+ /*
+ * We do a vendor check since the Ultra33 and AEC6210
+ * holds their timings in a different location.
+ */
+ printk("ide: timings == %08x\n", timings);
+
+ /*
+ * The switch preserves some stuff that was original.
+ */
+ switch(vendor) {
+ case PCI_VENDOR_ID_INTEL:
+ if (!(timings & 0x80008000)) {
+ printk("ide: INTEL: neither port is enabled\n");
+ goto quit;
+ }
+ break;
+ case PCI_VENDOR_ID_VIA:
+ if(!(timings & 0x03)) {
+ printk("ide: VIA: neither port is enabled\n");
+ goto quit;
+ }
+ break;
+ case PCI_VENDOR_ID_SI:
+ case PCI_VENDOR_ID_PROMISE:
+ case PCI_VENDOR_ID_ARTOP:
+ default:
+ break;
+ }
/*
* Save the dma_base port addr for each interface
*/
for (h = 0; h < MAX_HWIFS; ++h) {
+ ide_hwif_t *hwif = &ide_hwifs[h];
+
+ /*
+ * This prevents the first contoller from accidentally
+ * initalizing the hwif's that it does not use and block
+ * an off-board ide-pci from getting in the game.
+ */
+ if (step_count >= 2) {
+ goto quit;
+ }
+#ifdef CONFIG_BLK_DEV_OFFBOARD
+ /*
+ * This is a forced override for the onboard ide controller
+ * to be enabled, if one chooses to have an offboard ide-pci
+ * card as the primary booting device. This beasty is
+ * for offboard UDMA upgrades with hard disks, but saving
+ * the onboard DMA2 controllers for CDROMS, TAPES, ZIPS, etc...
+ */
+ if ((vendor == PCI_VENDOR_ID_INTEL) ||
+ (vendor == PCI_VENDOR_ID_SI) ||
+ (vendor == PCI_VENDOR_ID_VIA)) {
+ if (h == 2) {
+ hwif->io_base = 0x1f0;
+ hwif->ctl_port = 0x3f6;
+ hwif->irq = 14;
+ hwif->noprobe = 0;
+ }
+ if (h == 3) {
+ hwif->io_base = 0x170;
+ hwif->ctl_port = 0x376;
+ hwif->irq = 15;
+ hwif->noprobe = 0;
+ }
+ }
+#endif /* CONFIG_BLK_DEV_OFFBOARD */
+ /*
+ * If the chipset is listed as "ide_unknown", lets get a
+ * hwif while they last. This does the first check on
+ * the current availability of the ide_hwifs[h] in question.
+ */
+ if (hwif->chipset != ide_unknown) {
+ continue;
+ } else if (vendor == PCI_VENDOR_ID_INTEL) {
+ unsigned short time;
#ifdef DISPLAY_TRITON_TIMINGS
- byte s_clks, r_clks;
- unsigned short devid;
+ byte s_clks, r_clks;
+ unsigned short devid;
#endif /* DISPLAY_TRITON_TIMINGS */
- ide_hwif_t *hwif = &ide_hwifs[h];
- unsigned short time;
- if (hwif->io_base == 0x1f0) {
- time = timings & 0xffff;
- if ((time & 0x8000) == 0) /* interface enabled? */
- continue;
- hwif->chipset = ide_triton;
- if (dma_enabled)
- init_triton_dma(hwif, bmiba);
- } else if (hwif->io_base == 0x170) {
- time = timings >> 16;
- if ((time & 0x8000) == 0) /* interface enabled? */
+ if (hwif->io_base == 0x1f0) {
+ time = timings & 0xffff;
+ if ((time & 0x8000) == 0) /* interface enabled? */
+ continue;
+ hwif->chipset = ide_triton;
+ if (dma_enabled)
+ init_triton_dma(hwif, bmiba);
+ step_count++;
+ } else if (hwif->io_base == 0x170) {
+ time = timings >> 16;
+ if ((time & 0x8000) == 0) /* interface enabled? */
+ continue;
+ hwif->chipset = ide_triton;
+ if (dma_enabled)
+ init_triton_dma(hwif, bmiba + 8);
+ step_count++;
+ } else {
continue;
- hwif->chipset = ide_triton;
- if (dma_enabled)
- init_triton_dma(hwif, bmiba + 8);
- } else
- continue;
+ }
#ifdef DISPLAY_TRITON_TIMINGS
- s_clks = ((~time >> 12) & 3) + 2;
- r_clks = ((~time >> 8) & 3) + 1;
- printk(" %s timing: (0x%04x) sample_CLKs=%d, recovery_CLKs=%d\n",
- hwif->name, time, s_clks, r_clks);
- if ((time & 0x40) && !pcibios_read_config_word(bus, fn, 0x02, &devid)
- && devid == PCI_DEVICE_ID_INTEL_82371SB_1)
- {
- byte stime;
- if (pcibios_read_config_byte(bus, fn, 0x44, &stime)) {
- if (hwif->io_base == 0x1f0) {
- s_clks = ~stime >> 6;
- r_clks = ~stime >> 4;
+ s_clks = ((~time >> 12) & 3) + 2;
+ r_clks = ((~time >> 8) & 3) + 1;
+ printk(" %s timing: (0x%04x) sample_CLKs=%d, recovery_CLKs=%d\n",
+ hwif->name, time, s_clks, r_clks);
+ if ((time & 0x40) && !pcibios_read_config_word(bus, fn, PCI_DEVICE_ID, &devid)
+ && devid == PCI_DEVICE_ID_INTEL_82371SB_1) {
+ byte stime;
+ if (pcibios_read_config_byte(bus, fn, 0x44, &stime)) {
+ if (hwif->io_base == 0x1f0) {
+ s_clks = ~stime >> 6;
+ r_clks = ~stime >> 4;
+ } else {
+ s_clks = ~stime >> 2;
+ r_clks = ~stime;
+ }
+ s_clks = (s_clks & 3) + 2;
+ r_clks = (r_clks & 3) + 1;
+ printk(" slave: sample_CLKs=%d, recovery_CLKs=%d\n",
+ s_clks, r_clks);
+ }
+ }
+ print_triton_drive_flags (0, time & 0xf);
+ print_triton_drive_flags (1, (time >> 4) & 0xf);
+#endif /* DISPLAY_TRITON_TIMINGS */
+ } else if (vendor == PCI_VENDOR_ID_SI) {
+ if (hwif->io_base == 0x1f0) {
+ hwif->chipset = ide_triton;
+ if (dma_enabled)
+ init_triton_dma(hwif, bmiba);
+ step_count++;
+ } else if (hwif->io_base == 0x170) {
+ hwif->chipset = ide_triton;
+ if (dma_enabled)
+ init_triton_dma(hwif, bmiba + 8);
+ step_count++;
+ } else {
+ continue;
+ }
+ } else if(vendor == PCI_VENDOR_ID_VIA) {
+ if (hwif->io_base == 0x1f0) {
+ if((timings & 0x02) == 0)
+ continue;
+ hwif->chipset = ide_triton;
+ if (dma_enabled)
+ init_triton_dma(hwif, bmiba);
+ if (set_via_timings(bus, fn, 0xc0, 0xa0))
+ goto quit;
+#ifdef DISPLAY_APOLLO_TIMINGS
+ proc_register_dynamic(&proc_root, &via_proc_entry);
+#endif /* DISPLAY_APOLLO_TIMINGS */
+ step_count++;
+ } else if (hwif->io_base == 0x170) {
+ if((timings & 0x01) == 0)
+ continue;
+ hwif->chipset = ide_triton;
+ if (dma_enabled)
+ init_triton_dma(hwif, bmiba + 8);
+ if (set_via_timings(bus, fn, 0x30, 0x50))
+ goto quit;
+ step_count++;
+ } else {
+ continue;
+ }
+ } else if ((vendor == PCI_VENDOR_ID_PROMISE) ||
+ (vendor == PCI_VENDOR_ID_ARTOP)) {
+ /*
+ * This silly tmp = h routine allows an off-board ide-pci card to
+ * be booted as primary hwifgroup, provided that the onboard
+ * controllers are disabled. If they are active, then we wait our
+ * turn for hwif assignment.
+ */
+ unsigned char irq = 0;
+ pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &irq);
+ if ((h == 0) || (h == 1)) {
+ tmp = h * 2;
+ } else {
+ tmp = (h - 2) * 2;
+ }
+ hwif->io_base = io[tmp];
+ hwif->ctl_port = io[tmp + 1] + 2;
+ hwif->irq = irq;
+ hwif->noprobe = 0;
+
+ if (vendor == PCI_VENDOR_ID_ARTOP) {
+ hwif->serialized = 1;
+ }
+
+ if (dma_enabled) {
+ if (!check_region(bmiba, 8)) {
+ hwif->chipset = ide_udma;
+ init_triton_dma(hwif, bmiba);
+ step_count++;
+ } else if (!check_region((bmiba + 0x08), 8)) {
+ if ((vendor == PCI_VENDOR_ID_PROMISE) &&
+ (!check_region(bmiba+16, 16))) {
+ request_region(bmiba+16, 16, "PDC20246");
+ }
+ hwif->chipset = ide_udma;
+ init_triton_dma(hwif, bmiba + 8);
+ step_count++;
} else {
- s_clks = ~stime >> 2;
- r_clks = ~stime;
+ continue;
}
- s_clks = (s_clks & 3) + 2;
- r_clks = (r_clks & 3) + 1;
- printk(" slave: sample_CLKs=%d, recovery_CLKs=%d\n",
- s_clks, r_clks);
}
}
- print_triton_drive_flags (0, time & 0xf);
- print_triton_drive_flags (1, (time >> 4) & 0xf);
-#endif /* DISPLAY_TRITON_TIMINGS */
}
-quit: if (rc) printk("ide: pcibios access failed - %s\n", pcibios_strerror(rc));
-}
-
-void ide_init_promise (byte bus, byte fn, ide_hwif_t *hwif0, ide_hwif_t *hwif1, unsigned short dma)
-{
- int rc;
- unsigned short pcicmd;
- unsigned int bmiba = 0;
-
- printk("ide: Enabling DMA for Promise Technology IDE Ultra-DMA 33 on PCI bus %d function %d, port 0x%04x\n", bus, fn, dma);
- if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)) || (pcicmd & 1) == 0 || (pcicmd & 4) == 0)
- goto abort;
- if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba)))
- goto abort;
- bmiba &= 0xfff0; /* extract port base address */
- if (bmiba != dma || !bmiba)
- goto abort;
- hwif0->chipset = ide_promise_udma;
- hwif1->chipset = ide_promise_udma;
- init_triton_dma(hwif0, bmiba);
- init_triton_dma(hwif1, bmiba + 0x08);
- return;
-abort:
- printk(KERN_WARNING "ide: Promise/33 not configured correctly (BIOS)\n");
+ quit: if (rc) printk("ide: pcibios access failed - %s\n", pcibios_strerror(rc));
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov