[patch] via ide chipset update

Jeff Garzik (jgarzik@pobox.com)
Wed, 01 Sep 1999 06:26:52 -0400


This is a multi-part message in MIME format.
--------------FC0512895E4D8D8F45DEFF1B
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Patched against 2.3.16. changelog:

o renamed from via85c586 to via85cxxx

o moved PCI init into capability tables for easy maintenance

o preliminary 85C686 support. NOTE: only bridges. ide controller not
yet supported. It is simple to add though.

Jeff

-- 
Americans' greatest fear is that America will turn out to have been a
phenomenon, not a civilization.
                -- Shirley Hazzard, "Transit of Venus"
--------------FC0512895E4D8D8F45DEFF1B
Content-Type: text/plain; charset=us-ascii;
 name="patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="patch"

diff -urN /g/vanilla/v2.3.16/linux/Documentation/Configure.help linux/Documentation/Configure.help --- /g/vanilla/v2.3.16/linux/Documentation/Configure.help Mon Aug 30 21:05:57 1999 +++ linux/Documentation/Configure.help Wed Sep 1 06:12:53 1999 @@ -754,16 +754,15 @@ needed for further tweaking and development. Please read the comments at the top of drivers/block/trm290.c. -VIA82C586 chipset support (EXPERIMENTAL) -CONFIG_BLK_DEV_VIA82C586 +VIA82Cxxx chipset support (EXPERIMENTAL) +CONFIG_BLK_DEV_VIA82CXXX This allows you to to configure your chipset for a better use while running (U)DMA: it will allow you to enable efficiently the second channel dma usage, as it is may not be set by BIOS. It allows you to run a kernel command line at boot time in order to set fifo config. If no command line is provided, it will try to set fifo configuration at its best. It will allow you to get a proc/ide/via display - (while running a "cat") provided you enabled "proc" support and - set DISPLAY_APOLLO_TIMINGS in via82c586.c + (while running a "cat") provided you enabled "proc" support. This requires CONFIG_IDEDMA_PCI_AUTO to be enabled. diff -urN /g/vanilla/v2.3.16/linux/drivers/block/Config.in linux/drivers/block/Config.in --- /g/vanilla/v2.3.16/linux/drivers/block/Config.in Thu Aug 26 16:44:03 1999 +++ linux/drivers/block/Config.in Wed Sep 1 06:12:54 1999 @@ -90,7 +90,7 @@ if [ "$IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 if [ "$CONFIG_X86" = "y" ]; then - bool ' VIA82C586 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82C586 + bool ' VIA82Cxxx chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82CXXX fi fi fi diff -urN /g/vanilla/v2.3.16/linux/drivers/block/Makefile linux/drivers/block/Makefile --- /g/vanilla/v2.3.16/linux/drivers/block/Makefile Mon Aug 30 13:24:14 1999 +++ linux/drivers/block/Makefile Wed Sep 1 06:12:54 1999 @@ -222,8 +222,8 @@ IDE_OBJS += umc8672.o endif -ifeq ($(CONFIG_BLK_DEV_VIA82C586),y) -IDE_OBJS += via82c586.o +ifeq ($(CONFIG_BLK_DEV_VIA82CXXX),y) +IDE_OBJS += via82cxxx.o endif ### if CONFIG_BLK_DEV_IDE is n, IDE_OBJS will be ignored diff -urN /g/vanilla/v2.3.16/linux/drivers/block/ide-pci.c linux/drivers/block/ide-pci.c --- /g/vanilla/v2.3.16/linux/drivers/block/ide-pci.c Thu Aug 26 16:54:23 1999 +++ linux/drivers/block/ide-pci.c Wed Sep 1 06:12:54 1999 @@ -106,17 +106,17 @@ #define INIT_RZ1000 IDE_IGNORE #endif -#ifdef CONFIG_BLK_DEV_VIA82C586 -extern unsigned int pci_init_via82c568(struct pci_dev *, const char *); -extern void ide_init_via82c586(ide_hwif_t *); -extern void ide_dmacapable_via82c586(ide_hwif_t *, unsigned long dmabase); -#define PCI_VIA82C586 &pci_init_via82c568 -#define INIT_VIA82C586 &ide_init_via82c586 -#define DMA_VIA82C586 &ide_dmacapable_via82c586 -#else -#define PCI_VIA82C586 NULL -#define INIT_VIA82C586 NULL -#define DMA_VIA82C586 NULL +#ifdef CONFIG_BLK_DEV_VIA82CXXX +extern unsigned int pci_init_via82cxxx(struct pci_dev *, const char *); +extern void ide_init_via82cxxx(ide_hwif_t *); +extern void ide_dmacapable_via82cxxx(ide_hwif_t *, unsigned long dmabase); +#define PCI_VIA82CXXX &pci_init_via82cxxx +#define INIT_VIA82CXXX &ide_init_via82cxxx +#define DMA_VIA82CXXX &ide_dmacapable_via82cxxx +#else +#define PCI_VIA82CXXX NULL +#define INIT_VIA82CXXX NULL +#define DMA_VIA82CXXX NULL #endif #ifdef CONFIG_BLK_DEV_ALI15X3 @@ -220,7 +220,7 @@ {DEVID_PIIX3, "PIIX3", NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 }, {DEVID_PIIX4, "PIIX4", NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 }, {DEVID_VIA_IDE, "VIA_IDE", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 }, - {DEVID_VP_IDE, "VP_IDE", PCI_VIA82C586, INIT_VIA82C586, DMA_VIA82C586, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0, 0 }, + {DEVID_VP_IDE, "VP_IDE", PCI_VIA82CXXX, INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0, 0 }, {DEVID_PDC20246,"PDC20246", PCI_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 0, 16 }, {DEVID_PDC20262,"PDC20262", PCI_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 1, 48 }, {DEVID_RZ1000, "RZ1000", NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 }, diff -urN /g/vanilla/v2.3.16/linux/drivers/block/ide-proc.c linux/drivers/block/ide-proc.c --- /g/vanilla/v2.3.16/linux/drivers/block/ide-proc.c Thu Aug 26 16:44:03 1999 +++ linux/drivers/block/ide-proc.c Wed Sep 1 06:12:54 1999 @@ -73,9 +73,9 @@ #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif -#ifdef CONFIG_BLK_DEV_VIA82C586 +#ifdef CONFIG_BLK_DEV_VIA82CXXX int (*via_display_info)(char *, char **, off_t, int, int) = NULL; -#endif /* CONFIG_BLK_DEV_VIA82C586 */ +#endif /* CONFIG_BLK_DEV_VIA82CXXX */ #ifdef CONFIG_BLK_DEV_ALI15X3 int (*ali_display_info)(char *, char **, off_t, int, int) = NULL; @@ -750,12 +750,12 @@ ent = create_proc_entry("drivers", 0, proc_ide_root); if (!ent) return; ent->read_proc = proc_ide_read_drivers; -#ifdef CONFIG_BLK_DEV_VIA82C586 +#ifdef CONFIG_BLK_DEV_VIA82CXXX if (via_display_info) { ent = create_proc_entry("via", 0, proc_ide_root); ent->get_info = via_display_info; } -#endif /* CONFIG_BLK_DEV_VIA82C586 */ +#endif /* CONFIG_BLK_DEV_VIA82CXXX */ #ifdef CONFIG_BLK_DEV_ALI15X3 if (ali_display_info) { ent = create_proc_entry("ali", 0, proc_ide_root); @@ -770,10 +770,10 @@ * Mmmm.. does this free up all resources, * or do we need to do a more proper cleanup here ?? */ -#ifdef CONFIG_BLK_DEV_VIA82C586 +#ifdef CONFIG_BLK_DEV_VIA82CXXX if (via_display_info) remove_proc_entry("ide/via",0); -#endif /* CONFIG_BLK_DEV_VIA82C586 */ +#endif /* CONFIG_BLK_DEV_VIA82CXXX */ #ifdef CONFIG_BLK_DEV_ALI15X3 if (ali_display_info) remove_proc_entry("ide/ali",0); diff -urN /g/vanilla/v2.3.16/linux/drivers/block/ide.c linux/drivers/block/ide.c --- /g/vanilla/v2.3.16/linux/drivers/block/ide.c Thu Aug 26 16:44:03 1999 +++ linux/drivers/block/ide.c Wed Sep 1 06:12:54 1999 @@ -149,8 +149,8 @@ #include <linux/kmod.h> #endif /* CONFIG_KMOD */ -#ifdef CONFIG_BLK_DEV_VIA82C586 -extern byte fifoconfig; /* defined in via82c586.c used by ide_setup()*/ +#ifdef CONFIG_BLK_DEV_VIA82CXXX +extern byte fifoconfig; /* defined in via82cxxx.c used by ide_setup()*/ #endif static const byte ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, @@ -2793,7 +2793,7 @@ } } -#if defined(CONFIG_BLK_DEV_VIA82C586) +#if defined(CONFIG_BLK_DEV_VIA82CXXX) /* * Look for drive option "splitfifo=..." */ @@ -2843,7 +2843,7 @@ fifoconfig = tmp; goto done; } -#endif /* defined(CONFIG_BLK_DEV_VIA82C586) */ +#endif /* defined(CONFIG_BLK_DEV_VIA82CXXX) */ if (s[0] != 'i' || s[1] != 'd' || s[2] != 'e') goto bad_option; diff -urN /g/vanilla/v2.3.16/linux/drivers/block/via82c586.c linux/drivers/block/via82c586.c --- /g/vanilla/v2.3.16/linux/drivers/block/via82c586.c Thu Aug 26 16:55:23 1999 +++ linux/drivers/block/via82c586.c Wed Dec 31 19:00:00 1969 @@ -1,600 +0,0 @@ -/* - * linux/drivers/block/via82c586.c Version 0.04 July 11, 1999 - * - * Copyright (C) 1998 Michel Aubry, Maintainer - * Copyright (C) 1998 Andre Hedrick, Maintainer - * - * The VIA MVP-3 is reported OK with UDMA. - * The TX Pro III is also reported OK with UDMA. - * - * VIA chips also have a single FIFO, with the same 64 bytes deep - * buffer (16 levels of 4 bytes each). - * - * However, VIA chips can have the buffer split either 8:8 levels, - * 16:0 levels or 0:16 levels between both channels. One could think - * of using this feature, as even if no level of FIFO is given to a - * given channel, one can for instance always reach ATAPI drives through - * it, or, if one channel is unused, configuration defaults to - * an even split FIFO levels. - * - * This feature is available only through a kernel command line : - * "splitfifo=Chan,Thr0,Thr1" or "splitfifo=Chan". - * where: Chan =1,2,3 or 4 and Thrx = 1,2,3,or 4. - * - * If Chan == 1: - * gives all the fifo to channel 0, - * sets its threshold to Thr0/4, - * and disables any dma access to channel 1. - * - * If chan == 2: - * gives all the fifo to channel 1, - * sets its threshold to Thr1/4, - * and disables any dma access to channel 0. - * - * If chan == 3 or 4: - * shares evenly fifo between channels, - * gives channel 0 a threshold of Thr0/4, - * and channel 1 a threshold of Thr1/4. - * - * Note that by default (if no command line is provided) and if a channel - * has been disabled in Bios, all the fifo is given to the active channel, - * and its threshold is set to 3/4. - */ - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/interrupt.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/ide.h> - -#include <asm/io.h> - -static struct pci_dev *host_dev; -static struct pci_dev *isa_dev; - -#define DISPLAY_VIA_TIMINGS - -#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) -#include <linux/stat.h> -#include <linux/proc_fs.h> - -static char *FIFO_str[] = { - " 1 ", - "3/4", - "1/2", - "1/4" -}; - -static char *control3_str[] = { - "No limitation", - "64", - "128", - "192" -}; - -static int via_get_info(char *, char **, off_t, int, int); -extern int (*via_display_info)(char *, char **, off_t, int, int); /* ide-proc.c */ -static struct pci_dev *bmide_dev; - -static char * print_apollo_drive_config (char *buf, struct pci_dev *dev) -{ - int rc; - unsigned int time; - byte tm; - char *p = buf; - - /* Drive Timing Control */ - rc = pci_read_config_dword(dev, 0x48, &time); - p += sprintf(p, "Act Pls Width: %02d %02d %02d %02d\n", - ((time & 0xf0000000)>>28) + 1, - ((time & 0xf00000)>>20) + 1, - ((time & 0xf000)>>12) + 1, - ((time & 0xf0)>>4) + 1 ); - p += sprintf(p, "Recovery Time: %02d %02d %02d %02d\n", - ((time & 0x0f000000)>>24) + 1, - ((time & 0x0f0000)>>16) + 1, - ((time & 0x0f00)>>8) + 1, - (time & 0x0f) + 1 ); - - /* Address Setup Time */ - rc = pci_read_config_byte(dev, 0x4C, &tm); - p += sprintf(p, "Add. Setup T.: %01dT %01dT %01dT %01dT\n", - ((tm & 0xc0)>>6) + 1, - ((tm & 0x30)>>4) + 1, - ((tm & 0x0c)>>2) + 1, - (tm & 0x03) + 1 ); - - /* UltraDMA33 Extended Timing Control */ - rc = pci_read_config_dword(dev, 0x50, &time); - p += sprintf(p, "------------------UDMA-Timing-Control------------------------\n"); - p += sprintf(p, "Enable Meth.: %01d %01d %01d %01d\n", - (time & 0x80000000) ? 1 : 0, - (time & 0x800000) ? 1 : 0, - (time & 0x8000) ? 1 : 0, - (time & 0x80) ? 1 : 0 ); - p += sprintf(p, "Enable: %s %s %s %s\n", - (time & 0x40000000) ? "yes" : "no ", - (time & 0x400000) ? "yes" : "no ", - (time & 0x4000) ? "yes" : "no ", - (time & 0x40) ? "yes" : "no " ); - p += sprintf(p, "Transfer Mode: %s %s %s %s\n", - (time & 0x20000000) ? "PIO" : "DMA", - (time & 0x200000) ? "PIO" : "DMA", - (time & 0x2000) ? "PIO" : "DMA", - (time & 0x20) ? "PIO" : "DMA" ); - p += sprintf(p, "Cycle Time: %01dT %01dT %01dT %01dT\n", - ((time & 0x03000000)>>24) + 2, - ((time & 0x030000)>>16) + 2, - ((time & 0x0300)>>8) + 2, - (time & 0x03) + 2 ); - - return (char *)p; -} - -static char * print_apollo_ide_config (char *buf, struct pci_dev *dev) -{ - byte time, tmp; - unsigned short size0, size1; - int rc; - char *p = buf; - - rc = pci_read_config_byte(dev, 0x41, &time); - p += sprintf(p, "Prefetch Buffer : %s %s\n", - (time & 128) ? "on " : "off", - (time & 32) ? "on " : "off" ); - p += sprintf(p, "Post Write Buffer: %s %s\n", - (time & 64) ? "on " : "off", - (time & 16) ? "on " : "off" ); - - /* FIFO configuration */ - rc = pci_read_config_byte(dev, 0x43, &time); - tmp = ((time & 0x20)>>2) + ((time & 0x40)>>3); - p += sprintf(p, "FIFO Conf/Chan. : %02d %02d\n", - 16 - tmp, tmp); - tmp = (time & 0x0F)>>2; - p += sprintf(p, "Threshold Prim. : %s %s\n", - FIFO_str[tmp], - FIFO_str[time & 0x03] ); - - /* chipset Control3 */ - rc = pci_read_config_byte(dev, 0x46, &time); - p += sprintf(p, "Read DMA FIFO flush: %s %s\n", - (time & 0x80) ? "on " : "off", - (time & 0x40) ? "on " : "off" ); - p += sprintf(p, "End Sect. FIFO flush: %s %s\n", - (time & 0x20) ? "on " : "off", - (time & 0x10) ? "on " : "off" ); - p += sprintf(p, "Max DRDY Pulse Width: %s %s\n", - control3_str[(time & 0x03)], - (time & 0x03) ? "PCI clocks" : "" ); - - /* Primary and Secondary sector sizes */ - rc = pci_read_config_word(dev, 0x60, &size0); - rc = pci_read_config_word(dev, 0x68, &size1); - p += sprintf(p, "Bytes Per Sector: %03d %03d\n", - size0 & 0xfff, - size1 & 0xfff ); - - return (char *)p; -} - -static char * print_apollo_chipset_control1 (char *buf, struct pci_dev *dev) -{ - byte t; - int rc; - char *p = buf; - unsigned short c; - byte l, l_max; - - rc = pci_read_config_word(dev, 0x04, &c); - rc = pci_read_config_byte(dev, 0x44, &t); - rc = pci_read_config_byte(dev, 0x0d, &l); - rc = pci_read_config_byte(dev, 0x3f, &l_max); - - p += sprintf(p, "Command register = 0x%x\n", c); - p += sprintf(p, "Master Read Cycle IRDY %d Wait State\n", - (t & 64) >>6 ); - p += sprintf(p, "Master Write Cycle IRDY %d Wait State\n", - (t & 32) >> 5 ); - p += sprintf(p, "FIFO Output Data 1/2 Clock Advance: %s\n", - (t & 16) ? "on " : "off" ); - p += sprintf(p, "Bus Master IDE Status Register Read Retry: %s\n", - (t & 8) ? "on " : "off" ); - p += sprintf(p, "Latency timer = %d (max. = %d)\n", - l, l_max); - - return (char *)p; -} - -static char * print_apollo_chipset_control2 (char *buf, struct pci_dev *dev) -{ - byte t; - int rc; - char *p = buf; - rc = pci_read_config_byte(dev, 0x45, &t); - p += sprintf(p, "Interrupt Steering Swap: %s\n", - (t & 64) ? "on ":"off" ); - - return (char *)p; -} - -static char * print_apollo_chipset_control3 (char *buf, struct pci_dev *dev, - unsigned short n) -{ - /* - * at that point we can be sure that register 0x20 of the - * chipset contains the right address... - */ - unsigned int bibma; - int rc; - byte c0, c1; - char *p = buf; - - rc = pci_read_config_dword(dev, 0x20, &bibma); - bibma = (bibma & 0xfff0) ; - - /* - * at that point bibma+0x2 et bibma+0xa are byte registers - * to investigate: - */ - c0 = inb((unsigned short)bibma + 0x02); - c1 = inb((unsigned short)bibma + 0x0a); - - if (n == 0) { - /*p = sprintf(p,"--------------------Primary IDE------------Secondary IDE-----");*/ - p += sprintf(p, "both channels togth: %s %s\n", - (c0&0x80) ? "no" : "yes", - (c1&0x80) ? "no" : "yes" ); - } else { - /*p = sprintf(p,"--------------drive0------drive1-------drive0------drive1----");*/ - p += sprintf(p, "DMA enabled: %s %s %s %s\n", - (c0&0x20) ? "yes" : "no ", - (c0&0x40) ? "yes" : "no ", - (c1&0x20) ? "yes" : "no ", - (c1&0x40) ? "yes" : "no " ); - } - - return (char *)p; -} - -static int via_get_info (char *buffer, char **addr, off_t offset, int count, int dummy) -{ - /* - * print what /proc/via displays, - * if required from DISPLAY_APOLLO_TIMINGS - */ - char *p = buffer; - /* Parameter of chipset : */ - - /* Miscellaneous control 1 */ - p = print_apollo_chipset_control1(buffer, bmide_dev); - - /* Miscellaneous control 2 */ - p = print_apollo_chipset_control2(p, bmide_dev); - /* Parameters of drives: */ - - /* Header */ - p += sprintf(p, "------------------Primary IDE------------Secondary IDE-----\n"); - p = print_apollo_chipset_control3(p, bmide_dev, 0); - p = print_apollo_ide_config(p, bmide_dev); - p += sprintf(p, "--------------drive0------drive1-------drive0------drive1----\n"); - p = print_apollo_chipset_control3(p, bmide_dev, 1); - p = print_apollo_drive_config(p, bmide_dev); - - return p-buffer; /* hoping it is less than 4K... */ -} - -#endif /* defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) */ - -/* - * Used to set Fifo configuration via kernel command line: - */ - -byte fifoconfig = 0; -static byte newfifo = 0; - -/* Used to just intialize once Fifo configuration */ -static short int done = 0; - -/* - * Set VIA Chipset Timings for (U)DMA modes enabled. - * - * VIA Apollo chipset has complete support for - * setting up the timing parameters. - */ -static void set_via_timings (ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - byte post = hwif->channel ? 0x30 : 0xc0; - byte flush = hwif->channel ? 0x50 : 0xa0; - int mask = hwif->channel ? ((newfifo & 0x60) ? 0 : 1) : - (((newfifo & 0x60) == 0x60) ? 1 : 0); - byte via_config = 0; - int rc = 0, errors = 0; - - printk("%s: VIA Bus-Master ", hwif->name); - - /* - * setting IDE read prefetch buffer and IDE post write buffer. - * (This feature allows prefetched reads and post writes). - */ - if ((rc = pci_read_config_byte(dev, 0x41, &via_config))) - errors++; - - if (mask) { - if ((rc = pci_write_config_byte(dev, 0x41, via_config & ~post))) - errors++; - } else { - if ((rc = pci_write_config_byte(dev, 0x41, via_config | post))) - errors++; - } - - /* - * setting Channel read and End-of-sector FIFO flush. - * (This feature ensures that FIFO flush is enabled: - * - for read DMA when interrupt asserts the given channel. - * - at the end of each sector for the given channel.) - */ - if ((rc = pci_read_config_byte(dev, 0x46, &via_config))) - errors++; - - if (mask) { - if ((rc = pci_write_config_byte(dev, 0x46, via_config & ~flush))) - errors++; - } else { - if ((rc = pci_write_config_byte(dev, 0x46, via_config | flush))) - errors++; - } - - if (!hwif->dma_base) - printk("Config %s. No DMA Enabled\n", - errors ? "ERROR":"Success"); - else - printk("(U)DMA Timing Config %s\n", - errors ? "ERROR" : "Success"); -} - -/* - * Sets VIA 82c586 FIFO configuration: - * This chipsets gets a splitable fifo. This can be driven either by command - * line option (eg "splitfifo=2,2,3" which asks this driver to switch all the - * 16 fifo levels to the second drive, and give it a threshold of 3 for (u)dma - * triggering. - */ - -static int via_set_fifoconfig(ide_hwif_t *hwif) -{ - byte fifo; - unsigned int timings; - struct pci_dev *dev = hwif->pci_dev; - - /* read port configuration */ - if (pci_read_config_dword(dev, 0x40, &timings)) - return 1; - - /* first read actual fifo config: */ - if (pci_read_config_byte(dev, 0x43, &fifo)) - return 1; - - /* keep 4 and 7 bit as they seem to differ between chipsets flavors... */ - newfifo = fifo & 0x90; - - if (fifoconfig) { - /* we received a config request from kernel command line: */ - newfifo |= fifoconfig & 0x6f; - } else { - /* If ever just one channel is unused, allocate all fifo levels to it - * and give it a 3/4 threshold for (u)dma transfers. - * Otherwise, share it evenly between channels: - */ - if ((timings & 3) == 2) { - /* only primary channel is enabled - * 16 buf. to prim. chan. thresh=3/4 - */ - newfifo |= 0x06; - } else if ((timings & 3) == 1) { - /* only secondary channel is enabled! - * 16 buffers to sec. ch. thresh=3/4 - */ - newfifo |= 0x69; - } else { - /* fifo evenly distributed: */ - newfifo |= 0x2a; - } - } - - /* write resulting configuration to chipset: */ - if (pci_write_config_byte(dev, 0x43, newfifo)) - return 1; - - /* and then reread it to get the actual one */ - if (pci_read_config_byte(dev, 0x43, &newfifo)) - return 1; - - /* print a kernel report: */ - printk("Split FIFO Configuration: %s Primary buffers, threshold = %s\n", - ((newfifo & 0x60) == 0x60) ? " 0" : - ((newfifo & 0x60) ? " 8" : "16"), - !(newfifo & 0x0c) ? "1" : - (!(newfifo & 0x08) ? "3/4" : - (newfifo & 0x04) ? "1/4" : "1/2")); - - printk(" %s Second. buffers, threshold = %s\n", - ((newfifo & 0x60) == 0x60) ? "16" : - ((newfifo & 0x60) ? " 8" : " 0"), - !(newfifo & 0x03) ? "1" : - (!(newfifo & 0x02) ? "3/4" : - (newfifo & 0x01) ? "1/4" : "1/2")); - -#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) - bmide_dev = hwif->pci_dev; - via_display_info = &via_get_info; -#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS*/ - return 0; -} - -unsigned int __init pci_init_via82c568 (struct pci_dev *dev, const char *name) -{ - struct pci_dev *host; - struct pci_dev *isa; - - byte revision = 0; - - for (host = pci_devices; host; host=host->next) { - if (host->vendor == PCI_VENDOR_ID_VIA && - host->device == PCI_DEVICE_ID_VIA_82C585) { - host_dev = host; - printk("VT 82C585 Apollo VP1/VPX"); - for (isa = pci_devices; isa; isa=isa->next) { - if (isa->vendor == PCI_VENDOR_ID_VIA && - isa->device == PCI_DEVICE_ID_VIA_82C586_1) { - isa_dev = isa; - pci_read_config_byte(isa_dev, 0x0d, &revision); - if (revision >= 0x20) - printk(" Chipset Core ATA-33"); - break; - } - } - printk("\n"); - break; - } else if (host->vendor == PCI_VENDOR_ID_VIA && - host->device == PCI_DEVICE_ID_VIA_82C595) { - host_dev = host; - printk("VT 82C595 Apollo VP2"); - for (isa = pci_devices; isa; isa=isa->next) { - if (isa->vendor == PCI_VENDOR_ID_VIA && - isa->device == PCI_DEVICE_ID_VIA_82C586_1) { - isa_dev = isa; - pci_read_config_byte(isa_dev, 0x0d, &revision); - if (revision >= 0x20) - printk(" Chipset Core ATA-33"); - break; - } - } - printk("\n"); - break; - } else if (host->vendor == PCI_VENDOR_ID_VIA && - host->device == PCI_DEVICE_ID_VIA_82C597_0) { - host_dev = host; - printk("VT 82C597 Apollo VP3"); - for (isa = pci_devices; isa; isa=isa->next) { - if (isa->vendor == PCI_VENDOR_ID_VIA && - isa->device == PCI_DEVICE_ID_VIA_82C586_1) { - isa_dev = isa; - pci_read_config_byte(isa_dev, 0x0d, &revision); - if (revision >= 0x20) - printk(" Chipset Core ATA-33"); - break; - } - } - printk("\n"); - break; - } else if (host->vendor == PCI_VENDOR_ID_VIA && - host->device == PCI_DEVICE_ID_VIA_82C598_0) { - host_dev = host; - printk("VT 82C598 Apollo MVP3"); - for (isa = pci_devices; isa; isa=isa->next) { - if (isa->vendor == PCI_VENDOR_ID_VIA && - isa->device == PCI_DEVICE_ID_VIA_82C586_1) { - isa_dev = isa; - pci_read_config_byte(isa_dev, 0x0d, &revision); - if (revision >= 0x20) - printk(" Chipset Core ATA-33"); - break; - } else if (isa->vendor == PCI_VENDOR_ID_VIA && - isa->device == PCI_DEVICE_ID_VIA_82C596) { - isa_dev = isa; - printk(" Chipset Core ATA-33"); - break; - } - } - printk("\n"); - break; - } else if (host->vendor == PCI_VENDOR_ID_VIA && - host->device == PCI_DEVICE_ID_VIA_82C680) { - host_dev = host; - printk("VT 82C680 Apollo P6"); - for (isa = pci_devices; isa; isa=isa->next) { - if (isa->vendor == PCI_VENDOR_ID_VIA && - isa->device == PCI_DEVICE_ID_VIA_82C586_1) { - isa_dev = isa; - pci_read_config_byte(isa_dev, 0x0d, &revision); - if (revision >= 0x20) - printk(" Chipset Core ATA-33"); - break; - } - } - printk("\n"); - break; - } else if (host->vendor == PCI_VENDOR_ID_VIA && - host->device == PCI_DEVICE_ID_VIA_82C691) { - host_dev = host; - printk("VT 82C691 Apollo Pro"); - for (isa = pci_devices; isa; isa=isa->next) { - if (isa->vendor == PCI_VENDOR_ID_VIA && - isa->device == PCI_DEVICE_ID_VIA_82C596) { - isa_dev = isa; - printk(" Chipset Core ATA-33"); - break; - } - } - printk("\n"); - break; - } else if (host->vendor == PCI_VENDOR_ID_VIA && - host->device == PCI_DEVICE_ID_VIA_82C693) { - host_dev = host; - printk("VT 82C693 Apollo Pro Plus"); - for (isa = pci_devices; isa; isa=isa->next) { - if (isa->vendor == PCI_VENDOR_ID_VIA && - isa->device == PCI_DEVICE_ID_VIA_82C596) { - isa_dev = isa; - printk(" Chipset Core ATA-33"); - break; - } - } - printk("\n"); - break; - } - } - return 0; -} - -void __init ide_init_via82c586 (ide_hwif_t *hwif) -{ - set_via_timings(hwif); -} - -/* - * ide_dmacapable_via82c568(ide_hwif_t *, unsigned long) - * checks if channel "channel" of if hwif is dma - * capable or not, according to kernel command line, - * and the new fifo settings. - * It calls "ide_setup_dma" on capable mainboards, and - * bypasses the setup if not capable. - */ - -void ide_dmacapable_via82c586 (ide_hwif_t *hwif, unsigned long dmabase) -{ - if (!done) { - via_set_fifoconfig(hwif); - done = 1; - } - - /* - * check if any fifo is available for requested port: - */ - if (((hwif->channel == 0) && ((newfifo & 0x60) == 0x60)) || - ((hwif->channel == 1) && ((newfifo & 0x60) == 0x00))) { - printk(" %s: VP_IDE Bus-Master DMA disabled (FIFO setting)\n", hwif->name); - } else { - ide_setup_dma(hwif, dmabase, 8); - } -} diff -urN /g/vanilla/v2.3.16/linux/drivers/block/via82cxxx.c linux/drivers/block/via82cxxx.c --- /g/vanilla/v2.3.16/linux/drivers/block/via82cxxx.c Wed Dec 31 19:00:00 1969 +++ linux/drivers/block/via82cxxx.c Wed Sep 1 06:12:54 1999 @@ -0,0 +1,610 @@ +/* + * linux/drivers/block/via82cxxx.c Version 0.04 July 11, 1999 + * + * Copyright (C) 1998 Michel Aubry, Maintainer + * Copyright (C) 1998 Andre Hedrick, Maintainer + * + * The VIA MVP-4 is reported OK with UDMA. + * The VIA MVP-3 is reported OK with UDMA. + * The TX Pro III is also reported OK with UDMA. + * + * VIA chips also have a single FIFO, with the same 64 bytes deep + * buffer (16 levels of 4 bytes each). + * + * However, VIA chips can have the buffer split either 8:8 levels, + * 16:0 levels or 0:16 levels between both channels. One could think + * of using this feature, as even if no level of FIFO is given to a + * given channel, one can for instance always reach ATAPI drives through + * it, or, if one channel is unused, configuration defaults to + * an even split FIFO levels. + * + * This feature is available only through a kernel command line : + * "splitfifo=Chan,Thr0,Thr1" or "splitfifo=Chan". + * where: Chan =1,2,3 or 4 and Thrx = 1,2,3,or 4. + * + * If Chan == 1: + * gives all the fifo to channel 0, + * sets its threshold to Thr0/4, + * and disables any dma access to channel 1. + * + * If chan == 2: + * gives all the fifo to channel 1, + * sets its threshold to Thr1/4, + * and disables any dma access to channel 0. + * + * If chan == 3 or 4: + * shares evenly fifo between channels, + * gives channel 0 a threshold of Thr0/4, + * and channel 1 a threshold of Thr1/4. + * + * Note that by default (if no command line is provided) and if a channel + * has been disabled in Bios, all the fifo is given to the active channel, + * and its threshold is set to 3/4. + * + ************************************************************************* + * + * Updates: + * + * 1999/09/01 Jeff Garzik <jgarzik@pobox.com> + * - VIA MVP-4 support + * + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/timer.h> +#include <linux/mm.h> +#include <linux/ioport.h> +#include <linux/interrupt.h> +#include <linux/blkdev.h> +#include <linux/hdreg.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/ide.h> + +#include <asm/io.h> + +static struct pci_dev *host_dev = NULL; +static struct pci_dev *isa_dev = NULL; + +#define DISPLAY_VIA_TIMINGS + +#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> + +static char *FIFO_str[] = { + " 1 ", + "3/4", + "1/2", + "1/4" +}; + +static char *control3_str[] = { + "No limitation", + "64", + "128", + "192" +}; + +static const struct { + const char *name; + unsigned short host_id; +} ApolloHostChipInfo[] = { + { "VT 82C585 Apollo VP1/VPX", + PCI_DEVICE_ID_VIA_82C585, }, + { "VT 82C595 Apollo VP2", + PCI_DEVICE_ID_VIA_82C595, }, + { "VT 82C597 Apollo VP3", + PCI_DEVICE_ID_VIA_82C597_0, }, + { "VT 82C598 Apollo MVP3", + PCI_DEVICE_ID_VIA_82C598_0, }, + { "VT 82C680 Apollo P6", + PCI_DEVICE_ID_VIA_82C680, }, + { "VT 82C691 Apollo Pro", + PCI_DEVICE_ID_VIA_82C691, }, + { "VT 82C693 Apollo Pro Plus", + PCI_DEVICE_ID_VIA_82C693, }, + { "Apollo MVP4", + PCI_DEVICE_ID_VIA_82C501_0, }, +}; + +#define NUM_APOLLO_ISA_CHIP_DEVICES 2 +#define VIA_FLAG_CHECK_REV 0x00000001 +#define VIA_FLAG_ATA_66 0x00000002 + +static const struct { + unsigned short host_id; + unsigned short isa_id; + unsigned int flags; +} ApolloISAChipInfo[] = { + { PCI_DEVICE_ID_VIA_82C585, + PCI_DEVICE_ID_VIA_82C586_1, + VIA_FLAG_CHECK_REV }, + + { PCI_DEVICE_ID_VIA_82C595, + PCI_DEVICE_ID_VIA_82C586_1, + VIA_FLAG_CHECK_REV }, + + { PCI_DEVICE_ID_VIA_82C597_0, + PCI_DEVICE_ID_VIA_82C586_1, + VIA_FLAG_CHECK_REV }, + + { PCI_DEVICE_ID_VIA_82C598_0, + PCI_DEVICE_ID_VIA_82C586_1, + VIA_FLAG_CHECK_REV }, + + { PCI_DEVICE_ID_VIA_82C598_0, + PCI_DEVICE_ID_VIA_82C596, + 0 }, + + { PCI_DEVICE_ID_VIA_82C680, + PCI_DEVICE_ID_VIA_82C586_1, + VIA_FLAG_CHECK_REV }, + + { PCI_DEVICE_ID_VIA_82C691, + PCI_DEVICE_ID_VIA_82C596, + 0 }, + + { PCI_DEVICE_ID_VIA_82C693, + PCI_DEVICE_ID_VIA_82C596, + 0 }, + + { PCI_DEVICE_ID_VIA_82C501_0, + PCI_DEVICE_ID_VIA_82C686, + VIA_FLAG_ATA_66 }, +}; + +#define arraysize(x) (sizeof(x)/sizeof(*(x))) + +static int via_get_info(char *, char **, off_t, int, int); +extern int (*via_display_info)(char *, char **, off_t, int, int); /* ide-proc.c */ +static struct pci_dev *bmide_dev; + +static char * print_apollo_drive_config (char *buf, struct pci_dev *dev) +{ + int rc; + unsigned int time; + byte tm; + char *p = buf; + + /* Drive Timing Control */ + rc = pci_read_config_dword(dev, 0x48, &time); + p += sprintf(p, "Act Pls Width: %02d %02d %02d %02d\n", + ((time & 0xf0000000)>>28) + 1, + ((time & 0xf00000)>>20) + 1, + ((time & 0xf000)>>12) + 1, + ((time & 0xf0)>>4) + 1 ); + p += sprintf(p, "Recovery Time: %02d %02d %02d %02d\n", + ((time & 0x0f000000)>>24) + 1, + ((time & 0x0f0000)>>16) + 1, + ((time & 0x0f00)>>8) + 1, + (time & 0x0f) + 1 ); + + /* Address Setup Time */ + rc = pci_read_config_byte(dev, 0x4C, &tm); + p += sprintf(p, "Add. Setup T.: %01dT %01dT %01dT %01dT\n", + ((tm & 0xc0)>>6) + 1, + ((tm & 0x30)>>4) + 1, + ((tm & 0x0c)>>2) + 1, + (tm & 0x03) + 1 ); + + /* UltraDMA33 Extended Timing Control */ + rc = pci_read_config_dword(dev, 0x50, &time); + p += sprintf(p, "------------------UDMA-Timing-Control------------------------\n"); + p += sprintf(p, "Enable Meth.: %01d %01d %01d %01d\n", + (time & 0x80000000) ? 1 : 0, + (time & 0x800000) ? 1 : 0, + (time & 0x8000) ? 1 : 0, + (time & 0x80) ? 1 : 0 ); + p += sprintf(p, "Enable: %s %s %s %s\n", + (time & 0x40000000) ? "yes" : "no ", + (time & 0x400000) ? "yes" : "no ", + (time & 0x4000) ? "yes" : "no ", + (time & 0x40) ? "yes" : "no " ); + p += sprintf(p, "Transfer Mode: %s %s %s %s\n", + (time & 0x20000000) ? "PIO" : "DMA", + (time & 0x200000) ? "PIO" : "DMA", + (time & 0x2000) ? "PIO" : "DMA", + (time & 0x20) ? "PIO" : "DMA" ); + p += sprintf(p, "Cycle Time: %01dT %01dT %01dT %01dT\n", + ((time & 0x03000000)>>24) + 2, + ((time & 0x030000)>>16) + 2, + ((time & 0x0300)>>8) + 2, + (time & 0x03) + 2 ); + + return (char *)p; +} + +static char * print_apollo_ide_config (char *buf, struct pci_dev *dev) +{ + byte time, tmp; + unsigned short size0, size1; + int rc; + char *p = buf; + + rc = pci_read_config_byte(dev, 0x41, &time); + p += sprintf(p, "Prefetch Buffer : %s %s\n", + (time & 128) ? "on " : "off", + (time & 32) ? "on " : "off" ); + p += sprintf(p, "Post Write Buffer: %s %s\n", + (time & 64) ? "on " : "off", + (time & 16) ? "on " : "off" ); + + /* FIFO configuration */ + rc = pci_read_config_byte(dev, 0x43, &time); + tmp = ((time & 0x20)>>2) + ((time & 0x40)>>3); + p += sprintf(p, "FIFO Conf/Chan. : %02d %02d\n", + 16 - tmp, tmp); + tmp = (time & 0x0F)>>2; + p += sprintf(p, "Threshold Prim. : %s %s\n", + FIFO_str[tmp], + FIFO_str[time & 0x03] ); + + /* chipset Control3 */ + rc = pci_read_config_byte(dev, 0x46, &time); + p += sprintf(p, "Read DMA FIFO flush: %s %s\n", + (time & 0x80) ? "on " : "off", + (time & 0x40) ? "on " : "off" ); + p += sprintf(p, "End Sect. FIFO flush: %s %s\n", + (time & 0x20) ? "on " : "off", + (time & 0x10) ? "on " : "off" ); + p += sprintf(p, "Max DRDY Pulse Width: %s %s\n", + control3_str[(time & 0x03)], + (time & 0x03) ? "PCI clocks" : "" ); + + /* Primary and Secondary sector sizes */ + rc = pci_read_config_word(dev, 0x60, &size0); + rc = pci_read_config_word(dev, 0x68, &size1); + p += sprintf(p, "Bytes Per Sector: %03d %03d\n", + size0 & 0xfff, + size1 & 0xfff ); + + return (char *)p; +} + +static char * print_apollo_chipset_control1 (char *buf, struct pci_dev *dev) +{ + byte t; + int rc; + char *p = buf; + unsigned short c; + byte l, l_max; + + rc = pci_read_config_word(dev, 0x04, &c); + rc = pci_read_config_byte(dev, 0x44, &t); + rc = pci_read_config_byte(dev, 0x0d, &l); + rc = pci_read_config_byte(dev, 0x3f, &l_max); + + p += sprintf(p, "Command register = 0x%x\n", c); + p += sprintf(p, "Master Read Cycle IRDY %d Wait State\n", + (t & 64) >>6 ); + p += sprintf(p, "Master Write Cycle IRDY %d Wait State\n", + (t & 32) >> 5 ); + p += sprintf(p, "FIFO Output Data 1/2 Clock Advance: %s\n", + (t & 16) ? "on " : "off" ); + p += sprintf(p, "Bus Master IDE Status Register Read Retry: %s\n", + (t & 8) ? "on " : "off" ); + p += sprintf(p, "Latency timer = %d (max. = %d)\n", + l, l_max); + + return (char *)p; +} + +static char * print_apollo_chipset_control2 (char *buf, struct pci_dev *dev) +{ + byte t; + int rc; + char *p = buf; + rc = pci_read_config_byte(dev, 0x45, &t); + p += sprintf(p, "Interrupt Steering Swap: %s\n", + (t & 64) ? "on ":"off" ); + + return (char *)p; +} + +static char * print_apollo_chipset_control3 (char *buf, struct pci_dev *dev, + unsigned short n) +{ + /* + * at that point we can be sure that register 0x20 of the + * chipset contains the right address... + */ + unsigned int bibma; + int rc; + byte c0, c1; + char *p = buf; + + rc = pci_read_config_dword(dev, 0x20, &bibma); + bibma = (bibma & 0xfff0) ; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb((unsigned short)bibma + 0x02); + c1 = inb((unsigned short)bibma + 0x0a); + + if (n == 0) { + /*p = sprintf(p,"--------------------Primary IDE------------Secondary IDE-----");*/ + p += sprintf(p, "both channels togth: %s %s\n", + (c0&0x80) ? "no" : "yes", + (c1&0x80) ? "no" : "yes" ); + } else { + /*p = sprintf(p,"--------------drive0------drive1-------drive0------drive1----");*/ + p += sprintf(p, "DMA enabled: %s %s %s %s\n", + (c0&0x20) ? "yes" : "no ", + (c0&0x40) ? "yes" : "no ", + (c1&0x20) ? "yes" : "no ", + (c1&0x40) ? "yes" : "no " ); + } + + return (char *)p; +} + +static int via_get_info (char *buffer, char **addr, off_t offset, int count, int dummy) +{ + /* + * print what /proc/via displays, + * if required from DISPLAY_APOLLO_TIMINGS + */ + char *p = buffer; + /* Parameter of chipset : */ + + /* Miscellaneous control 1 */ + p = print_apollo_chipset_control1(buffer, bmide_dev); + + /* Miscellaneous control 2 */ + p = print_apollo_chipset_control2(p, bmide_dev); + /* Parameters of drives: */ + + /* Header */ + p += sprintf(p, "------------------Primary IDE------------Secondary IDE-----\n"); + p = print_apollo_chipset_control3(p, bmide_dev, 0); + p = print_apollo_ide_config(p, bmide_dev); + p += sprintf(p, "--------------drive0------drive1-------drive0------drive1----\n"); + p = print_apollo_chipset_control3(p, bmide_dev, 1); + p = print_apollo_drive_config(p, bmide_dev); + + return p-buffer; /* hoping it is less than 4K... */ +} + +#endif /* defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) */ + +/* + * Used to set Fifo configuration via kernel command line: + */ + +byte fifoconfig = 0; +static byte newfifo = 0; + +/* Used to just intialize once Fifo configuration */ +static short int done = 0; + +/* + * Set VIA Chipset Timings for (U)DMA modes enabled. + * + * VIA Apollo chipset has complete support for + * setting up the timing parameters. + */ +static void set_via_timings (ide_hwif_t *hwif) +{ + struct pci_dev *dev = hwif->pci_dev; + byte post = hwif->channel ? 0x30 : 0xc0; + byte flush = hwif->channel ? 0x50 : 0xa0; + int mask = hwif->channel ? ((newfifo & 0x60) ? 0 : 1) : + (((newfifo & 0x60) == 0x60) ? 1 : 0); + byte via_config = 0; + int rc = 0, errors = 0; + + printk("%s: VIA Bus-Master ", hwif->name); + + /* + * setting IDE read prefetch buffer and IDE post write buffer. + * (This feature allows prefetched reads and post writes). + */ + if ((rc = pci_read_config_byte(dev, 0x41, &via_config))) + errors++; + + if (mask) { + if ((rc = pci_write_config_byte(dev, 0x41, via_config & ~post))) + errors++; + } else { + if ((rc = pci_write_config_byte(dev, 0x41, via_config | post))) + errors++; + } + + /* + * setting Channel read and End-of-sector FIFO flush. + * (This feature ensures that FIFO flush is enabled: + * - for read DMA when interrupt asserts the given channel. + * - at the end of each sector for the given channel.) + */ + if ((rc = pci_read_config_byte(dev, 0x46, &via_config))) + errors++; + + if (mask) { + if ((rc = pci_write_config_byte(dev, 0x46, via_config & ~flush))) + errors++; + } else { + if ((rc = pci_write_config_byte(dev, 0x46, via_config | flush))) + errors++; + } + + if (!hwif->dma_base) + printk("Config %s. No DMA Enabled\n", + errors ? "ERROR":"Success"); + else + printk("(U)DMA Timing Config %s\n", + errors ? "ERROR" : "Success"); +} + +/* + * Sets VIA 82cxxx FIFO configuration: + * This chipsets gets a splitable fifo. This can be driven either by command + * line option (eg "splitfifo=2,2,3" which asks this driver to switch all the + * 16 fifo levels to the second drive, and give it a threshold of 3 for (u)dma + * triggering. + */ + +static int via_set_fifoconfig(ide_hwif_t *hwif) +{ + byte fifo; + unsigned int timings; + struct pci_dev *dev = hwif->pci_dev; + + /* read port configuration */ + if (pci_read_config_dword(dev, 0x40, &timings)) + return 1; + + /* first read actual fifo config: */ + if (pci_read_config_byte(dev, 0x43, &fifo)) + return 1; + + /* keep 4 and 7 bit as they seem to differ between chipsets flavors... */ + newfifo = fifo & 0x90; + + if (fifoconfig) { + /* we received a config request from kernel command line: */ + newfifo |= fifoconfig & 0x6f; + } else { + /* If ever just one channel is unused, allocate all fifo levels to it + * and give it a 3/4 threshold for (u)dma transfers. + * Otherwise, share it evenly between channels: + */ + if ((timings & 3) == 2) { + /* only primary channel is enabled + * 16 buf. to prim. chan. thresh=3/4 + */ + newfifo |= 0x06; + } else if ((timings & 3) == 1) { + /* only secondary channel is enabled! + * 16 buffers to sec. ch. thresh=3/4 + */ + newfifo |= 0x69; + } else { + /* fifo evenly distributed: */ + newfifo |= 0x2a; + } + } + + /* write resulting configuration to chipset: */ + if (pci_write_config_byte(dev, 0x43, newfifo)) + return 1; + + /* and then reread it to get the actual one */ + if (pci_read_config_byte(dev, 0x43, &newfifo)) + return 1; + + /* print a kernel report: */ + printk("Split FIFO Configuration: %s Primary buffers, threshold = %s\n", + ((newfifo & 0x60) == 0x60) ? " 0" : + ((newfifo & 0x60) ? " 8" : "16"), + !(newfifo & 0x0c) ? "1" : + (!(newfifo & 0x08) ? "3/4" : + (newfifo & 0x04) ? "1/4" : "1/2")); + + printk(" %s Second. buffers, threshold = %s\n", + ((newfifo & 0x60) == 0x60) ? "16" : + ((newfifo & 0x60) ? " 8" : " 0"), + !(newfifo & 0x03) ? "1" : + (!(newfifo & 0x02) ? "3/4" : + (newfifo & 0x01) ? "1/4" : "1/2")); + +#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) + bmide_dev = hwif->pci_dev; + via_display_info = &via_get_info; +#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS*/ + return 0; +} + +unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name) +{ + struct pci_dev *host; + struct pci_dev *isa; + int i, j, ata33, ata66; + + byte revision = 0; + + for (i = 0; i < arraysize (ApolloHostChipInfo) && !host_dev; i++) { + host = pci_find_device (PCI_VENDOR_ID_VIA, + ApolloHostChipInfo[i].host_id, + NULL); + if (!host) + continue; + + host_dev = host; + printk(ApolloHostChipInfo[i].name); + + for (j = 0; j < arraysize (ApolloISAChipInfo) && !isa_dev; j++) { + if (ApolloISAChipInfo[j].host_id != + ApolloHostChipInfo[i].host_id) + continue; + + isa = pci_find_device (PCI_VENDOR_ID_VIA, + ApolloISAChipInfo[i].isa_id, + NULL); + if (!isa) + continue; + + isa_dev = isa; + + ata33 = 1; + ata66 = 0; + + if (ApolloISAChipInfo[i].flags & VIA_FLAG_CHECK_REV) { + ata33 = 0; + pci_read_config_byte(isa_dev, 0x0d, &revision); + if (revision >= 0x20) + ata33 = 1; + } + else if (ApolloISAChipInfo[i].flags & VIA_FLAG_ATA_66) { + ata33 = 0; + ata66 = 1; + } + + + if (ata33 | ata66) + printk(" Chipset Core ATA-%s", + ata66 ? "66" : "33"); + } + + printk("\n"); + } + + return 0; +} + +void __init ide_init_via82cxxx (ide_hwif_t *hwif) +{ + set_via_timings(hwif); +} + +/* + * ide_dmacapable_via82cxxx(ide_hwif_t *, unsigned long) + * checks if channel "channel" of if hwif is dma + * capable or not, according to kernel command line, + * and the new fifo settings. + * It calls "ide_setup_dma" on capable mainboards, and + * bypasses the setup if not capable. + */ + +void ide_dmacapable_via82cxxx (ide_hwif_t *hwif, unsigned long dmabase) +{ + if (!done) { + via_set_fifoconfig(hwif); + done = 1; + } + + /* + * check if any fifo is available for requested port: + */ + if (((hwif->channel == 0) && ((newfifo & 0x60) == 0x60)) || + ((hwif->channel == 1) && ((newfifo & 0x60) == 0x00))) { + printk(" %s: VP_IDE Bus-Master DMA disabled (FIFO setting)\n", hwif->name); + } else { + ide_setup_dma(hwif, dmabase, 8); + } +} diff -urN /g/vanilla/v2.3.16/linux/drivers/pci/devlist.h linux/drivers/pci/devlist.h --- /g/vanilla/v2.3.16/linux/drivers/pci/devlist.h Tue Aug 31 13:53:32 1999 +++ linux/drivers/pci/devlist.h Wed Sep 1 06:12:54 1999 @@ -548,6 +548,7 @@ ENDVENDOR() VENDOR( VIA, "VIA Technologies" ) + DEVICE( VIA, VIA_8501_0, "VT 8501") DEVICE( VIA, VIA_82C505, "VT 82C505") DEVICE( VIA, VIA_82C561, "VT 82C561") DEVICE( VIA, VIA_82C586_1, "VT 82C586 Apollo IDE") @@ -573,6 +574,7 @@ DEVICE( VIA, VIA_86C100A, "VT 86C100A") + DEVICE( VIA, VIA_8501_1, "VT 8501 PCI Bridge") DEVICE( VIA, VIA_82C597_1, "VT 82C597 Apollo VP3 AGP") DEVICE( VIA, VIA_82C598_1, "VT 82C598 Apollo MVP3 AGP") ENDVENDOR() VENDOR( SMC2, "SMC" ) diff -urN /g/vanilla/v2.3.16/linux/include/linux/pci.h linux/include/linux/pci.h --- /g/vanilla/v2.3.16/linux/include/linux/pci.h Tue Aug 31 19:11:57 1999 +++ linux/include/linux/pci.h Wed Sep 1 06:12:54 1999 @@ -865,6 +865,7 @@ #define PCI_DEVICE_ID_TTI_HPT366 0x0004 #define PCI_VENDOR_ID_VIA 0x1106 +#define PCI_DEVICE_ID_VIA_8501_0 0x0501 #define PCI_DEVICE_ID_VIA_82C505 0x0505 #define PCI_DEVICE_ID_VIA_82C561 0x0561 #define PCI_DEVICE_ID_VIA_82C586_1 0x0571 @@ -888,6 +889,7 @@ #define PCI_DEVICE_ID_VIA_82C686_5 0x3058 #define PCI_DEVICE_ID_VIA_82C686_6 0x3068 #define PCI_DEVICE_ID_VIA_86C100A 0x6100 +#define PCI_DEVICE_ID_VIA_8501_1 0x8501 #define PCI_DEVICE_ID_VIA_82C597_1 0x8597 #define PCI_DEVICE_ID_VIA_82C598_1 0x8598

--------------FC0512895E4D8D8F45DEFF1B--

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/