patch-2.1.24 linux/drivers/block/triton.c
Next file: linux/drivers/char/rtc.c
Previous file: linux/drivers/block/floppy.c
Back to the patch index
Back to the overall index
- Lines: 172
- Date:
Tue Jan 28 09:32:47 1997
- Orig file:
v2.1.23/linux/drivers/block/triton.c
- Orig date:
Sun Nov 10 20:12:10 1996
diff -u --recursive --new-file v2.1.23/linux/drivers/block/triton.c linux/drivers/block/triton.c
@@ -1,7 +1,7 @@
/*
- * linux/drivers/block/triton.c Version 1.13 Aug 12, 1996
+ * linux/drivers/block/triton.c Version 1.20 Jan 27, 1997
*
- * Copyright (c) 1995-1996 Mark Lord
+ * Copyright (c) 1995-1997 Mark Lord
* May be copied or modified under the terms of the GNU General Public License
*/
@@ -95,6 +95,9 @@
* available from ftp://ftp.intel.com/pub/bios/10004bs0.exe
* (thanks to Glen Morrell <glen@spin.Stanford.edu> for researching this).
*
+ * Thanks to "Christopher J. Reimer" <reimer@doe.carleton.ca> for fixing the
+ * problem with some (all?) ACER motherboards/BIOSs.
+ *
* And, yes, Intel Zappa boards really *do* use the Triton IDE ports.
*/
#include <linux/types.h>
@@ -143,7 +146,11 @@
*/
#define PRD_BYTES 8
#define PRD_ENTRIES (PAGE_SIZE / (2 * PRD_BYTES))
-#define DEFAULT_BMIBA 0xe800 /* in case BIOS did not init it */
+
+/*
+ * Interface to access piix registers
+ */
+static unsigned int piix_key;
/*
* dma_intr() is the handler for disk read/write DMA interrupts
@@ -366,6 +373,53 @@
printk("\n");
}
+/* The next two functions were stolen from cmd640.c, with
+ a few modifications */
+
+static void put_piix_reg (unsigned short reg, long val)
+{
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+ outl_p((reg & 0xfc) | piix_key, 0xcf8);
+ outl_p(val, (reg & 3) | 0xcfc);
+ restore_flags(flags);
+}
+
+static long get_piix_reg (unsigned short reg)
+{
+ long b;
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+ outl_p((reg & 0xfc) | piix_key, 0xcf8);
+ b = inl_p((reg & 3) | 0xcfc);
+ restore_flags(flags);
+ return b;
+}
+
+/*
+ * Search for an (apparently) unused block of I/O space
+ * of "size" bytes in length.
+ */
+static short find_free_region (unsigned short size)
+{
+ unsigned short i, base = 0xe800;
+ for (base = 0xe800; base > 0; base -= 0x800) {
+ if (!check_region(base,size)) {
+ for (i = 0; i < size; i++) {
+ if (inb(base+i) != 0xff)
+ goto next;
+ }
+ return base; /* success */
+ }
+ next:
+ }
+ return 0; /* failure */
+}
+
/*
* ide_init_triton() prepares the IDE driver for DMA operation.
* This routine is called once, from ide.c during driver initialization,
@@ -379,8 +433,9 @@
unsigned int bmiba, timings;
printk("ide: i82371 PIIX (Triton) on PCI bus %d function %d\n", bus, fn);
+
/*
- * See if IDE and BM-DMA features are enabled:
+ * See if IDE ports are enabled
*/
if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)))
goto quit;
@@ -388,42 +443,44 @@
printk("ide: ports are not enabled (BIOS)\n");
goto quit;
}
+ if ((rc = pcibios_read_config_dword(bus, fn, 0x40, &timings)))
+ goto quit;
+ if (!(timings & 0x80008000)) {
+ printk("ide: neither port is enabled\n");
+ goto quit;
+ }
+
+ /*
+ * See if Bus-Mastered DMA is enabled
+ */
if ((pcicmd & 4) == 0) {
printk("ide: BM-DMA feature is not enabled (BIOS)\n");
} else {
/*
* Get the bmiba base address
*/
- int try_again = 1;
- do {
- if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &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)
- 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)))
- goto quit;
- rc = pcibios_write_config_dword(bus, fn, 0x20, DEFAULT_BMIBA|1);
- if (pcibios_write_config_word(bus, fn, 0x04, pcicmd|5) || rc)
- goto quit;
+ if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba)))
+ goto quit;
+ bmiba &= 0xfff0; /* extract port base address */
+ if (bmiba) {
+ dma_enabled = 1;
+ } else {
+ unsigned short base;
+ printk("ide: BM-DMA base register is invalid (0x%04x, PnP BIOS problem)\n", bmiba);
+ base = find_free_region(16);
+ if (base) {
+ printk("ide: bypassing BIOS; setting BMIBA to 0x%04x\n", base);
+ piix_key = 0x80000000 + (fn * 0x100);
+ put_piix_reg(0x04,get_piix_reg(0x04)&~5);
+ put_piix_reg(0x20,(get_piix_reg(0x20)&0xFFFF000F)|base|1);
+ put_piix_reg(0x04,get_piix_reg(0x04)|5);
+ bmiba = get_piix_reg(0x20)&0x0000FFF0;
+ if (bmiba == base && (get_piix_reg(0x04) & 5) == 5)
+ dma_enabled = 1;
+ else
+ printk("ide: no such luck; DMA disabled\n");
}
- } while (try_again--);
- }
-
- /*
- * 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");
- goto quit;
+ }
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov