From: Linus Torvalds Date: Fri, 23 Nov 2007 20:33:02 +0000 (-0500) Subject: Import 2.3.99pre2-3 X-Git-Tag: 2.3.99pre2-3 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=66c7a8e910a328219acb665f4dde79ed4537a3c7;p=history.git Import 2.3.99pre2-3 --- diff --git a/CREDITS b/CREDITS index 612d97d27e35..f5437e76b51a 100644 --- a/CREDITS +++ b/CREDITS @@ -1368,6 +1368,11 @@ E: lam836@cs.cuhk.hk D: Author of the dialog utility, foundation D: for Menuconfig's lxdialog. +N: Paul Laufer +E: pelaufer@csupomona.edu +D: Soundblaster driver fixes, ISAPnP quirk +S: California, USA + N: Tom Lees E: tom@lpsg.demon.co.uk W: http://www.lpsg.demon.co.uk/ diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 98dcf4d097bd..a9230e95f1df 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -323,19 +323,42 @@ CONFIG_BLK_DEV_NBD ATA/IDE/MFM/RLL support CONFIG_IDE If you say Y here, your kernel will be able to manage low cost mass storage - units such as ATA,IDE and ATAPI units. - ATA is. - Integrated Disk Electronics (IDE) is a subset of the ATA interface. Quite a - number of disks use IDE interface. State of the art disks use SCSI + units such as ATA/(E)IDE and ATAPI units. + + Integrated Disk Electronics (IDE aka ATA-1) is a connecting standard for + mass storage units such as hard disks. It was designed by Western Digital + and Compaq Computer in 1984. It was then named ST506. + Quite a number of disks use IDE interface. State of the art disks use SCSI interface. - ATAPI is a protocol used by IDE tape and CDROM drives, similar in many - respects to the SCSI protocol. + + AT Atachment (ATA) is a subset of the IDE specifications. + ST506 was also called ATA-1. + + Fast-IDE is ATA-2 (also named Fast ATA), Enhanced IDE (EIDE) is ATA-3. It + provides support for larger disks (up to 8.4GB by means of the LBA standard), + more disks (4 instead of 2) and for other mass storage units such as tapes + and cdrom. + UDMA/33 (aka UltraDMA/33) is ATA-4 and provides faster (and more CPU friendly) + transfer modes than previous PIO (Programmed processor Input/Ouput) from + previous ATA/IDE standards by means of fast DMA controlers. + + ATA Packet Interface (ATAPI) is a protocol used by EIDE tape and CDROM + drives, similar in many respects to the SCSI protocol. + + SMART IDE (Self Monitoring, Analysis and Reporting Technology) was designed + in order to prevent data corruption and disk crash by detecting pre hardware + faillure conditions (heat, access time, and the like...). Disks builded since + june 1995 may follow this standard. The kernel itself don't manage this; + however there are quite a number of user programs such as smart that can + query the status of SMART parameters disk. If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read Documentation/modules.txt. The module will be called ide.o. + For further information, please read Documentation/ide.txt. + If unsure, say Y. Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support diff --git a/Makefile b/Makefile index aef535ce2778..782263e609eb 100644 --- a/Makefile +++ b/Makefile @@ -380,7 +380,7 @@ mrproper: clean archmrproper rm -rf include/config rm -f .depend `find . -type f -name .depend -print` rm -f core `find . -type f -size 0 -print` - rm -f .hdepend scripts/mkdep scripts/split-include + rm -f .hdepend scripts/mkdep scripts/split-include scripts/docproc rm -f $(TOPDIR)/include/linux/modversions.h rm -rf $(TOPDIR)/include/linux/modules diff --git a/arch/alpha/config.in b/arch/alpha/config.in index df7ae01ca2f4..d70d42421314 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -126,6 +126,7 @@ if [ "$CONFIG_ALPHA_MIATA" = "y" -o "$CONFIG_ALPHA_LX164" = "y" \ then define_bool CONFIG_PCI y define_bool CONFIG_ALPHA_EV5 y + define_bool CONFIG_ALPHA_CIA y define_bool CONFIG_ALPHA_PYXIS y fi if [ "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_EIGER" = "y" ] diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index 6c538f4bafb5..9d87b6e0c218 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -18,7 +18,7 @@ O_OBJS := entry.o traps.o process.o osf_sys.o irq.o irq_alpha.o \ OX_OBJS := alpha_ksyms.o L_TARGET := rest.a -L_OBJS := irq_i8259.o irq_srm.o \ +L_OBJS := irq_i8259.o irq_srm.o irq_pyxis.o \ es1888.o smc37c669.o smc37c93x.o ns87312.o ifdef CONFIG_SMP @@ -32,7 +32,7 @@ endif ifdef CONFIG_ALPHA_GENERIC O_OBJS += core_apecs.o core_cia.o core_irongate.o core_lca.o core_mcpcia.o \ - core_polaris.o core_pyxis.o core_t2.o core_tsunami.o \ + core_polaris.o core_t2.o core_tsunami.o \ sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o sys_eiger.o \ sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o \ sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \ @@ -56,9 +56,6 @@ endif ifdef CONFIG_ALPHA_MCPCIA O_OBJS += core_mcpcia.o endif -ifdef CONFIG_ALPHA_PYXIS -O_OBJS += core_pyxis.o -endif ifdef CONFIG_ALPHA_T2 O_OBJS += core_t2.o endif diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c index b8a7f18eeb55..481a682b1857 100644 --- a/arch/alpha/kernel/core_cia.c +++ b/arch/alpha/kernel/core_cia.c @@ -6,7 +6,7 @@ * * Copyright (C) 1995 David A Rusling * Copyright (C) 1997, 1998 Jay Estabrook - * Copyright (C) 1998, 1999 Richard Henderson + * Copyright (C) 1998, 1999, 2000 Richard Henderson * * Code common to all CIA core logic chips. */ @@ -25,6 +25,8 @@ #include #undef __EXTERN_INLINE +#include + #include "proto.h" #include "pci_impl.h" @@ -35,27 +37,20 @@ * handle the system transaction. Another involves timing. Ho hum. */ -/* - * BIOS32-style PCI interface: - */ - #define DEBUG_CONFIG 0 -#define DEBUG_DUMP_REGS 0 - #if DEBUG_CONFIG # define DBGC(args) printk args #else # define DBGC(args) #endif -#define vuip volatile unsigned int * +#define vip volatile int * /* * Given a bus, device, and function number, compute resulting - * configuration space address and setup the CIA_HAXR2 register - * accordingly. It is therefore not safe to have concurrent - * invocations to configuration space access routines, but there - * really shouldn't be any need for this. + * configuration space address. It is therefore not safe to have + * concurrent invocations to configuration space access routines, but + * there really shouldn't be any need for this. * * Type 0: * @@ -96,34 +91,16 @@ static int mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr, unsigned char *type1) { - unsigned long addr; u8 bus = dev->bus->number; u8 device_fn = dev->devfn; - DBGC(("mk_conf_addr(bus=%d, device_fn=0x%x, where=0x%x, " - "pci_addr=0x%p, type1=0x%p)\n", - bus, device_fn, where, pci_addr, type1)); + *type1 = (bus != 0); + *pci_addr = (bus << 16) | (device_fn << 8) | where; - if (bus == 0) { - int device = device_fn >> 3; + DBGC(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x," + " returning address 0x%p\n" + bus, device_fn, where, *pci_addr)); - /* Type 0 configuration cycle. */ - - if (device > 20) { - DBGC(("mk_conf_addr: device (%d) > 20, returning -1\n", - device)); - return -1; - } - - *type1 = 0; - addr = (device_fn << 8) | (where); - } else { - /* Type 1 configuration cycle. */ - *type1 = 1; - addr = (bus << 16) | (device_fn << 8) | (where); - } - *pci_addr = addr; - DBGC(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); return 0; } @@ -131,43 +108,37 @@ static unsigned int conf_read(unsigned long addr, unsigned char type1) { unsigned long flags; - unsigned int stat0, value; - unsigned int cia_cfg = 0; + int stat0, value; + int cia_cfg = 0; - value = 0xffffffffU; - mb(); - - __save_and_cli(flags); /* avoid getting hit by machine check */ - - DBGC(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1)); + DBGC(("conf_read(addr=0x%lx, type1=%d) ", addr, type1)); + __save_and_cli(flags); /* Reset status register to avoid losing errors. */ - stat0 = *(vuip)CIA_IOC_CIA_ERR; - *(vuip)CIA_IOC_CIA_ERR = stat0; + stat0 = *(vip)CIA_IOC_CIA_ERR; + *(vip)CIA_IOC_CIA_ERR = stat0; mb(); - DBGC(("conf_read: CIA ERR was 0x%x\n", stat0)); /* If Type1 access, must set CIA CFG. */ if (type1) { - cia_cfg = *(vuip)CIA_IOC_CFG; - *(vuip)CIA_IOC_CFG = cia_cfg | 1; + cia_cfg = *(vip)CIA_IOC_CFG; + *(vip)CIA_IOC_CFG = (cia_cfg & ~3) | 1; mb(); - DBGC(("conf_read: TYPE1 access\n")); + *(vip)CIA_IOC_CFG; } - mb(); draina(); mcheck_expected(0) = 1; mcheck_taken(0) = 0; mb(); /* Access configuration space. */ - value = *(vuip)addr; + value = *(vip)addr; mb(); mb(); /* magic */ if (mcheck_taken(0)) { mcheck_taken(0) = 0; - value = 0xffffffffU; + value = 0xffffffff; mb(); } mcheck_expected(0) = 0; @@ -175,13 +146,14 @@ conf_read(unsigned long addr, unsigned char type1) /* If Type1 access, must reset IOC CFG so normal IO space ops work. */ if (type1) { - *(vuip)CIA_IOC_CFG = cia_cfg & ~1; + *(vip)CIA_IOC_CFG = cia_cfg; mb(); + *(vip)CIA_IOC_CFG; } - DBGC(("conf_read(): finished\n")); - __restore_flags(flags); + DBGC(("done\n")); + return value; } @@ -189,31 +161,31 @@ static void conf_write(unsigned long addr, unsigned int value, unsigned char type1) { unsigned long flags; - unsigned int stat0; - unsigned int cia_cfg = 0; + int stat0, cia_cfg = 0; - __save_and_cli(flags); /* avoid getting hit by machine check */ + DBGC(("conf_write(addr=0x%lx, type1=%d) ", addr, type1)); + __save_and_cli(flags); /* Reset status register to avoid losing errors. */ - stat0 = *(vuip)CIA_IOC_CIA_ERR; - *(vuip)CIA_IOC_CIA_ERR = stat0; + stat0 = *(vip)CIA_IOC_CIA_ERR; + *(vip)CIA_IOC_CIA_ERR = stat0; mb(); - DBGC(("conf_write: CIA ERR was 0x%x\n", stat0)); /* If Type1 access, must set CIA CFG. */ if (type1) { - cia_cfg = *(vuip)CIA_IOC_CFG; - *(vuip)CIA_IOC_CFG = cia_cfg | 1; + cia_cfg = *(vip)CIA_IOC_CFG; + *(vip)CIA_IOC_CFG = (cia_cfg & ~3) | 1; mb(); - DBGC(("conf_write: TYPE1 access\n")); + *(vip)CIA_IOC_CFG; } draina(); mcheck_expected(0) = 1; + mcheck_taken(0) = 0; mb(); /* Access configuration space. */ - *(vuip)addr = value; + *(vip)addr = value; mb(); mb(); /* magic */ @@ -222,12 +194,13 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1) /* If Type1 access, must reset IOC CFG so normal IO space ops work. */ if (type1) { - *(vuip)CIA_IOC_CFG = cia_cfg & ~1; + *(vip)CIA_IOC_CFG = cia_cfg; mb(); + *(vip)CIA_IOC_CFG; } - DBGC(("conf_write(): finished\n")); __restore_flags(flags); + DBGC(("done\n")); } static int @@ -314,158 +287,442 @@ struct pci_ops cia_pci_ops = write_dword: cia_write_config_dword }; +/* + * CIA Pass 1 and PYXIS Pass 1 and 2 have a broken scatter-gather tlb. + * It cannot be invalidated. Rather than hard code the pass numbers, + * actually try the tbia to see if it works. + */ + void cia_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end) { wmb(); *(vip)CIA_IOC_PCI_TBIA = 3; /* Flush all locked and unlocked. */ mb(); + *(vip)CIA_IOC_PCI_TBIA; +} + +/* + * Fixup attempt number 1. + * + * Write zeros directly into the tag registers. + */ + +static void +cia_pci_tbi_try1(struct pci_controler *hose, + dma_addr_t start, dma_addr_t end) +{ + wmb(); + *(vip)CIA_IOC_TB_TAGn(0) = 0; + *(vip)CIA_IOC_TB_TAGn(1) = 0; + *(vip)CIA_IOC_TB_TAGn(2) = 0; + *(vip)CIA_IOC_TB_TAGn(3) = 0; + *(vip)CIA_IOC_TB_TAGn(4) = 0; + *(vip)CIA_IOC_TB_TAGn(5) = 0; + *(vip)CIA_IOC_TB_TAGn(6) = 0; + *(vip)CIA_IOC_TB_TAGn(7) = 0; + mb(); + *(vip)CIA_IOC_TB_TAGn(0); +} + +#if 0 +/* + * Fixup attempt number 2. This is the method NT and NetBSD use. + * + * Allocate mappings, and put the chip into DMA loopback mode to read a + * garbage page. This works by causing TLB misses, causing old entries to + * be purged to make room for the new entries coming in for the garbage page. + */ + +#define CIA_BROKEN_TBI_TRY2_BASE 0xE0000000 + +static void __init +cia_enable_broken_tbi_try2(void) +{ + unsigned long *ppte, pte; + long i; + + ppte = __alloc_bootmem(PAGE_SIZE, 32768, 0); + pte = (virt_to_phys(ppte) >> (PAGE_SHIFT - 1)) | 1; + + for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); ++i) + ppte[i] = pte; + + *(vip)CIA_IOC_PCI_W3_BASE = CIA_BROKEN_TBI_TRY2_BASE | 3; + *(vip)CIA_IOC_PCI_W3_MASK = (PAGE_SIZE - 1) & 0xfff00000; + *(vip)CIA_IOC_PCI_T3_BASE = virt_to_phys(ppte) >> 2; +} + +static void +cia_pci_tbi_try2(struct pci_controler *hose, + dma_addr_t start, dma_addr_t end) +{ + unsigned long flags; + unsigned long bus_addr; + int ctrl; + long i; + + __save_and_cli(flags); + + /* Put the chip into PCI loopback mode. */ + mb(); + ctrl = *(vip)CIA_IOC_CIA_CTRL; + *(vip)CIA_IOC_CIA_CTRL = ctrl | CIA_CTRL_PCI_LOOP_EN; + mb(); + *(vip)CIA_IOC_CIA_CTRL; + mb(); + + /* Read from PCI dense memory space at TBI_ADDR, skipping 32k on + each read. This forces SG TLB misses. NetBSD claims that the + TLB entries are not quite LRU, meaning that we need to read more + times than there are actual tags. The 2117x docs claim strict + round-robin. Oh well, we've come this far... */ + + bus_addr = cia_ioremap(CIA_BROKEN_TBI_TRY2_BASE); + for (i = 0; i < 12; ++i, bus_addr += 32768) + cia_readl(bus_addr); + + /* Restore normal PCI operation. */ + mb(); + *(vip)CIA_IOC_CIA_CTRL = ctrl; + mb(); + *(vip)CIA_IOC_CIA_CTRL; + mb(); + + __restore_flags(flags); +} +#endif + +static void __init +verify_tb_operation(void) +{ + static int page[PAGE_SIZE/4] + __attribute__((aligned(PAGE_SIZE))) + __initlocaldata = { 0 }; + + struct pci_iommu_arena *arena = pci_isa_hose->sg_isa; + int ctrl, addr0, tag0, pte0, data0; + int temp; + + /* Put the chip into PCI loopback mode. */ + mb(); + ctrl = *(vip)CIA_IOC_CIA_CTRL; + *(vip)CIA_IOC_CIA_CTRL = ctrl | CIA_CTRL_PCI_LOOP_EN; + mb(); + *(vip)CIA_IOC_CIA_CTRL; + mb(); + + /* Write a valid entry directly into the TLB registers. */ + + addr0 = arena->dma_base; + tag0 = addr0 | 1; + pte0 = (virt_to_phys(page) >> (PAGE_SHIFT - 1)) | 1; + + *(vip)CIA_IOC_TB_TAGn(0) = tag0; + *(vip)CIA_IOC_TB_TAGn(1) = 0; + *(vip)CIA_IOC_TB_TAGn(2) = 0; + *(vip)CIA_IOC_TB_TAGn(3) = 0; + *(vip)CIA_IOC_TB_TAGn(4) = 0; + *(vip)CIA_IOC_TB_TAGn(5) = 0; + *(vip)CIA_IOC_TB_TAGn(6) = 0; + *(vip)CIA_IOC_TB_TAGn(7) = 0; + *(vip)CIA_IOC_TBn_PAGEm(0,0) = pte0; + *(vip)CIA_IOC_TBn_PAGEm(0,1) = 0; + *(vip)CIA_IOC_TBn_PAGEm(0,2) = 0; + *(vip)CIA_IOC_TBn_PAGEm(0,3) = 0; + mb(); + + /* First, verify we can read back what we've written. If + this fails, we can't be sure of any of the other testing + we're going to do, so bail. */ + /* ??? Actually, we could do the work with machine checks. + By passing this register update test, we pretty much + guarantee that cia_pci_tbi_try1 works. If this test + fails, cia_pci_tbi_try2 might still work. */ + + temp = *(vip)CIA_IOC_TB_TAGn(0); + if (temp != tag0) { + printk("pci: failed tb register update test " + "(tag0 %#x != %#x)\n", temp, tag0); + goto failed; + } + temp = *(vip)CIA_IOC_TB_TAGn(1); + if (temp != 0) { + printk("pci: failed tb register update test " + "(tag1 %#x != 0)\n", temp); + goto failed; + } + temp = *(vip)CIA_IOC_TBn_PAGEm(0,0); + if (temp != pte0) { + printk("pci: failed tb register update test " + "(pte0 %#x != %#x)\n", temp, pte0); + goto failed; + } + printk("pci: passed tb register update test\n"); + + /* Second, verify we can actually do I/O through this entry. */ + + data0 = 0xdeadbeef; + page[0] = data0; + mcheck_expected(0) = 1; + mcheck_taken(0) = 0; + mb(); + temp = cia_readl(cia_ioremap(addr0)); + mb(); + mcheck_expected(0) = 0; + mb(); + if (mcheck_taken(0)) { + printk("pci: failed sg loopback i/o read test (mcheck)\n"); + goto failed; + } + if (temp != data0) { + printk("pci: failed sg loopback i/o read test " + "(%#x != %#x)\n", temp, data0); + goto failed; + } + printk("pci: passed sg loopback i/o read test\n"); + + /* Third, try to invalidate the TLB. */ + + cia_pci_tbi(arena->hose, 0, -1); + temp = *(vip)CIA_IOC_TB_TAGn(0); + if (temp & 1) { + cia_pci_tbi_try1(arena->hose, 0, -1); + + temp = *(vip)CIA_IOC_TB_TAGn(0); + if (temp & 1) { + printk("pci: failed tbia test; " + "no usable workaround\n"); + goto failed; + } + + alpha_mv.mv_pci_tbi = cia_pci_tbi_try1; + printk("pci: failed tbia test; workaround 1 succeeded\n"); + } else { + printk("pci: passed tbia test\n"); + } + + /* Fourth, verify the TLB snoops the EV5's caches when + doing a tlb fill. */ + + data0 = 0x5adda15e; + page[0] = data0; + arena->ptes[4] = pte0; + mcheck_expected(0) = 1; + mcheck_taken(0) = 0; + mb(); + temp = cia_readl(cia_ioremap(addr0 + 4*PAGE_SIZE)); + mb(); + mcheck_expected(0) = 0; + mb(); + if (mcheck_taken(0)) { + printk("pci: failed pte write cache snoop test (mcheck)\n"); + goto failed; + } + if (temp != data0) { + printk("pci: failed pte write cache snoop test " + "(%#x != %#x)\n", temp, data0); + goto failed; + } + printk("pci: passed pte write cache snoop test\n"); + + /* Fifth, verify that a previously invalid PTE entry gets + filled from the page table. */ + + data0 = 0xabcdef123; + page[0] = data0; + arena->ptes[5] = pte0; + mcheck_expected(0) = 1; + mcheck_taken(0) = 0; + mb(); + temp = cia_readl(cia_ioremap(addr0 + 5*PAGE_SIZE)); + mb(); + mcheck_expected(0) = 0; + mb(); + if (mcheck_taken(0)) { + printk("pci: failed valid tag invalid pte reload test " + "(mcheck; workaround available)\n"); + /* Work around this bug by aligning new allocations + on 4 page boundaries. */ + arena->align_entry = 4; + } else if (temp != data0) { + printk("pci: failed valid tag invalid pte reload test " + "(%#x != %#x)\n", temp, data0); + goto failed; + } else { + printk("pci: passed valid tag invalid pte reload test\n"); + } + + /* Sixth, verify machine checks are working. Test invalid + pte under the same valid tag as we used above. */ + + mcheck_expected(0) = 1; + mcheck_taken(0) = 0; + mb(); + temp = cia_readl(cia_ioremap(addr0 + 6*PAGE_SIZE)); + mb(); + mcheck_expected(0) = 0; + mb(); + printk("pci: %s pci machine check test\n", + mcheck_taken(0) ? "passed" : "failed"); + + /* Clean up after the tests. */ + arena->ptes[4] = 0; + arena->ptes[5] = 0; + alpha_mv.mv_pci_tbi(arena->hose, 0, -1); + +exit: + /* Restore normal PCI operation. */ + mb(); + *(vip)CIA_IOC_CIA_CTRL = ctrl; + mb(); + *(vip)CIA_IOC_CIA_CTRL; + mb(); + return; + +failed: + printk("pci: disabling sg translation window\n"); + *(vip)CIA_IOC_PCI_W0_BASE = 0; + alpha_mv.mv_pci_tbi = NULL; + goto exit; } -void __init -cia_init_arch(void) +static void __init +do_init_arch(int is_pyxis) { struct pci_controler *hose; - struct resource *hae_mem; - unsigned int temp; - -#if DEBUG_DUMP_REGS - temp = *(vuip)CIA_IOC_CIA_REV; mb(); - printk("cia_init: CIA_REV was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_PCI_LAT; mb(); - printk("cia_init: CIA_PCI_LAT was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_CIA_CTRL; mb(); - printk("cia_init: CIA_CTRL was 0x%x\n", temp); - temp = *(vuip)0xfffffc8740000140UL; mb(); - printk("cia_init: CIA_CTRL1 was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_HAE_MEM; mb(); - printk("cia_init: CIA_HAE_MEM was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_HAE_IO; mb(); - printk("cia_init: CIA_HAE_IO was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_CFG; mb(); - printk("cia_init: CIA_CFG was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_CACK_EN; mb(); - printk("cia_init: CIA_CACK_EN was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_CFG; mb(); - printk("cia_init: CIA_CFG was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_CIA_DIAG; mb(); - printk("cia_init: CIA_DIAG was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_DIAG_CHECK; mb(); - printk("cia_init: CIA_DIAG_CHECK was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_PERF_MONITOR; mb(); - printk("cia_init: CIA_PERF_MONITOR was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_PERF_CONTROL; mb(); - printk("cia_init: CIA_PERF_CONTROL was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_CIA_ERR; mb(); - printk("cia_init: CIA_ERR was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_CIA_STAT; mb(); - printk("cia_init: CIA_STAT was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_MCR; mb(); - printk("cia_init: CIA_MCR was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_CIA_CTRL; mb(); - printk("cia_init: CIA_CTRL was 0x%x\n", temp); - temp = *(vuip)CIA_IOC_ERR_MASK; mb(); - printk("cia_init: CIA_ERR_MASK was 0x%x\n", temp); - temp = *((vuip)CIA_IOC_PCI_W0_BASE); mb(); - printk("cia_init: W0_BASE was 0x%x\n", temp); - temp = *((vuip)CIA_IOC_PCI_W1_BASE); mb(); - printk("cia_init: W1_BASE was 0x%x\n", temp); - temp = *((vuip)CIA_IOC_PCI_W2_BASE); mb(); - printk("cia_init: W2_BASE was 0x%x\n", temp); - temp = *((vuip)CIA_IOC_PCI_W3_BASE); mb(); - printk("cia_init: W3_BASE was 0x%x\n", temp); -#endif /* DEBUG_DUMP_REGS */ + int temp; + int cia_rev; + + cia_rev = *(vip)CIA_IOC_CIA_REV & CIA_REV_MASK; + printk("pci: cia revision %d%s\n", + cia_rev, is_pyxis ? " (pyxis)" : ""); + + /* Set up error reporting. */ + temp = *(vip)CIA_IOC_ERR_MASK; + temp &= ~(CIA_ERR_CPU_PE | CIA_ERR_MEM_NEM | CIA_ERR_PA_PTE_INV + | CIA_ERR_RCVD_MAS_ABT | CIA_ERR_RCVD_TAR_ABT); + *(vip)CIA_IOC_ERR_MASK = temp; + + /* Clear all currently pending errors. */ + *(vip)CIA_IOC_CIA_ERR = 0; + + /* Turn on mchecks. */ + temp = *(vip)CIA_IOC_CIA_CTRL; + temp |= CIA_CTRL_FILL_ERR_EN | CIA_CTRL_MCHK_ERR_EN; + *(vip)CIA_IOC_CIA_CTRL = temp; + + /* Clear the CFG register, which gets used for PCI config space + accesses. That is the way we want to use it, and we do not + want to depend on what ARC or SRM might have left behind. */ + *(vip)CIA_IOC_CFG = 0; + + /* Zero the HAEs. */ + *(vip)CIA_IOC_HAE_MEM = 0; + *(vip)CIA_IOC_HAE_IO = 0; + + /* For PYXIS, we always use BWX bus and i/o accesses. To that end, + make sure they're enabled on the controler. */ + if (is_pyxis) { + temp = *(vip)CIA_IOC_CIA_CNFG; + temp |= CIA_CNFG_IOA_BWEN; + *(vip)CIA_IOC_CIA_CNFG = temp; + } + + /* Syncronize with all previous changes. */ + mb(); + *(vip)CIA_IOC_CIA_REV; /* * Create our single hose. */ pci_isa_hose = hose = alloc_pci_controler(); - hae_mem = alloc_resource(); - hose->io_space = &ioport_resource; - hose->mem_space = hae_mem; + hose->mem_space = &iomem_resource; hose->config_space = CIA_CONF; hose->index = 0; - hae_mem->start = 0; - hae_mem->end = CIA_MEM_R1_MASK; - hae_mem->name = pci_hae0_name; - hae_mem->flags = IORESOURCE_MEM; + if (! is_pyxis) { + struct resource *hae_mem = alloc_resource(); + hose->mem_space = hae_mem; + + hae_mem->start = 0; + hae_mem->end = CIA_MEM_R1_MASK; + hae_mem->name = pci_hae0_name; + hae_mem->flags = IORESOURCE_MEM; - if (request_resource(&iomem_resource, hae_mem) < 0) - printk(KERN_ERR "Failed to request HAE_MEM\n"); + if (request_resource(&iomem_resource, hae_mem) < 0) + printk(KERN_ERR "Failed to request HAE_MEM\n"); + } /* * Set up the PCI to main memory translation windows. * * Window 0 is scatter-gather 8MB at 8MB (for isa) - * Window 1 is scatter-gather 128MB at 1GB - * Window 2 is direct access 2GB at 2GB - * ??? We ought to scale window 1 with memory. + * Window 1 is direct access 1GB at 1GB + * Window 2 is direct access 1GB at 2GB + * + * We must actually use 2 windows to direct-map the 2GB space, + * because of an idiot-syncrasy of the CYPRESS chip used on + * many PYXIS systems. It may respond to a PCI bus address in + * the last 1MB of the 4GB address range. + * + * ??? NetBSD hints that page tables must be aligned to 32K, + * possibly due to a hardware bug. This is over-aligned + * from the 8K alignment one would expect for an 8MB window. + * No description of what revisions affected. */ - /* ??? NetBSD hints that page tables must be aligned to 32K, - possibly due to a hardware bug. This is over-aligned - from the 8K alignment one would expect for an 8MB window. - No description of what CIA revisions affected. */ - hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0x8000); - hose->sg_pci = iommu_arena_new(hose, 0x40000000, 0x08000000, 0); - __direct_map_base = 0x80000000; + hose->sg_pci = NULL; + hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 32768); + __direct_map_base = 0x40000000; __direct_map_size = 0x80000000; - *(vuip)CIA_IOC_PCI_W0_BASE = hose->sg_isa->dma_base | 3; - *(vuip)CIA_IOC_PCI_W0_MASK = (hose->sg_isa->size - 1) & 0xfff00000; - *(vuip)CIA_IOC_PCI_T0_BASE = virt_to_phys(hose->sg_isa->ptes) >> 2; - - *(vuip)CIA_IOC_PCI_W1_BASE = hose->sg_pci->dma_base | 3; - *(vuip)CIA_IOC_PCI_W1_MASK = (hose->sg_pci->size - 1) & 0xfff00000; - *(vuip)CIA_IOC_PCI_T1_BASE = virt_to_phys(hose->sg_pci->ptes) >> 2; + *(vip)CIA_IOC_PCI_W0_BASE = hose->sg_isa->dma_base | 3; + *(vip)CIA_IOC_PCI_W0_MASK = (hose->sg_isa->size - 1) & 0xfff00000; + *(vip)CIA_IOC_PCI_T0_BASE = virt_to_phys(hose->sg_isa->ptes) >> 2; - *(vuip)CIA_IOC_PCI_W2_BASE = __direct_map_base | 1; - *(vuip)CIA_IOC_PCI_W2_MASK = (__direct_map_size - 1) & 0xfff00000; - *(vuip)CIA_IOC_PCI_T2_BASE = 0; + *(vip)CIA_IOC_PCI_W1_BASE = 0x40000000 | 1; + *(vip)CIA_IOC_PCI_W1_MASK = (0x40000000 - 1) & 0xfff00000; + *(vip)CIA_IOC_PCI_T1_BASE = 0; - *(vuip)CIA_IOC_PCI_W3_BASE = 0; + *(vip)CIA_IOC_PCI_W2_BASE = 0x80000000 | 1; + *(vip)CIA_IOC_PCI_W2_MASK = (0x40000000 - 1) & 0xfff00000; + *(vip)CIA_IOC_PCI_T2_BASE = 0x40000000; - cia_pci_tbi(hose, 0, -1); + *(vip)CIA_IOC_PCI_W3_BASE = 0; +} - /* - * Set up error reporting. - */ - temp = *(vuip)CIA_IOC_CIA_ERR; - temp |= 0x180; /* master, target abort */ - *(vuip)CIA_IOC_CIA_ERR = temp; +void __init +cia_init_arch(void) +{ + do_init_arch(0); +} - temp = *(vuip)CIA_IOC_CIA_CTRL; - temp |= 0x400; /* turn on FILL_ERR to get mchecks */ - *(vuip)CIA_IOC_CIA_CTRL = temp; +void __init +pyxis_init_arch(void) +{ + do_init_arch(1); +} - /* - * Next, clear the CIA_CFG register, which gets used - * for PCI Config Space accesses. That is the way - * we want to use it, and we do not want to depend on - * what ARC or SRM might have left behind... - */ - *(vuip)CIA_IOC_CFG = 0; - - /* - * Zero the HAEs. - */ - *(vuip)CIA_IOC_HAE_MEM = 0; - *(vuip)CIA_IOC_HAE_IO = 0; - mb(); +void __init +cia_init_pci(void) +{ + /* Must delay this from init_arch, as we need machine checks. */ + verify_tb_operation(); + common_init_pci(); } static inline void cia_pci_clr_err(void) { - unsigned int jd; + int jd; - jd = *(vuip)CIA_IOC_CIA_ERR; - *(vuip)CIA_IOC_CIA_ERR = jd; + jd = *(vip)CIA_IOC_CIA_ERR; + *(vip)CIA_IOC_CIA_ERR = jd; mb(); - *(vuip)CIA_IOC_CIA_ERR; /* re-read to force write. */ + *(vip)CIA_IOC_CIA_ERR; /* re-read to force write. */ } void diff --git a/arch/alpha/kernel/core_pyxis.c b/arch/alpha/kernel/core_pyxis.c deleted file mode 100644 index f6106c47546c..000000000000 --- a/arch/alpha/kernel/core_pyxis.c +++ /dev/null @@ -1,644 +0,0 @@ -/* - * linux/arch/alpha/kernel/core_pyxis.c - * - * Based on code written by David A Rusling (david.rusling@reo.mts.dec.com). - * - * Code common to all PYXIS core logic chips. - */ - -#include -#include - -#define __EXTERN_INLINE inline -#include -#include -#undef __EXTERN_INLINE - -#include -#include -#include -#include - -#include -#include - -#include "proto.h" -#include "irq_impl.h" -#include "pci_impl.h" - - -/* NOTE: Herein are back-to-back mb instructions. They are magic. - One plausible explanation is that the I/O controller does not properly - handle the system transaction. Another involves timing. Ho hum. */ - -/* - * BIOS32-style PCI interface: - */ - -#define DEBUG_CONFIG 0 -#if DEBUG_CONFIG -# define DBG_CNF(args) printk args -#else -# define DBG_CNF(args) -#endif - - -/* - * Given a bus, device, and function number, compute resulting - * configuration space address and setup the PYXIS_HAXR2 register - * accordingly. It is therefore not safe to have concurrent - * invocations to configuration space access routines, but there - * really shouldn't be any need for this. - * - * Type 0: - * - * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 - * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0| - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * 31:11 Device select bit. - * 10:8 Function number - * 7:2 Register number - * - * Type 1: - * - * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 - * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1| - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * 31:24 reserved - * 23:16 bus number (8 bits = 128 possible buses) - * 15:11 Device number (5 bits) - * 10:8 function number - * 7:2 register number - * - * Notes: - * The function number selects which function of a multi-function device - * (e.g., SCSI and Ethernet). - * - * The register selects a DWORD (32 bit) register offset. Hence it - * doesn't get shifted by 2 bits as we want to "drop" the bottom two - * bits. - */ - -static int -mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr, - unsigned char *type1) -{ - u8 bus = dev->bus->number; - u8 device_fn = dev->devfn; - - *type1 = (bus == 0) ? 0 : 1; - *pci_addr = (bus << 16) | (device_fn << 8) | (where); - - DBG_CNF(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x," - " returning address 0x%p\n" - bus, device_fn, where, *pci_addr)); - - return 0; -} - -static unsigned int -conf_read(unsigned long addr, unsigned char type1) -{ - unsigned long flags; - unsigned int stat0, value, temp; - unsigned int pyxis_cfg = 0; - - __save_and_cli(flags); /* avoid getting hit by machine check */ - - /* Reset status register to avoid losing errors. */ - stat0 = *(vuip)PYXIS_ERR; - *(vuip)PYXIS_ERR = stat0; mb(); - temp = *(vuip)PYXIS_ERR; /* re-read to force write */ - - /* If Type1 access, must set PYXIS CFG. */ - if (type1) { - pyxis_cfg = *(vuip)PYXIS_CFG; - *(vuip)PYXIS_CFG = (pyxis_cfg & ~3L) | 1; mb(); - temp = *(vuip)PYXIS_CFG; /* re-read to force write */ - } - - mb(); - draina(); - mcheck_expected(0) = 1; - mcheck_taken(0) = 0; - mb(); - - /* Access configuration space. */ - value = *(vuip)addr; - mb(); - mb(); /* magic */ - - if (mcheck_taken(0)) { - mcheck_taken(0) = 0; - value = 0xffffffffU; - mb(); - } - mcheck_expected(0) = 0; - mb(); - - /* If Type1 access, must reset IOC CFG so normal IO space ops work. */ - if (type1) { - *(vuip)PYXIS_CFG = pyxis_cfg & ~3L; mb(); - temp = *(vuip)PYXIS_CFG; /* re-read to force write */ - } - - __restore_flags(flags); - - DBG_CNF(("conf_read(addr=0x%lx, type1=%d) = %#x\n", - addr, type1, value)); - - return value; -} - -static void -conf_write(unsigned long addr, unsigned int value, unsigned char type1) -{ - unsigned long flags; - unsigned int stat0, temp; - unsigned int pyxis_cfg = 0; - - __save_and_cli(flags); /* avoid getting hit by machine check */ - - /* Reset status register to avoid losing errors. */ - stat0 = *(vuip)PYXIS_ERR; - *(vuip)PYXIS_ERR = stat0; mb(); - temp = *(vuip)PYXIS_ERR; /* re-read to force write */ - - /* If Type1 access, must set PYXIS CFG. */ - if (type1) { - pyxis_cfg = *(vuip)PYXIS_CFG; - *(vuip)PYXIS_CFG = (pyxis_cfg & ~3L) | 1; mb(); - temp = *(vuip)PYXIS_CFG; /* re-read to force write */ - } - - mb(); - draina(); - mcheck_expected(0) = 1; - mcheck_taken(0) = 0; - mb(); - - /* Access configuration space. */ - *(vuip)addr = value; - mb(); - temp = *(vuip)addr; /* read back to force the write */ - mcheck_expected(0) = 0; - mb(); - - /* If Type1 access, must reset IOC CFG so normal IO space ops work. */ - if (type1) { - *(vuip)PYXIS_CFG = pyxis_cfg & ~3L; mb(); - temp = *(vuip)PYXIS_CFG; /* re-read to force write */ - } - - __restore_flags(flags); - - DBG_CNF(("conf_write(addr=%#lx, value=%#x, type1=%d)\n", - addr, value, type1)); -} - -static int -pyxis_read_config_byte(struct pci_dev *dev, int where, u8 *value) -{ - unsigned long addr, pci_addr; - unsigned char type1; - - if (mk_conf_addr(dev, where, &pci_addr, &type1)) - return PCIBIOS_DEVICE_NOT_FOUND; - - addr = (pci_addr << 5) + 0x00 + PYXIS_CONF; - *value = conf_read(addr, type1) >> ((where & 3) * 8); - return PCIBIOS_SUCCESSFUL; -} - -static int -pyxis_read_config_word(struct pci_dev *dev, int where, u16 *value) -{ - unsigned long addr, pci_addr; - unsigned char type1; - - if (mk_conf_addr(dev, where, &pci_addr, &type1)) - return PCIBIOS_DEVICE_NOT_FOUND; - - addr = (pci_addr << 5) + 0x08 + PYXIS_CONF; - *value = conf_read(addr, type1) >> ((where & 3) * 8); - return PCIBIOS_SUCCESSFUL; -} - -static int -pyxis_read_config_dword(struct pci_dev *dev, int where, u32 *value) -{ - unsigned long addr, pci_addr; - unsigned char type1; - - if (mk_conf_addr(dev, where, &pci_addr, &type1)) - return PCIBIOS_DEVICE_NOT_FOUND; - - addr = (pci_addr << 5) + 0x18 + PYXIS_CONF; - *value = conf_read(addr, type1); - return PCIBIOS_SUCCESSFUL; -} - -static int -pyxis_write_config(struct pci_dev *dev, int where, u32 value, long mask) -{ - unsigned long addr, pci_addr; - unsigned char type1; - - if (mk_conf_addr(dev, where, &pci_addr, &type1)) - return PCIBIOS_DEVICE_NOT_FOUND; - - addr = (pci_addr << 5) + mask + PYXIS_CONF; - conf_write(addr, value << ((where & 3) * 8), type1); - return PCIBIOS_SUCCESSFUL; -} - -static int -pyxis_write_config_byte(struct pci_dev *dev, int where, u8 value) -{ - return pyxis_write_config(dev, where, value, 0x00); -} - -static int -pyxis_write_config_word(struct pci_dev *dev, int where, u16 value) -{ - return pyxis_write_config(dev, where, value, 0x08); -} - -static int -pyxis_write_config_dword(struct pci_dev *dev, int where, u32 value) -{ - return pyxis_write_config(dev, where, value, 0x18); -} - -struct pci_ops pyxis_pci_ops = -{ - read_byte: pyxis_read_config_byte, - read_word: pyxis_read_config_word, - read_dword: pyxis_read_config_dword, - write_byte: pyxis_write_config_byte, - write_word: pyxis_write_config_word, - write_dword: pyxis_write_config_dword -}; - -/* Note mask bit is true for ENABLED irqs. */ -static unsigned long cached_irq_mask; - -static inline void -pyxis_update_irq_hw(unsigned long mask) -{ - *(vulp)PYXIS_INT_MASK = mask; - mb(); - *(vulp)PYXIS_INT_MASK; -} - -static inline void -pyxis_enable_irq(unsigned int irq) -{ - pyxis_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16)); -} - -static void -pyxis_disable_irq(unsigned int irq) -{ - pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16))); -} - -static unsigned int -pyxis_startup_irq(unsigned int irq) -{ - pyxis_enable_irq(irq); - return 0; -} - -static void -pyxis_end_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - pyxis_enable_irq(irq); -} - -static void -pyxis_mask_and_ack_irq(unsigned int irq) -{ - unsigned long bit = 1UL << (irq - 16); - unsigned long mask = cached_irq_mask &= ~bit; - - /* Disable the interrupt. */ - *(vulp)PYXIS_INT_MASK = mask; - wmb(); - /* Ack PYXIS PCI interrupt. */ - *(vulp)PYXIS_INT_REQ = bit; - mb(); - /* Re-read to force both writes. */ - *(vulp)PYXIS_INT_MASK; -} - -static struct hw_interrupt_type pyxis_irq_type = { - typename: "PYXIS", - startup: pyxis_startup_irq, - shutdown: pyxis_disable_irq, - enable: pyxis_enable_irq, - disable: pyxis_disable_irq, - ack: pyxis_mask_and_ack_irq, - end: pyxis_end_irq, -}; - -void -pyxis_device_interrupt(unsigned long vector, struct pt_regs *regs) -{ - unsigned long pld; - unsigned int i; - - /* Read the interrupt summary register of PYXIS */ - pld = *(vulp)PYXIS_INT_REQ; - pld &= cached_irq_mask; - - /* - * Now for every possible bit set, work through them and call - * the appropriate interrupt handler. - */ - while (pld) { - i = ffz(~pld); - pld &= pld - 1; /* clear least bit set */ - if (i == 7) - isa_device_interrupt(vector, regs); - else - handle_irq(16+i, regs); - } -} - -void __init -init_pyxis_irqs(unsigned long ignore_mask) -{ - long i; - - *(vulp)PYXIS_INT_MASK = 0; /* disable all */ - *(vulp)PYXIS_INT_REQ = -1; /* flush all */ - mb(); - - /* Send -INTA pulses to clear any pending interrupts ...*/ - *(vuip) PYXIS_IACK_SC; - - for (i = 16; i < 48; ++i) { - if ((ignore_mask >> i) & 1) - continue; - irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &pyxis_irq_type; - } - - setup_irq(16+7, &isa_cascade_irqaction); -} - -void -pyxis_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end) -{ - wmb(); - *(vip)PYXIS_TBIA = 3; /* Flush all locked and unlocked. */ - mb(); -} - -/* - * Pass 1 and 2 have a broken scatter-gather tlb -- it cannot be invalidated. - * To work around this problem, we allocate mappings, and put the chip into - * DMA loopback mode to read a garbage page. This works by causing TLB - * misses, causing old entries to be purged to make room for the new entries - * coming in for the garbage page. - * - * Thanks to NetBSD sources for pointing out this bug. What a pain. - */ - -static unsigned long broken_tbi_addr; - -#define BROKEN_TBI_READS 12 - -static void -pyxis_broken_pci_tbi(struct pci_controler *hose, - dma_addr_t start, dma_addr_t end) -{ - unsigned long flags; - unsigned long bus_addr; - unsigned int ctrl; - long i; - - __save_and_cli(flags); - - /* Put the chip into PCI loopback mode. */ - mb(); - ctrl = *(vuip)PYXIS_CTRL; - *(vuip)PYXIS_CTRL = ctrl | 4; - mb(); - *(vuip)PYXIS_CTRL; - mb(); - - /* Read from PCI dense memory space at TBI_ADDR, skipping 64k - on each read. This forces SG TLB misses. It appears that - the TLB entries are "not quite LRU", meaning that we need - to read more times than there are actual tags. */ - - bus_addr = broken_tbi_addr; - for (i = 0; i < BROKEN_TBI_READS; ++i, bus_addr += 64*1024) - pyxis_readl(bus_addr); - - /* Restore normal PCI operation. */ - mb(); - *(vuip)PYXIS_CTRL = ctrl; - mb(); - *(vuip)PYXIS_CTRL; - mb(); - - __restore_flags(flags); -} - -static void __init -pyxis_enable_broken_tbi(struct pci_iommu_arena *arena) -{ - void *page; - unsigned long *ppte, ofs, pte; - long i, npages; - - page = alloc_bootmem_pages(PAGE_SIZE); - pte = (virt_to_phys(page) >> (PAGE_SHIFT - 1)) | 1; - npages = (BROKEN_TBI_READS + 1) * 64*1024 / PAGE_SIZE; - - ofs = iommu_arena_alloc(arena, npages); - ppte = arena->ptes + ofs; - for (i = 0; i < npages; ++i) - ppte[i] = pte; - - broken_tbi_addr = pyxis_ioremap(arena->dma_base + ofs*PAGE_SIZE); - alpha_mv.mv_pci_tbi = pyxis_broken_pci_tbi; - - printk("PYXIS: Enabling broken tbia workaround.\n"); -} - -void __init -pyxis_init_arch(void) -{ - struct pci_controler *hose; - unsigned int temp; - - /* Set up error reporting. Make sure CPU_PE is OFF in the mask. */ - temp = *(vuip)PYXIS_ERR_MASK; - *(vuip)PYXIS_ERR_MASK = temp & ~4; - - /* Enable master/target abort. */ - temp = *(vuip)PYXIS_ERR; - *(vuip)PYXIS_ERR = temp | 0x180; - - /* Clear the PYXIS_CFG register, which gets used for PCI Config - Space accesses. That is the way we want to use it, and we do - not want to depend on what ARC or SRM might have left behind. */ - *(vuip)PYXIS_CFG = 0; - - /* Zero the HAEs. */ - *(vuip)PYXIS_HAE_MEM = 0; - *(vuip)PYXIS_HAE_IO = 0; - - /* Finally, check that the PYXIS_CTRL1 has IOA_BEN set for - enabling byte/word PCI bus space(s) access. */ - temp = *(vuip)PYXIS_CTRL1; - *(vuip)PYXIS_CTRL1 = temp | 1; - - /* Syncronize with all previous changes. */ - mb(); - *(vuip)PYXIS_REV; - - /* - * Create our single hose. - */ - - hose = alloc_pci_controler(); - hose->io_space = &ioport_resource; - hose->mem_space = &iomem_resource; - hose->config_space = PYXIS_CONF; - hose->index = 0; - - /* - * Set up the PCI to main memory translation windows. - * - * Window 0 is scatter-gather 8MB at 8MB (for isa) - * Window 1 is scatter-gather 128MB at 3GB - * Window 2 is direct access 1GB at 1GB - * Window 3 is direct access 1GB at 2GB - * ??? We ought to scale window 1 with memory. - * - * We must actually use 2 windows to direct-map the 2GB space, - * because of an idiot-syncrasy of the CYPRESS chip. It may - * respond to a PCI bus address in the last 1MB of the 4GB - * address range. - */ - -#if 1 - /* ??? There's some bit of syncronization wrt writing new tlb - entries that's missing. Sometimes it works, sometimes invalid - tlb machine checks, sometimes hard lockup. And this just within - the boot sequence. - - I've tried extra memory barriers, extra alignment, pyxis - register reads, tlb flushes, and loopback tlb accesses. - - I guess the pyxis revision in the sx164 is just too buggy... */ - - hose->sg_isa = hose->sg_pci = NULL; - __direct_map_base = 0x40000000; - __direct_map_size = 0x80000000; - - *(vuip)PYXIS_W0_BASE = 0x40000000 | 1; - *(vuip)PYXIS_W0_MASK = (0x40000000 - 1) & 0xfff00000; - *(vuip)PYXIS_T0_BASE = 0; - - *(vuip)PYXIS_W1_BASE = 0x80000000 | 1; - *(vuip)PYXIS_W1_MASK = (0x40000000 - 1) & 0xfff00000; - *(vuip)PYXIS_T1_BASE = 0; - - *(vuip)PYXIS_W2_BASE = 0; - *(vuip)PYXIS_W3_BASE = 0; - - alpha_mv.mv_pci_tbi = NULL; - mb(); -#else - /* ??? NetBSD hints that page tables must be aligned to 32K, - possibly due to a hardware bug. This is over-aligned - from the 8K alignment one would expect for an 8MB window. - No description of what CIA revisions affected. */ - hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0x08000); - hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x08000000, 0x20000); - __direct_map_base = 0x40000000; - __direct_map_size = 0x80000000; - - *(vuip)PYXIS_W0_BASE = hose->sg_isa->dma_base | 3; - *(vuip)PYXIS_W0_MASK = (hose->sg_isa->size - 1) & 0xfff00000; - *(vuip)PYXIS_T0_BASE = virt_to_phys(hose->sg_isa->ptes) >> 2; - - *(vuip)PYXIS_W1_BASE = hose->sg_pci->dma_base | 3; - *(vuip)PYXIS_W1_MASK = (hose->sg_pci->size - 1) & 0xfff00000; - *(vuip)PYXIS_T1_BASE = virt_to_phys(hose->sg_pci->ptes) >> 2; - - *(vuip)PYXIS_W2_BASE = 0x40000000 | 1; - *(vuip)PYXIS_W2_MASK = (0x40000000 - 1) & 0xfff00000; - *(vuip)PYXIS_T2_BASE = 0; - - *(vuip)PYXIS_W3_BASE = 0x80000000 | 1; - *(vuip)PYXIS_W3_MASK = (0x40000000 - 1) & 0xfff00000; - *(vuip)PYXIS_T3_BASE = 0; - - /* Pass 1 and 2 (ie revision <= 1) have a broken TBIA. See the - complete description next to pyxis_broken_pci_tbi for details. */ - if ((*(vuip)PYXIS_REV & 0xff) <= 1) - pyxis_enable_broken_tbi(hose->sg_pci); - - alpha_mv.mv_pci_tbi(hose, 0, -1); -#endif -} - -static inline void -pyxis_pci_clr_err(void) -{ - unsigned int tmp; - - tmp = *(vuip)PYXIS_ERR; - *(vuip)PYXIS_ERR = tmp; - mb(); - *(vuip)PYXIS_ERR; /* re-read to force write */ -} - -void -pyxis_machine_check(unsigned long vector, unsigned long la_ptr, - struct pt_regs * regs) -{ - int expected; - - /* Clear the error before reporting anything. */ - mb(); - mb(); /* magic */ - draina(); - pyxis_pci_clr_err(); - wrmces(0x7); - mb(); - - expected = mcheck_expected(0); - if (!expected && vector == 0x660) { - struct el_common *com; - struct el_common_EV5_uncorrectable_mcheck *ev5; - struct el_PYXIS_sysdata_mcheck *pyxis; - - com = (void *)la_ptr; - ev5 = (void *)(la_ptr + com->proc_offset); - pyxis = (void *)(la_ptr + com->sys_offset); - - if (com->code == 0x202) { - printk(KERN_CRIT "PYXIS PCI machine check: err0=%08x " - "err1=%08x err2=%08x\n", - (int) pyxis->pci_err0, (int) pyxis->pci_err1, - (int) pyxis->pci_err2); - expected = 1; - } - } - process_mcheck_info(vector, la_ptr, regs, "PYXIS", expected); -} diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c index 1fa5a808847a..1ddcd36d146f 100644 --- a/arch/alpha/kernel/core_tsunami.c +++ b/arch/alpha/kernel/core_tsunami.c @@ -363,7 +363,7 @@ tsunami_init_one_pchip(tsunami_pchip *pchip, int index) pchip->wsba[3].csr = 0x80000000 | 1; pchip->wsm[3].csr = (0x40000000 - 1) & 0xfff00000; - pchip->tba[3].csr = 0; + pchip->tba[3].csr = 0x40000000; tsunami_pci_tbi(hose, 0, -1); } diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 5f1a6f59a590..0b9e1786d086 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -8,7 +8,7 @@ #define SIGCHLD 20 -#define NR_SYSCALLS 374 +#define NR_SYSCALLS 376 /* * These offsets must match with alpha_mv in . @@ -991,7 +991,7 @@ sys_call_table: .quad osf_shmat .quad sys_shmctl /* 210 */ .quad sys_shmdt - .quad osf_shmget + .quad sys_shmget .quad alpha_ni_syscall .quad alpha_ni_syscall .quad alpha_ni_syscall /* 215 */ @@ -1154,4 +1154,5 @@ sys_call_table: .quad sys_setresgid .quad sys_getresgid .quad sys_ni_syscall /* sys_dipc */ - .quad sys_shmget + .quad sys_pivot_root + .quad sys_mincore /* 375 */ diff --git a/arch/alpha/kernel/irq_pyxis.c b/arch/alpha/kernel/irq_pyxis.c new file mode 100644 index 000000000000..65414a7f50ee --- /dev/null +++ b/arch/alpha/kernel/irq_pyxis.c @@ -0,0 +1,127 @@ +/* + * linux/arch/alpha/kernel/irq_pyxis.c + * + * Based on code written by David A Rusling (david.rusling@reo.mts.dec.com). + * + * IRQ Code common to all PYXIS core logic chips. + */ + +#include +#include +#include + +#include +#include + +#include "proto.h" +#include "irq_impl.h" + + +/* Note mask bit is true for ENABLED irqs. */ +static unsigned long cached_irq_mask; + +static inline void +pyxis_update_irq_hw(unsigned long mask) +{ + *(vulp)PYXIS_INT_MASK = mask; + mb(); + *(vulp)PYXIS_INT_MASK; +} + +static inline void +pyxis_enable_irq(unsigned int irq) +{ + pyxis_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16)); +} + +static void +pyxis_disable_irq(unsigned int irq) +{ + pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16))); +} + +static unsigned int +pyxis_startup_irq(unsigned int irq) +{ + pyxis_enable_irq(irq); + return 0; +} + +static void +pyxis_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + pyxis_enable_irq(irq); +} + +static void +pyxis_mask_and_ack_irq(unsigned int irq) +{ + unsigned long bit = 1UL << (irq - 16); + unsigned long mask = cached_irq_mask &= ~bit; + + /* Disable the interrupt. */ + *(vulp)PYXIS_INT_MASK = mask; + wmb(); + /* Ack PYXIS PCI interrupt. */ + *(vulp)PYXIS_INT_REQ = bit; + mb(); + /* Re-read to force both writes. */ + *(vulp)PYXIS_INT_MASK; +} + +static struct hw_interrupt_type pyxis_irq_type = { + typename: "PYXIS", + startup: pyxis_startup_irq, + shutdown: pyxis_disable_irq, + enable: pyxis_enable_irq, + disable: pyxis_disable_irq, + ack: pyxis_mask_and_ack_irq, + end: pyxis_end_irq, +}; + +void +pyxis_device_interrupt(unsigned long vector, struct pt_regs *regs) +{ + unsigned long pld; + unsigned int i; + + /* Read the interrupt summary register of PYXIS */ + pld = *(vulp)PYXIS_INT_REQ; + pld &= cached_irq_mask; + + /* + * Now for every possible bit set, work through them and call + * the appropriate interrupt handler. + */ + while (pld) { + i = ffz(~pld); + pld &= pld - 1; /* clear least bit set */ + if (i == 7) + isa_device_interrupt(vector, regs); + else + handle_irq(16+i, regs); + } +} + +void __init +init_pyxis_irqs(unsigned long ignore_mask) +{ + long i; + + *(vulp)PYXIS_INT_MASK = 0; /* disable all */ + *(vulp)PYXIS_INT_REQ = -1; /* flush all */ + mb(); + + /* Send -INTA pulses to clear any pending interrupts ...*/ + *(vuip) CIA_IACK_SC; + + for (i = 16; i < 48; ++i) { + if ((ignore_mask >> i) & 1) + continue; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; + irq_desc[i].handler = &pyxis_irq_type; + } + + setup_irq(16+7, &isa_cascade_irqaction); +} diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c index 8b14a59fe912..51806c9962e4 100644 --- a/arch/alpha/kernel/irq_srm.c +++ b/arch/alpha/kernel/irq_srm.c @@ -6,9 +6,6 @@ #include #include -#include -#include - #include "proto.h" #include "irq_impl.h" diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h index cc55781cbc7f..bc9c0d3de41c 100644 --- a/arch/alpha/kernel/machvec_impl.h +++ b/arch/alpha/kernel/machvec_impl.h @@ -77,27 +77,26 @@ mv_writew: CAT(low,_writew), \ mv_writel: CAT(low,_writel), \ mv_writeq: CAT(low,_writeq), \ - mv_ioremap: CAT(low,_ioremap), \ - mv_is_ioaddr: CAT(low,_is_ioaddr) + mv_ioremap: CAT(low,_ioremap) \ #define IO(UP,low) \ IO_LITE(UP,low), \ pci_ops: &CAT(low,_pci_ops) -/* Any assembler that can generate a GENERIC kernel can generate BWX - instructions. So always use them for PYXIS I/O. */ - #define DO_APECS_IO IO(APECS,apecs) #define DO_CIA_IO IO(CIA,cia) #define DO_IRONGATE_IO IO(IRONGATE,irongate) #define DO_LCA_IO IO(LCA,lca) #define DO_MCPCIA_IO IO(MCPCIA,mcpcia) #define DO_POLARIS_IO IO(POLARIS,polaris) -#define DO_PYXIS_IO IO(PYXIS,pyxis) #define DO_T2_IO IO(T2,t2) #define DO_TSUNAMI_IO IO(TSUNAMI,tsunami) +#define DO_PYXIS_IO IO_LITE(CIA,cia_bwx), \ + pci_ops: &CAT(cia,_pci_ops) + #define BUS(which) \ + mv_is_ioaddr: CAT(which,_is_ioaddr), \ mv_pci_tbi: CAT(which,_pci_tbi) #define DO_APECS_BUS BUS(apecs) @@ -105,7 +104,6 @@ #define DO_IRONGATE_BUS BUS(irongate) #define DO_LCA_BUS BUS(lca) #define DO_MCPCIA_BUS BUS(mcpcia) -#define DO_PYXIS_BUS BUS(pyxis) #define DO_POLARIS_BUS BUS(polaris) #define DO_T2_BUS BUS(t2) #define DO_TSUNAMI_BUS BUS(tsunami) diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 091edaf3719b..0395f87f1f72 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -189,15 +189,6 @@ asmlinkage int osf_getpriority(int which, int who, int a2, int a3, int a4, return prio; } - -/* - * Heh. As documented by DEC.. - */ -asmlinkage unsigned long sys_madvise(void) -{ - return 0; -} - /* * No need to acquire the kernel lock, we're local.. */ @@ -1374,8 +1365,3 @@ asmlinkage int sys_old_adjtimex(struct timex32 *txc_p) return ret; } - -asmlinkage long osf_shmget (key_t key, int size, int flag) -{ - return sys_shmget (key, size, flag); -} diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h index 3aee6ec34f85..f434b329dbdd 100644 --- a/arch/alpha/kernel/pci_impl.h +++ b/arch/alpha/kernel/pci_impl.h @@ -138,6 +138,7 @@ struct pci_iommu_arena dma_addr_t dma_base; unsigned int size; unsigned int next_entry; + unsigned int align_entry; }; diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 9e7e13e9bf50..5a36aa578d77 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -67,6 +67,10 @@ iommu_arena_new(struct pci_controler *hose, dma_addr_t base, arena->size = window_size; arena->next_entry = 0; + /* Align allocations to a multiple of a page size. Not needed + unless there are chip bugs. */ + arena->align_entry = 1; + return arena; } @@ -74,28 +78,36 @@ long iommu_arena_alloc(struct pci_iommu_arena *arena, long n) { unsigned long flags; - unsigned long *beg, *p, *end; - long i; + unsigned long *ptes; + long i, p, nent, mask; spin_lock_irqsave(&arena->lock, flags); /* Search forward for the first sequence of N empty ptes. */ - beg = arena->ptes; - end = beg + (arena->size >> PAGE_SHIFT); - p = beg + arena->next_entry; + ptes = arena->ptes; + nent = arena->size >> PAGE_SHIFT; + mask = arena->align_entry - 1; + p = (arena->next_entry + mask) & ~mask; i = 0; - while (i < n && p < end) - i = (*p++ == 0 ? i + 1 : 0); + while (i < n && p+i < nent) { + if (ptes[p+i]) + p = (p + i + 1 + mask) & ~mask, i = 0; + else + i = i + 1; + } if (i < n) { /* Reached the end. Flush the TLB and restart the search from the beginning. */ alpha_mv.mv_pci_tbi(arena->hose, 0, -1); - p = beg; - i = 0; - while (i < n && p < end) - i = (*p++ == 0 ? i + 1 : 0); + p = 0, i = 0; + while (i < n && p+i < nent) { + if (ptes[p+i]) + p = (p + i + 1 + mask) & ~mask, i = 0; + else + i = i + 1; + } if (i < n) { spin_unlock_irqrestore(&arena->lock, flags); @@ -107,13 +119,13 @@ iommu_arena_alloc(struct pci_iommu_arena *arena, long n) bit zero is the valid bit, so write ~1 into everything. The chip specific bits will fill this in with something kosher when we return. */ - for (p = p - n, i = 0; i < n; ++i) - p[i] = ~1UL; + for (i = 0; i < n; ++i) + ptes[p+i] = ~1UL; - arena->next_entry = p - beg + n; + arena->next_entry = p + n; spin_unlock_irqrestore(&arena->lock, flags); - return p - beg; + return p; } static void @@ -238,6 +250,12 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, long size, npages = calc_npages((dma_addr & ~PAGE_MASK) + size); iommu_arena_free(arena, dma_ofs, npages); + /* If we're freeing ptes above the `next_entry' pointer, they + may have snuck back into the TLB since the last wrap flush. + We need to flush the TLB before reallocating these. */ + if (dma_ofs >= arena->next_entry) + alpha_mv.mv_pci_tbi(hose, dma_addr, dma_addr + size - 1); + DBGA("pci_unmap_single: sg [%x,%lx] np %ld from %p\n", dma_addr, size, npages, __builtin_return_address(0)); } @@ -509,6 +527,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, struct pci_iommu_arena *arena; struct scatterlist *end; dma_addr_t max_dma; + dma_addr_t fbeg, fend; if (direction == PCI_DMA_NONE) BUG(); @@ -522,9 +541,11 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, if (!arena || arena->dma_base + arena->size > max_dma) arena = hose->sg_isa; + fbeg = -1, fend = 0; for (end = sg + nents; sg < end; ++sg) { unsigned long addr, size; long npages, ofs; + dma_addr_t tend; addr = sg->dma_address; size = sg->dma_length; @@ -547,8 +568,18 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, npages = calc_npages((addr & ~PAGE_MASK) + size); ofs = (addr - arena->dma_base) >> PAGE_SHIFT; iommu_arena_free(arena, ofs, npages); + + tend = addr + size - 1; + if (fbeg > addr) fbeg = addr; + if (fend < tend) fend = tend; } + /* If we're freeing ptes above the `next_entry' pointer, they + may have snuck back into the TLB since the last wrap flush. + We need to flush the TLB before reallocating these. */ + if ((fend - arena->dma_base) >> PAGE_SHIFT >= arena->next_entry) + alpha_mv.mv_pci_tbi(hose, fbeg, fend); + DBGA("pci_unmap_sg: %d entries\n", nents - (end - sg)); } diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index 8e7bbcfaf46a..f13edeebf206 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -20,7 +20,9 @@ extern void apecs_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t); /* core_cia.c */ extern struct pci_ops cia_pci_ops; +extern void cia_init_pci(void); extern void cia_init_arch(void); +extern void pyxis_init_arch(void); extern void cia_machine_check(u64, u64, struct pt_regs *); extern void cia_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t); @@ -52,12 +54,6 @@ extern void polaris_init_arch(void); extern void polaris_machine_check(u64, u64, struct pt_regs *); #define polaris_pci_tbi ((void *)0) -/* core_pyxis.c */ -extern struct pci_ops pyxis_pci_ops; -extern void pyxis_init_arch(void); -extern void pyxis_machine_check(u64, u64, struct pt_regs *); -extern void pyxis_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t); - /* core_t2.c */ extern struct pci_ops t2_pci_ops; extern void t2_init_arch(void); diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c index 867d762f84df..656a0a8df108 100644 --- a/arch/alpha/kernel/sys_alcor.c +++ b/arch/alpha/kernel/sys_alcor.c @@ -249,7 +249,7 @@ struct alpha_machine_vector alcor_mv __initmv = { init_arch: cia_init_arch, init_irq: alcor_init_irq, init_rtc: common_init_rtc, - init_pci: common_init_pci, + init_pci: cia_init_pci, kill_arch: alcor_kill_arch, pci_map_irq: alcor_map_irq, pci_swizzle: common_swizzle, @@ -279,7 +279,7 @@ struct alpha_machine_vector xlt_mv __initmv = { init_arch: cia_init_arch, init_irq: alcor_init_irq, init_rtc: common_init_rtc, - init_pci: common_init_pci, + init_pci: cia_init_pci, kill_arch: alcor_kill_arch, pci_map_irq: alcor_map_irq, pci_swizzle: common_swizzle, diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c index 8e016ada0fca..9b2b39d73b49 100644 --- a/arch/alpha/kernel/sys_cabriolet.c +++ b/arch/alpha/kernel/sys_cabriolet.c @@ -3,7 +3,7 @@ * * Copyright (C) 1995 David A Rusling * Copyright (C) 1996 Jay A Estabrook - * Copyright (C) 1998, 1999 Richard Henderson + * Copyright (C) 1998, 1999, 2000 Richard Henderson * * Code supporting the Cabriolet (AlphaPC64), EB66+, and EB164, * PC164 and LX164. @@ -28,7 +28,6 @@ #include #include #include -#include #include "proto.h" #include "irq_impl.h" @@ -223,6 +222,12 @@ cabriolet_init_pci(void) ns87312_enable_ide(0x398); } +static inline void __init +cia_cab_init_pci(void) +{ + cia_init_pci(); + ns87312_enable_ide(0x398); +} /* * The PC164 and LX164 have 19 PCI interrupts, four from each of the four @@ -286,7 +291,7 @@ alphapc164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) static inline void __init alphapc164_init_pci(void) { - common_init_pci(); + cia_init_pci(); SMC93x_Init(); } @@ -339,7 +344,7 @@ struct alpha_machine_vector eb164_mv __initmv = { init_arch: cia_init_arch, init_irq: cabriolet_init_irq, init_rtc: common_init_rtc, - init_pci: cabriolet_init_pci, + init_pci: cia_cab_init_pci, pci_map_irq: cabriolet_map_irq, pci_swizzle: common_swizzle, }; @@ -377,8 +382,8 @@ struct alpha_machine_vector lx164_mv __initmv = { DO_EV5_MMU, DO_DEFAULT_RTC, DO_PYXIS_IO, - DO_PYXIS_BUS, - machine_check: pyxis_machine_check, + DO_CIA_BUS, + machine_check: cia_machine_check, max_dma_address: ALPHA_MAX_DMA_ADDRESS, min_io_address: DEFAULT_IO_BASE, min_mem_address: DEFAULT_MEM_BASE, diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index 63abc109f671..4735a08f6ead 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -36,32 +36,31 @@ /* Note mask bit is true for ENABLED irqs. */ static unsigned long cached_irq_mask; /* dp264 boards handle at max four CPUs */ -static unsigned long cpu_irq_affinity[4]; +static unsigned long cpu_irq_affinity[4] = { ~0UL, ~0UL, ~0UL, ~0UL }; spinlock_t dp264_irq_lock = SPIN_LOCK_UNLOCKED; static void -tsunami_update_irq_hw(unsigned long mask, unsigned long isa_enable) +tsunami_update_irq_hw(unsigned long mask) { register tsunami_cchip *cchip = TSUNAMI_cchip; + unsigned long isa_enable = 1UL << 55; register int bcpu = boot_cpuid; #ifdef CONFIG_SMP register unsigned long cpm = cpu_present_mask; volatile unsigned long *dim0, *dim1, *dim2, *dim3; - unsigned long mask0, mask1, mask2, mask3, maskB, dummy; + unsigned long mask0, mask1, mask2, mask3, dummy; - mask0 = mask1 = mask2 = mask3 = mask; - maskB = mask | isa_enable; - if (bcpu == 0) mask0 = maskB; - else if (bcpu == 1) mask1 = maskB; - else if (bcpu == 2) mask2 = maskB; - else if (bcpu == 3) mask3 = maskB; + mask0 = mask & cpu_irq_affinity[0]; + mask1 = mask & cpu_irq_affinity[1]; + mask2 = mask & cpu_irq_affinity[2]; + mask3 = mask & cpu_irq_affinity[3]; - mask0 &= cpu_irq_affinity[0]; - mask1 &= cpu_irq_affinity[1]; - mask2 &= cpu_irq_affinity[2]; - mask3 &= cpu_irq_affinity[3]; + if (bcpu == 0) mask0 |= isa_enable; + else if (bcpu == 1) mask1 |= isa_enable; + else if (bcpu == 2) mask2 |= isa_enable; + else mask3 |= isa_enable; dim0 = &cchip->dim0.csr; dim1 = &cchip->dim1.csr; @@ -86,7 +85,7 @@ tsunami_update_irq_hw(unsigned long mask, unsigned long isa_enable) if (bcpu == 0) dimB = &cchip->dim0.csr; else if (bcpu == 1) dimB = &cchip->dim1.csr; else if (bcpu == 2) dimB = &cchip->dim2.csr; - else if (bcpu == 3) dimB = &cchip->dim3.csr; + else dimB = &cchip->dim3.csr; *dimB = mask | isa_enable; mb(); @@ -94,24 +93,12 @@ tsunami_update_irq_hw(unsigned long mask, unsigned long isa_enable) #endif } -static inline void -dp264_update_irq_hw(unsigned long mask) -{ - tsunami_update_irq_hw(mask, (1UL << 55) | 0xffff); -} - -static inline void -clipper_update_irq_hw(unsigned long mask) -{ - tsunami_update_irq_hw(mask, 1UL << 55); -} - static void dp264_enable_irq(unsigned int irq) { spin_lock(&dp264_irq_lock); cached_irq_mask |= 1UL << irq; - dp264_update_irq_hw(cached_irq_mask); + tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); } @@ -120,7 +107,7 @@ dp264_disable_irq(unsigned int irq) { spin_lock(&dp264_irq_lock); cached_irq_mask &= ~(1UL << irq); - dp264_update_irq_hw(cached_irq_mask); + tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); } @@ -142,8 +129,8 @@ static void clipper_enable_irq(unsigned int irq) { spin_lock(&dp264_irq_lock); - cached_irq_mask |= 1UL << irq; - clipper_update_irq_hw(cached_irq_mask); + cached_irq_mask |= 1UL << (irq - 16); + tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); } @@ -151,8 +138,8 @@ static void clipper_disable_irq(unsigned int irq) { spin_lock(&dp264_irq_lock); - cached_irq_mask &= ~(1UL << irq); - clipper_update_irq_hw(cached_irq_mask); + cached_irq_mask &= ~(1UL << (irq - 16)); + tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); } @@ -191,7 +178,7 @@ dp264_set_affinity(unsigned int irq, unsigned long affinity) { spin_lock(&dp264_irq_lock); cpu_set_irq_affinity(irq, affinity); - dp264_update_irq_hw(cached_irq_mask); + tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); } @@ -199,8 +186,8 @@ static void clipper_set_affinity(unsigned int irq, unsigned long affinity) { spin_lock(&dp264_irq_lock); - cpu_set_irq_affinity(irq, affinity); - clipper_update_irq_hw(cached_irq_mask); + cpu_set_irq_affinity(irq - 16, affinity); + tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); } @@ -304,12 +291,10 @@ clipper_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) } static void __init -init_tsunami_irqs(struct hw_interrupt_type * ops) +init_tsunami_irqs(struct hw_interrupt_type * ops, int imin, int imax) { long i; - - /* Only irqs between 16 and 47 are tsunami irqs. */ - for (i = 16; i < 48; ++i) { + for (i = imin; i <= imax; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = ops; } @@ -328,13 +313,10 @@ dp264_init_irq(void) if (alpha_using_srm) alpha_mv.device_interrupt = dp264_srm_device_interrupt; - /* this is single threaded by design so no need of any smp lock */ - for (cpu = 0; cpu < 4; cpu++) - cpu_irq_affinity[cpu] = ~0UL; - dp264_update_irq_hw(0UL); + tsunami_update_irq_hw(0); init_i8259a_irqs(); - init_tsunami_irqs(&dp264_irq_type); + init_tsunami_irqs(&dp264_irq_type, 16, 47); } static void __init @@ -348,10 +330,10 @@ clipper_init_irq(void) if (alpha_using_srm) alpha_mv.device_interrupt = clipper_srm_device_interrupt; - clipper_update_irq_hw(0UL); + tsunami_update_irq_hw(0); init_i8259a_irqs(); - init_tsunami_irqs(&clipper_irq_type); + init_tsunami_irqs(&clipper_irq_type, 24, 63); } diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c index 9e4fbe569237..4545ff0e2788 100644 --- a/arch/alpha/kernel/sys_eiger.c +++ b/arch/alpha/kernel/sys_eiger.c @@ -34,10 +34,6 @@ #include "machvec_impl.h" -/* - * HACK ALERT! only the boot cpu is used for interrupts. - */ - /* Note that this interrupt code is identical to TAKARA. */ /* Note mask bit is true for DISABLED irqs. */ diff --git a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c index 0191ef91b96c..f54de2c874c9 100644 --- a/arch/alpha/kernel/sys_miata.c +++ b/arch/alpha/kernel/sys_miata.c @@ -3,7 +3,7 @@ * * Copyright (C) 1995 David A Rusling * Copyright (C) 1996 Jay A Estabrook - * Copyright (C) 1998, 1999 Richard Henderson + * Copyright (C) 1998, 1999, 2000 Richard Henderson * * Code supporting the MIATA (EV56+PYXIS). */ @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include "proto.h" #include "irq_impl.h" @@ -215,7 +215,7 @@ miata_swizzle(struct pci_dev *dev, u8 *pinp) static void __init miata_init_pci(void) { - common_init_pci(); + cia_init_pci(); SMC669_Init(0); /* it might be a GL (fails harmlessly if not) */ es1888_init(); } @@ -240,8 +240,8 @@ struct alpha_machine_vector miata_mv __initmv = { DO_EV5_MMU, DO_DEFAULT_RTC, DO_PYXIS_IO, - DO_PYXIS_BUS, - machine_check: pyxis_machine_check, + DO_CIA_BUS, + machine_check: cia_machine_check, max_dma_address: ALPHA_MAX_DMA_ADDRESS, min_io_address: DEFAULT_IO_BASE, min_mem_address: DEFAULT_MEM_BASE, diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c index a667311546e7..f436b4902013 100644 --- a/arch/alpha/kernel/sys_mikasa.c +++ b/arch/alpha/kernel/sys_mikasa.c @@ -258,7 +258,7 @@ struct alpha_machine_vector mikasa_primo_mv __initmv = { init_arch: cia_init_arch, init_irq: mikasa_init_irq, init_rtc: common_init_rtc, - init_pci: common_init_pci, + init_pci: cia_init_pci, pci_map_irq: mikasa_map_irq, pci_swizzle: common_swizzle, }; diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c index 523d298539ec..8ef79db13e5a 100644 --- a/arch/alpha/kernel/sys_noritake.c +++ b/arch/alpha/kernel/sys_noritake.c @@ -309,7 +309,7 @@ struct alpha_machine_vector noritake_primo_mv __initmv = { init_arch: cia_init_arch, init_irq: noritake_init_irq, init_rtc: common_init_rtc, - init_pci: common_init_pci, + init_pci: cia_init_pci, pci_map_irq: noritake_map_irq, pci_swizzle: noritake_swizzle, }; diff --git a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c index 01d80ab9735d..23069e06dc98 100644 --- a/arch/alpha/kernel/sys_ruffian.c +++ b/arch/alpha/kernel/sys_ruffian.c @@ -3,7 +3,7 @@ * * Copyright (C) 1995 David A Rusling * Copyright (C) 1996 Jay A Estabrook - * Copyright (C) 1998, 1999 Richard Henderson + * Copyright (C) 1998, 1999, 2000 Richard Henderson * * Code supporting the RUFFIAN. */ @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "proto.h" #include "irq_impl.h" @@ -149,8 +149,8 @@ struct alpha_machine_vector ruffian_mv __initmv = { DO_EV5_MMU, DO_DEFAULT_RTC, DO_PYXIS_IO, - DO_PYXIS_BUS, - machine_check: pyxis_machine_check, + DO_CIA_BUS, + machine_check: cia_machine_check, max_dma_address: ALPHA_RUFFIAN_MAX_DMA_ADDRESS, min_io_address: DEFAULT_IO_BASE, min_mem_address: DEFAULT_MEM_BASE, @@ -161,7 +161,7 @@ struct alpha_machine_vector ruffian_mv __initmv = { init_arch: pyxis_init_arch, init_irq: ruffian_init_irq, init_rtc: ruffian_init_rtc, - init_pci: common_init_pci, + init_pci: cia_init_pci, kill_arch: ruffian_kill_arch, pci_map_irq: ruffian_map_irq, pci_swizzle: common_swizzle, diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c index bad57d35ea56..b98e46028312 100644 --- a/arch/alpha/kernel/sys_sx164.c +++ b/arch/alpha/kernel/sys_sx164.c @@ -3,7 +3,7 @@ * * Copyright (C) 1995 David A Rusling * Copyright (C) 1996 Jay A Estabrook - * Copyright (C) 1998, 1999 Richard Henderson + * Copyright (C) 1998, 1999, 2000 Richard Henderson * * Code supporting the SX164 (PCA56+PYXIS). */ @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "proto.h" #include "irq_impl.h" @@ -107,10 +107,10 @@ sx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) return COMMON_TABLE_LOOKUP; } -void __init +static void __init sx164_init_pci(void) { - common_init_pci(); + cia_init_pci(); SMC669_Init(0); } @@ -124,8 +124,8 @@ struct alpha_machine_vector sx164_mv __initmv = { DO_EV5_MMU, DO_DEFAULT_RTC, DO_PYXIS_IO, - DO_PYXIS_BUS, - machine_check: pyxis_machine_check, + DO_CIA_BUS, + machine_check: cia_machine_check, max_dma_address: ALPHA_MAX_DMA_ADDRESS, min_io_address: DEFAULT_IO_BASE, min_mem_address: DEFAULT_MEM_BASE, diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index a0bc57125994..9ebba39553a6 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c @@ -258,7 +258,7 @@ takara_init_pci(void) if (alpha_using_srm) alpha_mv.pci_map_irq = takara_map_irq_srm; - common_init_pci(); + cia_init_pci(); ns87312_enable_ide(0x26e); } diff --git a/arch/i386/kernel/pci-i386.c b/arch/i386/kernel/pci-i386.c index 6dd0a4306af2..942de9c79046 100644 --- a/arch/i386/kernel/pci-i386.c +++ b/arch/i386/kernel/pci-i386.c @@ -323,3 +323,17 @@ int pcibios_enable_resources(struct pci_dev *dev) } return 0; } + +/* + * If we set up a device for bus mastering, we need to check the latency + * timer as certain crappy BIOSes forget to set it properly. + */ +void pcibios_set_master(struct pci_dev *dev) +{ + u8 lat; + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) { + printk("PCI: Increasing latency timer of device %s to 64\n", dev->slot_name); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); + } +} diff --git a/arch/i386/kernel/pci-pc.c b/arch/i386/kernel/pci-pc.c index e51e96e4332a..b588642cc6c3 100644 --- a/arch/i386/kernel/pci-pc.c +++ b/arch/i386/kernel/pci-pc.c @@ -1103,9 +1103,9 @@ static char *pcibios_lookup_irq(struct pci_dev *dev, struct irq_routing_table *r { struct irq_info *q; struct pci_dev *router; - int i, pirq, newirq; + int i, pirq, newirq, reg; u32 rtrid, mask; - u8 x; + u8 x, y; char *msg = NULL; pin--; @@ -1169,14 +1169,44 @@ static char *pcibios_lookup_irq(struct pci_dev *dev, struct irq_routing_table *r DBG(" -> [PIIX] set to %02x\n", newirq); pci_write_config_byte(router, pirq, newirq); msg = "PIIX-NEW"; - } else - DBG(" -> [PIIX] sink\n"); + } else DBG(" -> [PIIX] sink\n"); break; case ID(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533): newirq = ali_set_irq(router, pirq-1, newirq); if (newirq) msg = "ALI"; break; + case ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596): + case ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686): + reg = 0x55 + (pirq >> 1); + pci_read_config_byte(router, reg, &x); + y = (pirq & 1) ? (x >> 4) : (x & 0x0f); + if (y) { + DBG(" -> [VIA] %02x\n", y); + newirq = y; + msg = "VIA"; + } else if (newirq) { + DBG(" -> [VIA] set to %02x\n", newirq); + x = (pirq & 1) ? ((x & 0x0f) | (newirq << 4)) : ((x & 0xf0) | newirq); + pci_write_config_byte(router, reg, y); + msg = "VIA-NEW"; + } else DBG(" -> [VIA] sink\n"); + break; + case ID(PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C700): + reg = 0xb8 + (pirq >> 5); + pci_read_config_byte(router, reg, &x); + y = (pirq & 0x10) ? (x >> 4) : (x & 0x0f); + if (y) { + DBG(" -> [OPTI] %02x\n", y); + newirq = y; + msg = "OPTI"; + } else if (newirq) { + DBG(" -> [OPTI] set to %02x\n", newirq); + x = (pirq & 0x10) ? ((x & 0x0f) | (newirq << 4)) : ((x & 0xf0) | newirq); + pci_write_config_byte(router, reg, y); + msg = "OPTI-NEW"; + } else DBG(" -> [OPTI] sink\n"); + break; default: DBG(" -> unknown router %04x/%04x\n", rt->rtr_vendor, rt->rtr_device); if (newirq && mask == (1 << newirq)) { diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 73a6c2bf7ae0..30595e694eb0 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -756,7 +756,7 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id) id->CurAPMvalues = __le16_to_cpu(id->CurAPMvalues); id->word92 = __le16_to_cpu(id->word92); id->hw_config = __le16_to_cpu(id->hw_config); - for (i=0; i<34; i++) + for (i=0; i<32; i++) id->words94_125[i] = __le16_to_cpu(id->words94_125[i]); id->last_lun = __le16_to_cpu(id->last_lun); id->word127 = __le16_to_cpu(id->word127); diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index e9b506e105ff..b1ed3c2afb44 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -1,4 +1,4 @@ -/* $Id: ioport.c,v 1.35 2000/02/27 08:16:25 davem Exp $ +/* $Id: ioport.c,v 1.36 2000/03/16 08:22:53 anton Exp $ * ioport.c: Simple io mapping allocator. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -745,6 +745,10 @@ void ioport_init(void) halt(); }; +} + +void register_proc_sparc_ioport(void) +{ #ifdef CONFIG_PROC_FS create_proc_read_entry("io_map",0,0,_sparc_io_get_info,&sparc_iomap); create_proc_read_entry("dvma_map",0,0,_sparc_io_get_info,&_sparc_dvma); diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index d4ac34932b54..5966e04d75de 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.115 2000/02/26 04:24:31 davem Exp $ +/* $Id: setup.c,v 1.116 2000/03/15 23:26:22 anton Exp $ * linux/arch/sparc/kernel/setup.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -268,8 +268,6 @@ extern void sun_serial_setup(void); extern unsigned short root_flags; extern unsigned short root_dev; extern unsigned short ram_flags; -extern unsigned sparc_ramdisk_image; -extern unsigned sparc_ramdisk_size; #define RAMDISK_IMAGE_START_MASK 0x07FF #define RAMDISK_PROMPT_FLAG 0x8000 #define RAMDISK_LOAD_FLAG 0x4000 @@ -382,42 +380,9 @@ void __init setup_arch(char **cmdline_p) rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0); rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0); #endif -#ifdef CONFIG_BLK_DEV_INITRD -// FIXME needs to do the new bootmem alloc stuff - if (sparc_ramdisk_image) { - initrd_start = sparc_ramdisk_image; - if (initrd_start < KERNBASE) initrd_start += KERNBASE; - initrd_end = initrd_start + sparc_ramdisk_size; - if (initrd_end > *memory_end_p) { - printk(KERN_CRIT "initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - initrd_end,*memory_end_p); - initrd_start = 0; - } - if (initrd_start >= *memory_start_p && initrd_start < *memory_start_p + 2 * PAGE_SIZE) { - initrd_below_start_ok = 1; - *memory_start_p = PAGE_ALIGN (initrd_end); - } else if (initrd_start && sparc_ramdisk_image < KERNBASE) { - switch (sparc_cpu_model) { - case sun4m: - case sun4d: - initrd_start -= KERNBASE; - initrd_end -= KERNBASE; - break; - default: - break; - } - } - } -#endif + prom_setsync(prom_sync_me); -#ifdef CONFIG_SUN_SERIAL -#if 0 - /* XXX We can't do this until the bootmem allocator is working. */ - sun_serial_setup(); /* set this up ASAP */ -#endif -#endif { #if !CONFIG_SUN_SERIAL serial_console = 0; diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 3ca74e26dd7a..7b7a0eb61ac4 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc_ksyms.c,v 1.95 2000/03/14 08:29:26 davem Exp $ +/* $Id: sparc_ksyms.c,v 1.96 2000/03/16 09:12:49 jj Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -68,6 +68,8 @@ extern void bcopy (const char *, char *, int); extern int __ashrdi3(int, int); extern int __ashldi3(int, int); extern int __lshrdi3(int, int); +extern int __muldi3(int, int); +extern int __divdi3(int, int); extern void dump_thread(struct pt_regs *, struct user *); @@ -273,6 +275,8 @@ EXPORT_SYMBOL_NOVERS(memmove); EXPORT_SYMBOL_NOVERS(__ashrdi3); EXPORT_SYMBOL_NOVERS(__ashldi3); EXPORT_SYMBOL_NOVERS(__lshrdi3); +EXPORT_SYMBOL_NOVERS(__muldi3); +EXPORT_SYMBOL_NOVERS(__divdi3); EXPORT_SYMBOL_DOT(rem); EXPORT_SYMBOL_DOT(urem); diff --git a/arch/sparc/kernel/unaligned.c b/arch/sparc/kernel/unaligned.c index 592a2a4c0096..2f051a6aa9ff 100644 --- a/arch/sparc/kernel/unaligned.c +++ b/arch/sparc/kernel/unaligned.c @@ -1,4 +1,4 @@ -/* $Id: unaligned.c,v 1.20 2000/01/21 11:38:42 jj Exp $ +/* $Id: unaligned.c,v 1.21 2000/03/15 08:50:16 anton Exp $ * unaligned.c: Unaligned load/store trap handling with special * cases for the kernel to do them more quickly. * @@ -106,6 +106,26 @@ static inline unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) return win->locals[reg - 16]; /* yes, I know what this does... */ } +static inline unsigned long safe_fetch_reg(unsigned int reg, struct pt_regs *regs) +{ + struct reg_window *win; + unsigned long ret; + + if(reg < 16) + return (!reg ? 0 : regs->u_regs[reg]); + + /* Ho hum, the slightly complicated case. */ + win = (struct reg_window *) regs->u_regs[UREG_FP]; + + if ((unsigned long)win & 3) + return -1; + + if (get_user(ret, &win->locals[reg - 16])) + return -1; + + return ret; +} + static inline unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) { struct reg_window *win; @@ -132,6 +152,22 @@ static inline unsigned long compute_effective_address(struct pt_regs *regs, } } +static inline unsigned long safe_compute_effective_address(struct pt_regs *regs, + unsigned int insn) +{ + unsigned int rs1 = (insn >> 14) & 0x1f; + unsigned int rs2 = insn & 0x1f; + unsigned int rd = (insn >> 25) & 0x1f; + + if(insn & 0x2000) { + maybe_flush_windows(rs1, 0, rd); + return (safe_fetch_reg(rs1, regs) + sign_extend_imm13(insn)); + } else { + maybe_flush_windows(rs1, rs2, rd); + return (safe_fetch_reg(rs1, regs) + safe_fetch_reg(rs2, regs)); + } +} + /* This is just to make gcc think panic does return... */ static void unaligned_panic(char *str) { @@ -427,7 +463,7 @@ void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRALN; - info.si_addr = (void *)compute_effective_address(regs, insn); + info.si_addr = (void *)safe_compute_effective_address(regs, insn); info.si_trapno = 0; send_sig_info(SIGBUS, &info, current); } diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index d269e148b2fe..8c3e8e4a9f7f 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.32 2000/02/28 04:00:48 anton Exp $ +# $Id: Makefile,v 1.33 2000/03/16 00:52:07 anton Exp $ # Makefile for Sparc library files.. # @@ -6,7 +6,7 @@ OBJS = mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o memcpy.o memset.o \ strlen.o checksum.o blockops.o memscan.o memcmp.o strncmp.o \ strncpy_from_user.o divdi3.o udivdi3.o strlen_user.o \ copy_user.o locks.o atomic.o bitops.o debuglocks.o lshrdi3.o \ - ashldi3.o rwsem.o + ashldi3.o rwsem.o muldi3.o lib.a: $(OBJS) $(AR) rcs lib.a $(OBJS) diff --git a/arch/sparc/lib/muldi3.S b/arch/sparc/lib/muldi3.S new file mode 100644 index 000000000000..7f17872d0603 --- /dev/null +++ b/arch/sparc/lib/muldi3.S @@ -0,0 +1,76 @@ +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + .text + .align 4 + .globl __muldi3 +__muldi3: + save %sp, -104, %sp + wr %g0, %i1, %y + sra %i3, 0x1f, %g2 + and %i1, %g2, %g2 + andcc %g0, 0, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, %i3, %g1 + mulscc %g1, 0, %g1 + add %g1, %g2, %l2 + rd %y, %o1 + mov %o1, %l3 + mov %i1, %o0 + call .umul + mov %i2, %o1 + mov %o0, %l0 + mov %i0, %o0 + call .umul + mov %i3, %o1 + add %l0, %o0, %l0 + mov %l2, %i0 + add %l2, %l0, %i0 + ret + restore %g0, %l3, %o1 diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index d92fbbb0b180..2fa3a2c56f28 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.83 2000/03/07 23:12:35 anton Exp $ +/* $Id: init.c,v 1.84 2000/03/15 23:26:26 anton Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -43,7 +43,11 @@ unsigned long sparc_unmapped_base; struct pgtable_cache_struct pgt_quicklists = { 0, 0, 0, 0, SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED }; /* References to section boundaries */ -extern char __init_begin, __init_end, _start, end, etext , edata; +extern char __init_begin, __init_end, _start, _end, etext , edata; + +/* Initial ramdisk setup */ +extern unsigned int sparc_ramdisk_image; +extern unsigned int sparc_ramdisk_size; unsigned long totalram_pages = 0; @@ -118,6 +122,7 @@ unsigned long __init bootmem_init(void) { unsigned long bootmap_size, start_pfn, end_pfn; unsigned long end_of_phys_memory = 0UL; + unsigned long bootmap_pfn; int i; /* Limit maximum memory until we implement highmem for sparc */ @@ -160,7 +165,7 @@ unsigned long __init bootmem_init(void) /* Start with page aligned address of last symbol in kernel * image. */ - start_pfn = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &end)); + start_pfn = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &_end)); /* Adjust up to the physical address where the kernel begins. */ start_pfn += phys_base; @@ -168,14 +173,36 @@ unsigned long __init bootmem_init(void) /* Now shift down to get the real physical page frame number. */ start_pfn >>= PAGE_SHIFT; + bootmap_pfn = start_pfn; + end_pfn = end_of_phys_memory >> PAGE_SHIFT; +#ifdef CONFIG_BLK_DEV_INITRD + /* Now have to check initial ramdisk, so that bootmap does not overwrite it */ + if (sparc_ramdisk_image) { + if (sparc_ramdisk_image >= (unsigned long)&_end - 2 * PAGE_SIZE) + sparc_ramdisk_image -= KERNBASE; + initrd_start = sparc_ramdisk_image + phys_base; + initrd_end = initrd_start + sparc_ramdisk_size; + if (initrd_end > end_of_phys_memory) { + printk(KERN_CRIT "initrd extends beyond end of memory " + "(0x%016lx > 0x%016lx)\ndisabling initrd\n", + initrd_end, end_of_phys_memory); + initrd_start = 0; + } + if (initrd_start) { + if (initrd_start >= (start_pfn << PAGE_SHIFT) && + initrd_start < (start_pfn << PAGE_SHIFT) + 2 * PAGE_SIZE) + bootmap_pfn = PAGE_ALIGN (initrd_end) >> PAGE_SHIFT; + } + } +#endif /* Initialize the boot-time allocator. */ #ifdef DEBUG_BOOTMEM - prom_printf("init_bootmem(spfn[%lx],epfn[%lx])\n", - start_pfn, end_pfn); + prom_printf("init_bootmem(spfn[%lx],bpfn[%lx],epfn[%lx])\n", + start_pfn, bootmap_pfn, end_pfn); #endif - bootmap_size = init_bootmem(start_pfn, end_pfn); + bootmap_size = init_bootmem(bootmap_pfn, end_pfn); /* Now register the available physical memory with the * allocator. @@ -190,15 +217,27 @@ unsigned long __init bootmem_init(void) sp_banks[i].num_bytes); } - /* Reserve the kernel text/data/bss and the bootmem bitmap. */ + /* Reserve the kernel text/data/bss, the bootmem bitmap and initrd. */ #ifdef DEBUG_BOOTMEM +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", + initrd_start, initrd_end - initrd_start); +#endif prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", - phys_base, - (start_pfn << PAGE_SHIFT) + - bootmap_size + PAGE_SIZE-1 - phys_base); + phys_base, (start_pfn << PAGE_SHIFT) - phys_base); + prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", + (bootmap_pfn << PAGE_SHIFT), bootmap_size); #endif - reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) + - bootmap_size + PAGE_SIZE-1 - phys_base); +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) { + reserve_bootmem(initrd_start, initrd_end - initrd_start); + initrd_start += PAGE_OFFSET; + initrd_end += PAGE_OFFSET; + } +#endif + reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) - phys_base); + reserve_bootmem((bootmap_pfn << PAGE_SHIFT), bootmap_size); #ifdef DEBUG_BOOTMEM prom_printf("init_bootmem: return end_pfn[%lx]\n", end_pfn); @@ -371,18 +410,6 @@ void __init mem_init(void) } memset(sparc_valid_addr_bitmap, 0, i << 2); - /* fix this */ -#ifdef CONFIG_BLK_DEV_INITRD - addr = __va(phys_base); - last = PAGE_ALIGN((unsigned long)&end) + phys_base; - while(addr < last) { - if (initrd_below_start_ok && addr >= initrd_start && addr < initrd_end) - mem_map[MAP_NR(addr)].flags &= ~(1<> 10); } +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + if (start < end) + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + for (; start < end; start += PAGE_SIZE) { + struct page *p = mem_map + MAP_NR(start); + + ClearPageReserved(p); + set_page_count(p, 1); + __free_page(p); + num_physpages++; + } +} +#endif + void si_meminfo(struct sysinfo *val) { val->totalram = totalram_pages; diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index fefd4e71a453..99a5e750bc8c 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.102 2000/03/14 07:31:35 jj Exp $ +# $Id: config.in,v 1.104 2000/03/15 15:02:28 jj Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -86,8 +86,8 @@ bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then tristate ' Linear (append) mode' CONFIG_MD_LINEAR tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED - tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING - tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 +# tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING +# tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 fi tristate 'RAM disk support' CONFIG_BLK_DEV_RAM diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 0d1b968fa3a4..f0c9460fa6b9 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.52 2000/03/03 23:48:41 davem Exp $ +/* $Id: setup.c,v 1.53 2000/03/15 14:42:52 jj Exp $ * linux/arch/sparc64/kernel/setup.c * * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) @@ -431,8 +431,6 @@ extern void panic_setup(char *, int *); extern unsigned short root_flags; extern unsigned short root_dev; extern unsigned short ram_flags; -extern unsigned int sparc_ramdisk_image; -extern unsigned int sparc_ramdisk_size; #define RAMDISK_IMAGE_START_MASK 0x07FF #define RAMDISK_PROMPT_FLAG 0x8000 #define RAMDISK_LOAD_FLAG 0x4000 @@ -512,29 +510,6 @@ void __init setup_arch(char **cmdline_p) rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0); rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0); #endif -#ifdef CONFIG_BLK_DEV_INITRD -// FIXME needs to do the new bootmem alloc stuff - if (sparc_ramdisk_image) { - unsigned long start = 0; - - if (sparc_ramdisk_image >= (unsigned long)&end - 2 * PAGE_SIZE) - sparc_ramdisk_image -= KERNBASE; - initrd_start = sparc_ramdisk_image + phys_base + PAGE_OFFSET; - initrd_end = initrd_start + sparc_ramdisk_size; - if (initrd_end > *memory_end_p) { - printk(KERN_CRIT "initrd extends beyond end of memory " - "(0x%016lx > 0x%016lx)\ndisabling initrd\n", - initrd_end,*memory_end_p); - initrd_start = 0; - } - if (initrd_start) - start = sparc_ramdisk_image + KERNBASE; - if (start >= *memory_start_p && start < *memory_start_p + 2 * PAGE_SIZE) { - initrd_below_start_ok = 1; - *memory_start_p = PAGE_ALIGN (start + sparc_ramdisk_size); - } - } -#endif /* Due to stack alignment restrictions and assumptions... */ init_mm.mmap->vm_page_prot = PAGE_SHARED; diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index b4ee5625e62f..0d5f615cf338 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -528,7 +528,7 @@ static unsigned long penguins_are_doing_time = 0; void smp_capture(void) { if (smp_processors_ready) { - int result = atomic_add_return(1, &smp_capture_depth); + int result = __atomic_add(1, &smp_capture_depth); membar("#StoreStore | #LoadStore"); if(result == 1) { @@ -596,18 +596,21 @@ void smp_promstop_others(void) smp_cross_call(&xcall_promstop, 0, 0, 0); } -static inline void sparc64_do_profile(unsigned long pc, unsigned long g3) +static inline void sparc64_do_profile(unsigned long pc, unsigned long o7) { if (prof_buffer && current->pid) { extern int _stext; extern int rwlock_impl_begin, rwlock_impl_end; extern int atomic_impl_begin, atomic_impl_end; + extern int __memcpy_begin, __memcpy_end; - if ((pc >= (unsigned long) &rwlock_impl_begin && + if ((pc >= (unsigned long) &atomic_impl_begin && + pc < (unsigned long) &atomic_impl_end) || + (pc >= (unsigned long) &rwlock_impl_begin && pc < (unsigned long) &rwlock_impl_end) || - (pc >= (unsigned long) &atomic_impl_begin && - pc < (unsigned long) &atomic_impl_end)) - pc = g3; + (pc >= (unsigned long) &__memcpy_begin && + pc < (unsigned long) &__memcpy_end)) + pc = o7; pc -= (unsigned long) &_stext; pc >>= prof_shift; @@ -646,7 +649,7 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs) clear_softint((1UL << 0)); do { if(!user) - sparc64_do_profile(regs->tpc, regs->u_regs[UREG_G3]); + sparc64_do_profile(regs->tpc, regs->u_regs[UREG_RETPC]); if(!--prof_counter(cpu)) { if (cpu == boot_cpu_id) { diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 45128d749099..4f1271ba9cd4 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.76 2000/03/14 08:29:29 davem Exp $ +/* $Id: sparc64_ksyms.c,v 1.78 2000/03/15 15:02:30 jj Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -207,6 +207,7 @@ EXPORT_SYMBOL(pci_map_sg); EXPORT_SYMBOL(pci_unmap_sg); EXPORT_SYMBOL(pci_dma_sync_single); EXPORT_SYMBOL(pci_dma_sync_sg); +EXPORT_SYMBOL(pci_dma_supported); #endif /* Solaris/SunOS binary compatibility */ diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index c27b342ea517..c74893d39089 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.137 2000/03/14 07:31:22 jj Exp $ +/* $Id: sys_sparc32.c,v 1.138 2000/03/15 06:01:23 davem Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c index 79233433608b..989e965a94f1 100644 --- a/arch/sparc64/kernel/unaligned.c +++ b/arch/sparc64/kernel/unaligned.c @@ -1,4 +1,4 @@ -/* $Id: unaligned.c,v 1.18 1999/08/02 08:39:44 davem Exp $ +/* $Id: unaligned.c,v 1.19 2000/03/16 11:53:05 jj Exp $ * unaligned.c: Unaligned load/store trap handling with special * cases for the kernel to do them more quickly. * @@ -590,9 +590,19 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) maybe_flush_windows(0, 0, rd, from_kernel); reg = fetch_reg_addr(rd, regs); - if ((insn & 0x780000) == 0x180000) - reg[1] = 0; - reg[0] = 0; + if (from_kernel || rd < 16) { + reg[0] = 0; + if ((insn & 0x780000) == 0x180000) + reg[1] = 0; + } else if (current->thread.flags & SPARC_FLAG_32BIT) { + put_user(0, (int *)reg); + if ((insn & 0x780000) == 0x180000) + put_user(0, ((int *)reg) + 1); + } else { + put_user(0, reg); + if ((insn & 0x780000) == 0x180000) + put_user(0, reg + 1); + } advance(regs); } diff --git a/arch/sparc64/lib/VIScopy.S b/arch/sparc64/lib/VIScopy.S index 57cf6b0f1afc..e20118648b7c 100644 --- a/arch/sparc64/lib/VIScopy.S +++ b/arch/sparc64/lib/VIScopy.S @@ -1,4 +1,4 @@ -/* $Id: VIScopy.S,v 1.21 1999/07/30 09:35:35 davem Exp $ +/* $Id: VIScopy.S,v 1.22 2000/03/16 16:44:38 davem Exp $ * VIScopy.S: High speed copy operations utilizing the UltraSparc * Visual Instruction Set. * @@ -304,6 +304,9 @@ .type bcopy,@function #ifdef __KERNEL__ + .globl __memcpy_begin +__memcpy_begin: + .globl __memcpy .type __memcpy,@function @@ -1001,6 +1004,9 @@ fpu_retl: FPU_RETL #ifdef __KERNEL__ + .globl __memcpy_end +__memcpy_end: + .section .fixup .align 4 VIScopyfixup_reto2: diff --git a/arch/sparc64/lib/atomic.S b/arch/sparc64/lib/atomic.S index cac9d15ddc1e..35a34ebbf7dd 100644 --- a/arch/sparc64/lib/atomic.S +++ b/arch/sparc64/lib/atomic.S @@ -1,4 +1,4 @@ -/* $Id: atomic.S,v 1.2 1999/08/23 05:15:58 davem Exp $ +/* $Id: atomic.S,v 1.3 2000/03/16 16:44:37 davem Exp $ * atomic.S: These things are too big to do inline. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -13,24 +13,24 @@ .globl __atomic_add atomic_impl_begin: -__atomic_add: - lduw [%g1], %g5 - add %g5, %g2, %g7 - cas [%g1], %g5, %g7 +__atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ + lduw [%o1], %g5 + add %g5, %o0, %g7 + cas [%o1], %g5, %g7 cmp %g5, %g7 bne,pn %icc, __atomic_add nop - jmpl %g3 + 8, %g0 - add %g7, %g2, %g2 + retl + add %g7, %o0, %o0 .globl __atomic_sub -__atomic_sub: - lduw [%g1], %g5 - sub %g5, %g2, %g7 - cas [%g1], %g5, %g7 +__atomic_sub: /* %o0 = increment, %o1 = atomic_ptr */ + lduw [%o1], %g5 + sub %g5, %o0, %g7 + cas [%o1], %g5, %g7 cmp %g5, %g7 bne,pn %icc, __atomic_sub nop - jmpl %g3 + 8, %g0 - sub %g7, %g2, %g2 + retl + sub %g7, %o0, %o0 atomic_impl_end: diff --git a/arch/sparc64/lib/rwlock.S b/arch/sparc64/lib/rwlock.S index 74360bf685ad..03f3bfe598e2 100644 --- a/arch/sparc64/lib/rwlock.S +++ b/arch/sparc64/lib/rwlock.S @@ -1,4 +1,4 @@ -/* $Id: rwlock.S,v 1.2 1999/08/23 05:15:58 davem Exp $ +/* $Id: rwlock.S,v 1.3 2000/03/16 16:44:38 davem Exp $ * rwlocks.S: These things are too big to do inline. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -12,34 +12,33 @@ /* The non-contention read lock usage is 2 cache lines. */ .globl __read_lock, __read_unlock - /* g1=lock, g3=retpc, g5/g7=scratch */ rwlock_impl_begin: -__read_lock: - ldsw [%g1], %g5 +__read_lock: /* %o0 = lock_ptr */ + ldsw [%o0], %g5 brlz,pn %g5, __read_wait_for_writer 4: add %g5, 1, %g7 - cas [%g1], %g5, %g7 + cas [%o0], %g5, %g7 cmp %g5, %g7 bne,pn %icc, __read_lock membar #StoreLoad | #StoreStore -99: jmpl %g3 + 8, %g0 +99: retl nop -__read_unlock: - lduw [%g1], %g5 +__read_unlock: /* %o0 = lock_ptr */ + lduw [%o0], %g5 sub %g5, 1, %g7 - cas [%g1], %g5, %g7 + cas [%o0], %g5, %g7 cmp %g5, %g7 be,pt %xcc, 99b membar #StoreLoad | #StoreStore b,a,pt %xcc, __read_unlock __read_wait_for_writer: - ldsw [%g1], %g5 + ldsw [%o0], %g5 brlz,pt %g5, __read_wait_for_writer membar #LoadLoad b,a,pt %xcc, 4b __write_wait_for_writer: - ldsw [%g1], %g5 + ldsw [%o0], %g5 brlz,pt %g5, __write_wait_for_writer membar #LoadLoad b,a,pt %xcc, 4f @@ -48,24 +47,23 @@ __write_wait_for_writer: .align 64 .globl __write_unlock - /* g1=lock, g3=retpc, g2/g5/g7=scratch */ -__write_unlock: +__write_unlock: /* %o0 = lock_ptr */ sethi %hi(0x80000000), %g2 -1: lduw [%g1], %g5 +1: lduw [%o0], %g5 andn %g5, %g2, %g7 - cas [%g1], %g5, %g7 + cas [%o0], %g5, %g7 cmp %g5, %g7 be,pt %icc, 99b membar #StoreLoad | #StoreStore b,a,pt %xcc, 1b .globl __write_lock -__write_lock: +__write_lock: /* %o0 = lock_ptr */ sethi %hi(0x80000000), %g2 -1: ldsw [%g1], %g5 +1: ldsw [%o0], %g5 4: brnz,pn %g5, 5f or %g5, %g2, %g7 - cas [%g1], %g5, %g7 + cas [%o0], %g5, %g7 cmp %g5, %g7 be,pt %icc, 99b membar #StoreLoad | #StoreStore @@ -73,10 +71,10 @@ __write_lock: b,a,pt %xcc, 1b 5: brlz %g5, __write_wait_for_writer or %g5, %g2, %g7 - cas [%g1], %g5, %g7 + cas [%o0], %g5, %g7 cmp %g5, %g7 bne,pn %icc, 5b -8: ldsw [%g1], %g5 +8: ldsw [%o0], %g5 cmp %g5, %g2 be,pn %icc, 99b membar #LoadLoad diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index d09ac451b612..1d2049b5f9ff 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.148 2000/03/07 07:08:31 anton Exp $ +/* $Id: init.c,v 1.149 2000/03/15 14:42:58 jj Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) @@ -48,6 +48,10 @@ unsigned long mmu_context_bmap[CTX_BMAP_SLOTS]; /* References to section boundaries */ extern char __init_begin, __init_end, _start, _end, etext, edata; +/* Initial ramdisk setup */ +extern unsigned int sparc_ramdisk_image; +extern unsigned int sparc_ramdisk_size; + int do_check_pgt_cache(int low, int high) { int freed = 0; @@ -808,6 +812,7 @@ unsigned long __init bootmem_init(void) { unsigned long bootmap_size, start_pfn, end_pfn; unsigned long end_of_phys_memory = 0UL; + unsigned long bootmap_pfn; int i; /* XXX It is a bit ambiguous here, whether we should @@ -855,15 +860,37 @@ unsigned long __init bootmem_init(void) /* Now shift down to get the real physical page frame number. */ start_pfn >>= PAGE_SHIFT; + + bootmap_pfn = start_pfn; end_pfn = end_of_phys_memory >> PAGE_SHIFT; +#ifdef CONFIG_BLK_DEV_INITRD + /* Now have to check initial ramdisk, so that bootmap does not overwrite it */ + if (sparc_ramdisk_image) { + if (sparc_ramdisk_image >= (unsigned long)&_end - 2 * PAGE_SIZE) + sparc_ramdisk_image -= KERNBASE; + initrd_start = sparc_ramdisk_image + phys_base; + initrd_end = initrd_start + sparc_ramdisk_size; + if (initrd_end > end_of_phys_memory) { + printk(KERN_CRIT "initrd extends beyond end of memory " + "(0x%016lx > 0x%016lx)\ndisabling initrd\n", + initrd_end, end_of_phys_memory); + initrd_start = 0; + } + if (initrd_start) { + if (initrd_start >= (start_pfn << PAGE_SHIFT) && + initrd_start < (start_pfn << PAGE_SHIFT) + 2 * PAGE_SIZE) + bootmap_pfn = PAGE_ALIGN (initrd_end) >> PAGE_SHIFT; + } + } +#endif /* Initialize the boot-time allocator. */ #ifdef DEBUG_BOOTMEM - prom_printf("init_bootmem(spfn[%lx],epfn[%lx])\n", - start_pfn, end_pfn); + prom_printf("init_bootmem(spfn[%lx],bpfn[%lx],epfn[%lx])\n", + start_pfn, bootmap_pfn, end_pfn); #endif - bootmap_size = init_bootmem(start_pfn, end_pfn); + bootmap_size = init_bootmem(bootmap_pfn, end_pfn); /* Now register the available physical memory with the * allocator. @@ -878,15 +905,27 @@ unsigned long __init bootmem_init(void) sp_banks[i].num_bytes); } - /* Reserve the kernel text/data/bss and the bootmem bitmap. */ + /* Reserve the kernel text/data/bss, the bootmem bootmap and initrd. */ #ifdef DEBUG_BOOTMEM +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", + initrd_start, initrd_end - initrd_start); +#endif + prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", + phys_base, (start_pfn << PAGE_SHIFT) - phys_base); prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", - phys_base, - (((start_pfn << PAGE_SHIFT) + - bootmap_size) - phys_base)); + (bootmap_pfn << PAGE_SHIFT), bootmap_size); +#endif +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) { + reserve_bootmem(initrd_start, initrd_end - initrd_start); + initrd_start += PAGE_OFFSET; + initrd_end += PAGE_OFFSET; + } #endif - reserve_bootmem(phys_base, (((start_pfn << PAGE_SHIFT) + - bootmap_size) - phys_base)); + reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) - phys_base); + reserve_bootmem((bootmap_pfn << PAGE_SHIFT), bootmap_size); #ifdef DEBUG_BOOTMEM prom_printf("init_bootmem: return end_pfn[%lx]\n", end_pfn); @@ -1234,11 +1273,6 @@ void __init mem_init(void) ((unsigned long) &empty_zero_page); last += PAGE_OFFSET + phys_base; while (addr < last) { -#ifdef CONFIG_BLK_DEV_INITRD -// FIXME to use bootmem scheme... - if (initrd_below_start_ok && addr >= initrd_start && addr < initrd_end) - mem_map[MAP_NR(addr)].flags &= ~(1<> 22, sparc64_valid_addr_bitmap); addr += PAGE_SIZE; } @@ -1319,6 +1353,22 @@ void free_initmem (void) } } +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + if (start < end) + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + for (; start < end; start += PAGE_SIZE) { + struct page *p = mem_map + MAP_NR(start); + + ClearPageReserved(p); + set_page_count(p, 1); + __free_page(p); + num_physpages++; + } +} +#endif + void si_meminfo(struct sysinfo *val) { val->totalram = num_physpages; diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 239c61acca2a..863b2fc42b32 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -91,7 +91,7 @@ extern spinlock_t rtc_lock; static struct timer_list rtc_irq_timer; -static long long rtc_llseek(struct file *file, loff_t offset, int origin); +static loff_t rtc_llseek(struct file *file, loff_t offset, int origin); static ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos); @@ -178,7 +178,7 @@ static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) * Now all the various file operations that we export. */ -static long long rtc_llseek(struct file *file, loff_t offset, int origin) +static loff_t rtc_llseek(struct file *file, loff_t offset, int origin) { return -ESPIPE; } diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index 542ad44a171a..b2ae2e6b8029 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c @@ -68,7 +68,7 @@ #define UDIDETCR1 0x7B #define DTPR1 0x7C -#undef DISPLAY_CMD64X_TIMINGS +#define DISPLAY_CMD64X_TIMINGS #if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) #include @@ -116,22 +116,22 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); p += sprintf(p, " %sabled %sabled\n", - (reg72&0x80) ? "dis" : " en", (reg7a&0x80) ? "dis" : " en"); + (reg72&0x80) ? "dis" : " en", (reg7a&0x80) ? "dis" : " en"); p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); p += sprintf(p, "DMA enabled: %s %s %s %s\n", - (reg72&0x20) ? "yes" : "no ", (reg72&0x40) ? "yes" : "no ", (reg7a&0x20) ? "yes" : "no ", (reg7a&0x40) ? "yes" : "no " ); - p += sprintf(p, "UDMA enabled: %s %s %s %s\n", - (reg73&0x01) ? "yes" : "no ", (reg73&0x02) ? "yes" : "no ", (reg7b&0x01) ? "yes" : "no ", (reg7b&0x02) ? "yes" : "no " ); - p += sprintf(p, "UDMA enabled: %s %s %s %s\n", - (reg73&0x15) ? "4" : (reg73&0x25) ? "3" : (reg73&0x11) ? "2" : (reg73&0x21) ? "1" : (reg73&0x31) ? "0" : "X", - (reg73&0x4A) ? "4" : (reg73&0x8A) ? "3" : (reg73&0x42) ? "2" : (reg73&0x82) ? "1" : (reg73&0xC2) ? "0" : "X", - (reg7b&0x15) ? "4" : (reg7b&0x25) ? "3" : (reg7b&0x11) ? "2" : (reg7b&0x21) ? "1" : (reg7b&0x31) ? "0" : "X", - (reg7b&0x4A) ? "4" : (reg7b&0x8A) ? "3" : (reg7b&0x42) ? "2" : (reg7b&0x82) ? "1" : (reg7b&0xC2) ? "0" : "X" ); - p += sprintf(p, "DMA enabled: %s %s %s %s\n", - (reg73&0x10) ? "2" : (reg73&0x20) ? "1" : (reg73&0x30) ? "0" : "X", - (reg73&0x40) ? "2" : (reg73&0x80) ? "1" : (reg73&0xC0) ? "0" : "X", - (reg7b&0x10) ? "2" : (reg7b&0x20) ? "1" : (reg7b&0x30) ? "0" : "X", - (reg7b&0x40) ? "2" : (reg7b&0x80) ? "1" : (reg7b&0xC0) ? "0" : "X" ); + (reg72&0x20) ? "yes" : "no ", (reg72&0x40) ? "yes" : "no ", (reg7a&0x20) ? "yes" : "no ", (reg7a&0x40) ? "yes" : "no " ); + p += sprintf(p, "DMA Mode: %s(%s) %s(%s) %s(%s) %s(%s)\n", + (reg72&0x20)?((reg73&0x01)?"UDMA":" DMA"):" PIO", + (reg72&0x20)?(((reg73&0x15)==0x15)?"4":((reg73&0x25)==0x25)?"3":((reg73&0x10)==0x10)?"2":((reg73&0x20)==0x20)?"1":((reg73&0x30)==0x30)?"0":"X"):"?", + (reg72&0x40)?((reg73&0x02)?"UDMA":" DMA"):" PIO", + (reg72&0x40)?(((reg73&0x4A)==0x4A)?"4":((reg73&0x8A)==0x8A)?"3":((reg73&0x40)==0x40)?"2":((reg73&0x80)==0x80)?"1":((reg73&0xC0)==0xC0)?"0":"X"):"?", + (reg7a&0x20)?((reg7b&0x01)?"UDMA":" DMA"):" PIO", + (reg7a&0x20)?(((reg7b&0x15)==0x15)?"4":((reg7b&0x25)==0x25)?"3":((reg7b&0x10)==0x10)?"2":((reg7b&0x20)==0x20)?"1":((reg7b&0x30)==0x30)?"0":"X"):"?", + (reg7a&0x40)?((reg7b&0x02)?"UDMA":" DMA"):" PIO", + (reg7a&0x40)?(((reg7b&0x4A)==0x4A)?"4":((reg7b&0x8A)==0x8A)?"3":((reg7b&0x40)==0x40)?"2":((reg7b&0x80)==0x80)?"1":((reg7b&0xC0)==0xC0)?"0":"X"):"?" ); + p += sprintf(p, "PIO Mode: %s %s %s %s\n", + "?", "?", "?", "?"); + p += sprintf(p, "PIO\n"); SPLIT_BYTE(reg53, hi_byte, lo_byte); @@ -668,9 +668,11 @@ unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name) (void) pci_write_config_byte(dev, DRWTIM3, 0x3f); #if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) - cmd64x_proc = 1; - bmide_dev = dev; - cmd64x_display_info = &cmd64x_get_info; + if (!cmd64x_proc) { + cmd64x_proc = 1; + bmide_dev = dev; + cmd64x_display_info = &cmd64x_get_info; + } #endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_PROC_FS */ return 0; diff --git a/drivers/ide/ide-geometry.c b/drivers/ide/ide-geometry.c index 6ebf20fe1133..4c67d0911dc6 100644 --- a/drivers/ide/ide-geometry.c +++ b/drivers/ide/ide-geometry.c @@ -3,7 +3,7 @@ */ #include -#ifdef CONFIG_BLK_DEV_IDE +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) #include #include @@ -211,4 +211,4 @@ int ide_xlate_1024 (kdev_t i_rdev, int xparm, int ptheads, const char *msg) drive->bios_cyl, drive->bios_head, drive->bios_sect); return ret; } -#endif /* CONFIG_BLK_DEV_IDE */ +#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_IDE_MODULE) */ diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index 97e57fa558d4..93f20566db1f 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c @@ -417,18 +417,22 @@ unsigned int __init ata66_piix (ide_hwif_t *hwif) void __init ide_init_piix (ide_hwif_t *hwif) { + if (!hwif->irq) + hwif->irq = hwif->channel ? 15 : 14; + hwif->tuneproc = &piix_tune_drive; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + + if (!hwif->dma_base) + return; - if (hwif->dma_base) { #ifdef CONFIG_PIIX_TUNING - hwif->dmaproc = &piix_dmaproc; + hwif->autodma = 1; + hwif->dmaproc = &piix_dmaproc; +#else + if (hwif->autodma) + hwif->autodma = 0; + #endif /* CONFIG_PIIX_TUNING */ - hwif->drives[0].autotune = 0; - hwif->drives[1].autotune = 0; - } else { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - } - if (!hwif->irq) - hwif->irq = hwif->channel ? 15 : 14; } diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index c2ec24d391d6..afa1cc5b67f9 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c @@ -104,6 +104,7 @@ static const struct { { "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 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, }, @@ -127,7 +128,7 @@ static const struct { { 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_82C691, PCI_DEVICE_ID_VIA_82C596, VIA_FLAG_ATA_66 }, { PCI_DEVICE_ID_VIA_82C693, PCI_DEVICE_ID_VIA_82C596, 0 }, { PCI_DEVICE_ID_VIA_8501_0, PCI_DEVICE_ID_VIA_82C686, VIA_FLAG_ATA_66 }, { PCI_DEVICE_ID_VIA_8371_0, PCI_DEVICE_ID_VIA_82C686, VIA_FLAG_ATA_66 }, diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 2653270c35c0..ddbb4bf7a647 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -52,34 +52,36 @@ #include "sis900.h" static const char *version = -"sis900.c: v1.06.04 02/11/2000\n"; +"sis900.c: v1.07 03/07/2000\n"; static int max_interrupt_work = 20; +static int multicast_filter_limit = 128; + #define sis900_debug debug static int sis900_debug = 0; -static int multicast_filter_limit = 128; - /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (4*HZ) - -struct mac_chip_info { - const char *name; - u16 vendor_id, device_id, flags; - int io_size; - struct net_device *(*probe) (struct mac_chip_info *mac, struct pci_dev * pci_dev, - struct net_device * net_dev); +/* SiS 900 is capable of 32 bits BM DMA */ +#define SIS900_DMA_MASK 0xffffffff + +static struct net_device * sis900_mac_probe (struct pci_dev * pci_dev, + char *card_name); +enum { + SIS_900 = 0, + SIS_7018 +}; +static char * card_names[] = { + "SiS 900 PCI Fast Ethernet", + "SiS 7016 PCI Fast Ethernet" }; -static struct net_device * sis900_mac_probe (struct mac_chip_info * mac, struct pci_dev * pci_dev, - struct net_device * net_dev); - -static struct mac_chip_info mac_chip_table[] = { - { "SiS 900 PCI Fast Ethernet", PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_900, - PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE, sis900_mac_probe}, - { "SiS 7016 PCI Fast Ethernet",PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7016, - PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE, sis900_mac_probe}, - {0,}, /* 0 terminated list. */ +static struct pci_device_id sis900_pci_tbl [] __initdata = { + {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_900, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_900}, + {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7016, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_7018} }; +MODULE_DEVICE_TABLE (pci, sis900_pci_tbl); static void sis900_read_mode(struct net_device *net_dev, int phy_addr, int *speed, int *duplex); static void amd79c901_read_mode(struct net_device *net_dev, int phy_addr, int *speed, int *duplex); @@ -111,24 +113,22 @@ typedef struct _BufferDesc { } BufferDesc; struct sis900_private { - struct net_device *next_module; struct net_device_stats stats; struct pci_dev * pci_dev; spinlock_t lock; - struct mac_chip_info * mac; struct mii_phy * mii; unsigned int cur_phy; struct timer_list timer; /* Link status detection timer. */ - unsigned int cur_rx, dirty_rx; + unsigned int cur_rx, dirty_rx; unsigned int cur_tx, dirty_tx; /* The saved address of a sent/receive-in-place packet buffer */ struct sk_buff *tx_skbuff[NUM_TX_DESC]; struct sk_buff *rx_skbuff[NUM_RX_DESC]; - BufferDesc tx_ring[NUM_TX_DESC]; + BufferDesc tx_ring[NUM_TX_DESC]; BufferDesc rx_ring[NUM_RX_DESC]; unsigned int tx_full; /* The Tx queue is full. */ @@ -163,68 +163,47 @@ static u16 sis900_compute_hashtable_index(u8 *addr); static void set_rx_mode(struct net_device *net_dev); static void sis900_reset(struct net_device *net_dev); -/* A list of all installed SiS900 devices, for removing the driver module. */ -static struct net_device *root_sis900_dev = NULL; - /* walk through every ethernet PCI devices to see if some of them are matched with our card list*/ -static int __init sis900_probe (void) +static int __init sis900_probe (struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { - int found = 0; - struct pci_dev * pci_dev = NULL; - - while ((pci_dev = pci_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pci_dev)) != NULL) { - /* pci_dev contains all ethernet devices */ - u32 pci_io_base; - struct mac_chip_info * mac; - struct net_device *net_dev = NULL; - - for (mac = mac_chip_table; mac->vendor_id; mac++) { - /* try to match our card list */ - if (pci_dev->vendor == mac->vendor_id && - pci_dev->device == mac->device_id) - break; - } - - if (mac->vendor_id == 0) - /* pci_dev does not match any of our cards */ - continue; - - /* now, pci_dev should be either 900 or 7016 */ - pci_io_base = pci_dev->resource[0].start; - if ((mac->flags & PCI_COMMAND_IO ) && - check_region(pci_io_base, mac->io_size)) - continue; - - /* setup various bits in PCI command register */ - pci_enable_device (pci_dev); - pci_set_master(pci_dev); + u32 pci_io_base; - /* do the real low level jobs */ - net_dev = mac->probe(mac, pci_dev, net_dev); - - if (net_dev != NULL) { - found++; - } - net_dev = NULL; + if (!pci_dma_supported(pci_dev, SIS900_DMA_MASK)) { + printk(KERN_ERR "sis900.c: architecture does not support " + "32bit PCI busmaster DMA\n"); + return -ENODEV; + } + + pci_io_base = pci_dev->resource[0].start; + if (check_region(pci_io_base, SIS900_TOTAL_SIZE)) { + printk(KERN_ERR "sis900.c: can't allocate I/O space at 0x%08x\n", + pci_io_base); + return -ENODEV; } - return found ? 0 : -ENODEV; + + /* setup various bits in PCI command register */ + pci_enable_device (pci_dev); + pci_set_master(pci_dev); + + /* do the real low level jobs */ + if (sis900_mac_probe(pci_dev, card_names[pci_id->driver_data]) == NULL) + return -1; + + return 0; } -static struct net_device * sis900_mac_probe (struct mac_chip_info * mac, struct pci_dev * pci_dev, - struct net_device * net_dev) +static struct net_device * __init sis900_mac_probe (struct pci_dev * pci_dev, char * card_name) { struct sis900_private *sis_priv; long ioaddr = pci_dev->resource[0].start; + struct net_device *net_dev = NULL; int irq = pci_dev->irq; - static int did_version = 0; u16 signature; int i; - if (did_version++ == 0) - printk(KERN_INFO "%s", version); - if ((net_dev = init_etherdev(net_dev, 0)) == NULL) return NULL; + /* check to see if we have sane EEPROM */ signature = (u16) read_eeprom(ioaddr, EEPROMSignature); if (signature == 0xffff || signature == 0x0000) { @@ -233,8 +212,8 @@ static struct net_device * sis900_mac_probe (struct mac_chip_info * mac, struct return NULL; } - printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", net_dev->name, mac->name, - ioaddr, irq); + printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", net_dev->name, + card_name, ioaddr, irq); /* get MAC address from EEPROM */ for (i = 0; i < 3; i++) @@ -252,23 +231,22 @@ static struct net_device * sis900_mac_probe (struct mac_chip_info * mac, struct memset(sis_priv, 0, sizeof(struct sis900_private)); /* We do a request_region() to register /proc/ioports info. */ - request_region(ioaddr, mac->io_size, net_dev->name); + request_region(ioaddr, SIS900_TOTAL_SIZE, net_dev->name); net_dev->base_addr = ioaddr; net_dev->irq = irq; sis_priv->pci_dev = pci_dev; - sis_priv->mac = mac; spin_lock_init(&sis_priv->lock); /* probe for mii transciver */ if (sis900_mii_probe(net_dev) == 0) { unregister_netdev(net_dev); kfree(sis_priv); - release_region(ioaddr, mac->io_size); + release_region(ioaddr, SIS900_TOTAL_SIZE); return NULL; } - sis_priv->next_module = root_sis900_dev; - root_sis900_dev = net_dev; + pci_dev->driver_data = net_dev; + pci_dev->dma_mask = SIS900_DMA_MASK; /* The SiS900-specific entries in the device structure. */ net_dev->open = &sis900_open; @@ -283,7 +261,7 @@ static struct net_device * sis900_mac_probe (struct mac_chip_info * mac, struct return net_dev; } -static int sis900_mii_probe (struct net_device * net_dev) +static int __init sis900_mii_probe (struct net_device * net_dev) { struct sis900_private * sis_priv = (struct sis900_private *)net_dev->priv; int phy_addr; @@ -966,21 +944,42 @@ static int sis900_rx(struct net_device *net_dev) net_dev->name); break; } + + /* gvie the socket buffer to upper layers */ skb = sis_priv->rx_skbuff[entry]; - sis_priv->rx_skbuff[entry] = NULL; - /* reset buffer descriptor state */ - sis_priv->rx_ring[entry].cmdsts = 0; - sis_priv->rx_ring[entry].bufptr = 0; - skb_put(skb, rx_size); skb->protocol = eth_type_trans(skb, net_dev); netif_rx(skb); - + + /* some network statistics */ if ((rx_status & BCAST) == MCAST) sis_priv->stats.multicast++; net_dev->last_rx = jiffies; sis_priv->stats.rx_bytes += rx_size; sis_priv->stats.rx_packets++; + + /* refill the Rx buffer, what if there is not enought memory for + new socket buffer ?? */ + if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) { + /* not enough memory for skbuff, this makes a "hole" + on the buffer ring, it is not clear how the + hardware will react to this kind of degenerated + buffer */ + printk(KERN_INFO "%s: Memory squeeze," + "deferring packet.\n", + net_dev->name); + sis_priv->rx_skbuff[entry] = NULL; + /* reset buffer descriptor state */ + sis_priv->rx_ring[entry].cmdsts = 0; + sis_priv->rx_ring[entry].bufptr = 0; + sis_priv->stats.rx_dropped++; + break; + } + skb->dev = net_dev; + sis_priv->rx_skbuff[entry] = skb; + sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; + sis_priv->rx_ring[entry].bufptr = virt_to_bus(skb->tail); + sis_priv->dirty_rx++; } sis_priv->cur_rx++; entry = sis_priv->cur_rx % NUM_RX_DESC; @@ -1249,23 +1248,46 @@ static void sis900_reset(struct net_device *net_dev) outl(PESEL, ioaddr + cfg); } -static void __exit sis900_cleanup_module(void) +static void __exit sis900_remove(struct pci_dev *pci_dev) { - /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ - while (root_sis900_dev) { - struct sis900_private *sis_priv = - (struct sis900_private *)root_sis900_dev->priv; - struct net_device *next_dev = sis_priv->next_module; + struct net_device *net_dev = pci_dev->driver_data; + struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv; - unregister_netdev(root_sis900_dev); - release_region(root_sis900_dev->base_addr, - sis_priv->mac->io_size); - kfree(sis_priv); - kfree(root_sis900_dev); + unregister_netdev(net_dev); + release_region(net_dev->base_addr, + SIS900_TOTAL_SIZE); + + kfree(sis_priv); + kfree(net_dev); +} - root_sis900_dev = next_dev; +#define SIS900_MODULE_NAME "sis900" + +static struct pci_driver sis900_pci_driver = { + name: SIS900_MODULE_NAME, + id_table: sis900_pci_tbl, + probe: sis900_probe, + remove: sis900_remove, +}; + +static int __init sis900_init_module(void) +{ + if (!pci_present()) /* No PCI bus in this machine! */ + return -ENODEV; + + printk(KERN_INFO "%s", version); + + if (!pci_register_driver(&sis900_pci_driver)) { + pci_unregister_driver(&sis900_pci_driver); + return -ENODEV; } + return 0; +} + +static void __exit sis900_cleanup_module(void) +{ + pci_unregister_driver(&sis900_pci_driver); } -module_init(sis900_probe); +module_init(sis900_init_module); module_exit(sis900_cleanup_module); diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 19615012f972..6ca32855afcc 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -420,7 +420,7 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev, if (via_rhine_chip_info[chip_id].flags & PCI_USES_MASTER) pci_set_master (pdev); - dev = init_etherdev(NULL, sizeof (*np)); + dev = init_etherdev(NULL, 0); if (dev == NULL) { printk (KERN_ERR "init_ethernet failed for card #%d\n", card_idx); @@ -466,7 +466,10 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev, dev->base_addr = ioaddr; dev->irq = irq; - np = dev->priv; + np = (void *)(((long)kmalloc(sizeof(*np), GFP_KERNEL) + 31) & ~31); + if(np == NULL) + goto err_out_np_failed; + dev->priv = np; spin_lock_init (&np->lock); np->chip_id = chip_id; @@ -518,6 +521,7 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev, return 0; +err_out_np_failed: #ifndef VIA_USE_IO /* note this is ifdef'd because the ioremap is ifdef'd... * so additional exit conditions above this must move @@ -1173,6 +1177,7 @@ static void __devexit via_rhine_remove_one (struct pci_dev *pdev) iounmap((char *)(dev->base_addr)); #endif + kfree(dev->priv); kfree(dev); } diff --git a/drivers/parport/ChangeLog b/drivers/parport/ChangeLog index d0b742359842..8c89ab7dc7a1 100644 --- a/drivers/parport/ChangeLog +++ b/drivers/parport/ChangeLog @@ -3,7 +3,7 @@ * parport_pc.c (cleanup_module): Don't call pci_unregister_driver if we didn't call pci_register_driver first. -2000-03-13 +2000-03-13 Tim Waugh * parport_pc.c (parport_pc_init): Moved from asm/parport.h. @@ -24,12 +24,12 @@ (parport_pc_find_ports): New function. (init_module): Make superio a config option, not a parameter. -2000-03-10 +2000-03-10 Tim Waugh * parport_pc.c (decode_winbond): Use correct 83877ATF chip ID. (decode_winbond): Fix typo. -2000-03-09 +2000-03-09 Tim Waugh * parport_pc.c: Integrate SuperIO PCI probe with normal PCI card probe, so that the MODULE_DEVICE_TABLE is complete. diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1837c2467d0a..0b6614fe18ab 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -384,19 +384,14 @@ void pci_set_master(struct pci_dev *dev) { u16 cmd; - u8 lat; pci_read_config_word(dev, PCI_COMMAND, &cmd); if (! (cmd & PCI_COMMAND_MASTER)) { - printk("PCI: Enabling bus mastering for device %s\n", dev->slot_name); + DBG("PCI: Enabling bus mastering for device %s\n", dev->slot_name); cmd |= PCI_COMMAND_MASTER; pci_write_config_word(dev, PCI_COMMAND, cmd); } - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); - if (lat < 16) { - printk("PCI: Increasing latency timer of device %s to 64\n", dev->slot_name); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); - } + pcibios_set_master(dev); } /* diff --git a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c index c57fdfcc642b..33db6b4ede8f 100644 --- a/drivers/pcmcia/yenta.c +++ b/drivers/pcmcia/yenta.c @@ -528,6 +528,7 @@ static unsigned int yenta_probe_irq(pci_socket_t *socket, u32 isa_irq_mask) cb_writel(socket, CB_SOCKET_EVENT, -1); } cb_writel(socket, CB_SOCKET_MASK, 0); + exca_writeb(socket, I365_CSCINT, 0); mask = probe_irq_mask(val) & 0xffff; diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c index acbc1880c3e6..35865dd7066a 100644 --- a/drivers/sbus/sbus.c +++ b/drivers/sbus/sbus.c @@ -1,4 +1,4 @@ -/* $Id: sbus.c,v 1.84 2000/03/15 01:51:16 davem Exp $ +/* $Id: sbus.c,v 1.86 2000/03/16 09:23:57 jj Exp $ * sbus.c: SBus support routines. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -304,6 +304,8 @@ static void __init sbus_fixup_all_regs(struct sbus_dev *first_sdev) } } +extern void register_proc_sparc_ioport(void); + void __init sbus_init(void) { int nd, this_sbus, sbus_devs, topnd, iommund; @@ -311,7 +313,11 @@ void __init sbus_init(void) struct sbus_bus *sbus; struct sbus_dev *this_dev; int num_sbus = 0; /* How many did we find? */ - + +#ifndef __sparc_v9__ + register_proc_sparc_ioport(); +#endif + #ifdef CONFIG_SUN4 return sun4_dvma_init(); #endif diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile index 5b4d35c8c00d..046379d37d6b 100644 --- a/drivers/sound/Makefile +++ b/drivers/sound/Makefile @@ -18,7 +18,7 @@ ALL_SUB_DIRS := $(SUB_DIRS) export-objs := ad1848.o audio_syms.o midi_syms.o mpu401.o \ msnd.o opl3.o sb_common.o sequencer_syms.o \ - sound_core.o sound_syms.o uart401.o ad1816.o \ + sound_core.o sound_syms.o uart401.o \ nm256_audio.o ac97.o ac97_codec.o diff --git a/drivers/sound/ac97_codec.c b/drivers/sound/ac97_codec.c index 32a3380e9ae4..0a0e30775c40 100644 --- a/drivers/sound/ac97_codec.c +++ b/drivers/sound/ac97_codec.c @@ -1,5 +1,5 @@ /* - * ac97_codec.c: Generic AC97 mixer module + * ac97_codec.c: Generic AC97 mixer/modem module * * Derived from ac97 mixer in maestro and trident driver. * @@ -20,6 +20,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * History + * v0.4 Mar 15 2000 Ollie Lho + * dual codec support verified with 4 channel output * v0.3 Feb 22 2000 Ollie Lho * bug fix for record mask setting * v0.2 Feb 10 2000 Ollie Lho @@ -42,7 +44,9 @@ static void ac97_set_mixer(struct ac97_codec *codec, unsigned int oss_mixer, uns static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask); static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg); -static int sigmatel_init(struct ac97_codec * codec); +static int ac97_init_mixer(struct ac97_codec *codec); + +static int sigmatel_init(struct ac97_codec *codec); #define arraysize(x) (sizeof(x)/sizeof((x)[0])) @@ -59,6 +63,8 @@ static struct { {0x43525923, "Cirrus Logic CS4298" , NULL}, {0x43525931, "Cirrus Logic CS4299" , NULL}, {0x4e534331, "National Semiconductor LM4549" , NULL}, + {0x53494c22, "Silicon Laboratory Si3036" , NULL}, + {0x53494c23, "Silicon Laboratory Si3038" , NULL}, {0x83847600, "SigmaTel STAC????" , NULL}, {0x83847604, "SigmaTel STAC9701/3/4/5", NULL}, {0x83847605, "SigmaTel STAC9704" , NULL}, @@ -323,7 +329,6 @@ static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask) /* else, write the first set in the mask as the output */ - val = ffs(mask); val = ac97_oss_rm[val-1]; val |= val << 8; /* set both channels */ @@ -503,14 +508,22 @@ int ac97_read_proc (char *page, char **start, off_t off, int ac97_probe_codec(struct ac97_codec *codec) { - u16 id1, id2, cap; + u16 id1, id2; + u16 audio, modem; int i; /* probing AC97 codec, AC97 2.0 says that bit 15 of register 0x00 (reset) should be read zero. Probing of AC97 in this way is not reliable, it is not even SAFE !! */ codec->codec_write(codec, AC97_RESET, 0L); - if ((cap = codec->codec_read(codec, AC97_RESET)) & 0x8000) + if ((audio = codec->codec_read(codec, AC97_RESET)) & 0x8000) { + printk(KERN_ERR "ac97_codec: %s ac97 codec not present\n", + codec->id ? "Secondary" : "Primary"); return 0; + } + + /* probe for Modem Codec */ + codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L); + modem = codec->codec_read(codec, AC97_EXTENDED_MODEM_ID); codec->name = NULL; codec->codec_init = NULL; @@ -526,9 +539,20 @@ int ac97_probe_codec(struct ac97_codec *codec) } if (codec->name == NULL) codec->name = "Unknown"; - printk(KERN_INFO "ac97_codec: ac97 vendor id1: 0x%04x, id2: 0x%04x (%s)\n", + printk(KERN_INFO "ac97_codec: AC97 %s codec, vendor id1: 0x%04x, " + "id2: 0x%04x (%s)\n", audio ? "Audio" : (modem ? "Modem" : ""), id1, id2, codec->name); + return ac97_init_mixer(codec); +} + +static int ac97_init_mixer(struct ac97_codec *codec) +{ + u16 cap; + int i; + + cap = codec->codec_read(codec, AC97_RESET); + /* mixer masks */ codec->supported_mixers = AC97_SUPPORTED_MASK; codec->stereo_mixers = AC97_STEREO_MASK; @@ -548,7 +572,7 @@ int ac97_probe_codec(struct ac97_codec *codec) codec->codec_write(codec, AC97_MASTER_VOL_STEREO, 0L); codec->codec_write(codec, AC97_PCMOUT_VOL, 0L); - /* codec specific initialization for 4-6 channel output */ + /* codec specific initialization for 4-6 channel output or secondary codec stuff */ if (codec->id != 0 && codec->codec_init != NULL) { codec->codec_init(codec); } @@ -566,11 +590,28 @@ int ac97_probe_codec(struct ac97_codec *codec) return 1; } +static int ac97_init_modem(struct ac97_codec *codec) +{ + return 0; +} + static int sigmatel_init(struct ac97_codec * codec) { codec->codec_write(codec, AC97_SURROUND_MASTER, 0L); - /* initialize SigmaTel STAC9721/23 */ - codec->codec_write(codec, 0x74, 0x01); + + /* initialize SigmaTel STAC9721/23 as secondary codec, decoding AC link + sloc 3,4 = 0x01, slot 7,8 = 0x00, */ + codec->codec_write(codec, 0x74, 0x00); + + /* we don't have the crystal when we are on an AMR card, so use + BIT_CLK as our clock source. Write the magic word ABBA and read + back to enable register 0x78 */ + codec->codec_write(codec, 0x76, 0xabba); + codec->codec_read(codec, 0x76); + + /* sync all the clocks*/ + codec->codec_write(codec, 0x78, 0x3802); + return 1; } diff --git a/drivers/sound/ad1816.c b/drivers/sound/ad1816.c index 8bd68c4dcb37..a92ab630f11c 100644 --- a/drivers/sound/ad1816.c +++ b/drivers/sound/ad1816.c @@ -6,16 +6,8 @@ * * Based on the CS4232/AD1848 driver Copyright (C) by Hannu Savolainen 1993-1996 * - * This software is still under development. New versions of the driver - * are available from: - * http://www.student.informatik.tu-darmstadt.de/~tek/projects/linux.html - * or http://www.tu-darmstadt.de/~tek01/projects/linux.html - * - * Please report any bugs to: tek@rbg.informatik.tu-darmstadt.de * - * - * version: 1.3 - * cvs: $Header: /home/tek/CVSROOT/sound22/ad1816.c,v 1.3 1999/04/18 16:41:41 tek Exp $ + * version: 1.3.1 * status: experimental * date: 1999/4/18 * @@ -34,18 +26,22 @@ * required by some Aztech/Newcom SC-16 cards. 1999/04/18 * * Christoph Hellwig: Adapted to module_init/module_exit. 2000/03/03 + * + * Christoph Hellwig: Added isapnp support 2000/03/15 */ #include #include +#include #include + #include "soundmodule.h" #include "sound_config.h" #define DEBUGNOISE(x) -#define DEBUGINFO(x) -#define DEBUGLOG(x) x -#define DEBUGWARN(x) x +#define DEBUGINFO(x) +#define DEBUGLOG(x) +#define DEBUGWARN(x) #define CHECK_FOR_POWER { int timeout=100; \ while (timeout > 0 && (inb(devc->base)&0x80)!= 0x80) {\ @@ -356,7 +352,7 @@ static void ad1816_trigger (int dev, int state) unsigned long flags; ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc; - DEBUGINFO (printk("ad1816: trigger called! (devc=%d,devc->base=%d\n",devc,devc->base)); + DEBUGINFO (printk("ad1816: trigger called! (devc=%d,devc->base=%d\n", devc, devc->base)); /* mode may have changed */ @@ -427,70 +423,38 @@ static unsigned int ad1816_set_bits (int dev, unsigned int arg) { ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc; - static struct format_tbl - { + static struct format_tbl { int format; unsigned char bits; - } - format2bits[] = - { - { - 0, 0 - } - , - { - AFMT_MU_LAW, 1 - } - , - { - AFMT_A_LAW, 3 - } - , - { - AFMT_IMA_ADPCM, 0 - } - , - { - AFMT_U8, 0 - } - , - { - AFMT_S16_LE, 2 - } - , - { - AFMT_S16_BE, 6 - } - , - { - AFMT_S8, 0 - } - , - { - AFMT_U16_LE, 0 - } - , - { - AFMT_U16_BE, 0 - } - }; + } format2bits[] = { + { 0, 0 }, + { AFMT_MU_LAW, 1 }, + { AFMT_A_LAW, 3 }, + { AFMT_IMA_ADPCM, 0 }, + { AFMT_U8, 0 }, + { AFMT_S16_LE, 2 }, + { AFMT_S16_BE, 6 }, + { AFMT_S8, 0 }, + { AFMT_U16_LE, 0 }, + { AFMT_U16_BE, 0 } + }; + int i, n = sizeof (format2bits) / sizeof (struct format_tbl); /* return current format */ - if (arg == 0) { + if (arg == 0) return devc->audio_format; - } devc->audio_format = arg; /* search matching format bits */ - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++) if (format2bits[i].format == arg) { devc->format_bits = format2bits[i].bits; devc->audio_format = arg; return arg; } - } + /* Still hanging here. Something must be terribly wrong */ devc->format_bits = 0; return devc->audio_format = AFMT_U8; @@ -500,9 +464,8 @@ static short ad1816_set_channels (int dev, short arg) { ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc; - if (arg != 1 && arg != 2) { + if (arg != 1 && arg != 2) return devc->channels; - } devc->channels = arg; return arg; @@ -515,9 +478,8 @@ static int ad1816_open (int dev, int mode) unsigned long flags; /* is device number valid ? */ - if (dev < 0 || dev >= num_audiodevs) { + if (dev < 0 || dev >= num_audiodevs) return -(ENXIO); - } /* get device info of this dev */ devc = (ad1816_info *) audio_devs[dev]->devc; @@ -600,10 +562,10 @@ static struct audio_driver ad1816_audio_driver = static void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy) { - unsigned char status; - ad1816_info *devc; - int dev; - unsigned long flags; + unsigned char status; + ad1816_info *devc; + int dev; + unsigned long flags; if (irq < 0 || irq > 15) { @@ -632,18 +594,15 @@ static void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy) devc->irq_ok=1; - if (status == 0) { + if (status == 0) DEBUGWARN(printk ("ad1816: interrupt: Got interrupt, but no reason?\n")); - } - if (devc->opened && (devc->audio_mode & PCM_ENABLE_INPUT) - && (status&64)){ + + if (devc->opened && (devc->audio_mode & PCM_ENABLE_INPUT) && (status&64)) DMAbuf_inputintr (dev); - } - if (devc->opened && (devc->audio_mode & PCM_ENABLE_OUTPUT) && - (status & 128)) { + if (devc->opened && (devc->audio_mode & PCM_ENABLE_OUTPUT) && (status & 128)) DMAbuf_outputintr (dev, 1); - } + restore_flags(flags); } @@ -659,7 +618,7 @@ struct mixer_def { }; static char mix_cvt[101] = { - 0, 0,3,7,10,13,16,19,21,23,26,28,30,32,34,35,37,39,40,42, + 0, 0, 3, 7,10,13,16,19,21,23,26,28,30,32,34,35,37,39,40,42, 43,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,64,65, 65,66,67,68,69,70,70,71,72,73,73,74,75,75,76,77,77,78,79,79, 80,81,81,82,82,83,84,84,85,85,86,86,87,87,88,88,89,89,90,90, @@ -705,23 +664,23 @@ MIX_ENT(SOUND_MIXER_LINE3, 39, 0, 9, 4, 39, 1, 0, 5) static unsigned short default_mixer_levels[SOUND_MIXER_NRDEVICES] = { - 0x4343, /* Master Volume */ - 0x3232, /* Bass */ - 0x3232, /* Treble */ - 0x0000, /* FM */ - 0x4343, /* PCM */ - 0x0000, /* PC Speaker */ - 0x0000, /* Ext Line */ - 0x0000, /* Mic */ - 0x0000, /* CD */ - 0x0000, /* Recording monitor */ - 0x0000, /* SB PCM */ - 0x0000, /* Recording level */ - 0x0000, /* Input gain */ - 0x0000, /* Output gain */ - 0x0000, /* Line1 */ - 0x0000, /* Line2 */ - 0x0000 /* Line3 (usually line in)*/ + 0x4343, /* Master Volume */ + 0x3232, /* Bass */ + 0x3232, /* Treble */ + 0x0000, /* FM */ + 0x4343, /* PCM */ + 0x0000, /* PC Speaker */ + 0x0000, /* Ext Line */ + 0x0000, /* Mic */ + 0x0000, /* CD */ + 0x0000, /* Recording monitor */ + 0x0000, /* SB PCM */ + 0x0000, /* Recording level */ + 0x0000, /* Input gain */ + 0x0000, /* Output gain */ + 0x0000, /* Line1 */ + 0x0000, /* Line2 */ + 0x0000 /* Line3 (usually line in)*/ }; #define LEFT_CHN 0 @@ -739,29 +698,24 @@ ad1816_set_recmask (ad1816_info * devc, int mask) n = 0; /* Count selected device bits */ - for (i = 0; i < 32; i++) { - if (mask & (1 << i)) { + for (i = 0; i < 32; i++) + if (mask & (1 << i)) n++; - } - } - if (n == 0) { + if (n == 0) mask = SOUND_MASK_MIC; - } else if (n != 1) { /* Too many devices selected */ + else if (n != 1) { /* Too many devices selected */ /* Filter out active settings */ mask &= ~devc->recmask; n = 0; /* Count selected device bits */ - for (i = 0; i < 32; i++) { - if (mask & (1 << i)) { + for (i = 0; i < 32; i++) + if (mask & (1 << i)) n++; - } - } - if (n != 1) { + if (n != 1) mask = SOUND_MASK_MIC; - } } switch (mask) { @@ -810,9 +764,8 @@ change_bits (int *regval, int dev, int chn, int newval) /* Reverse polarity*/ - if (mix_devices[dev][chn].polarity == 1) { + if (mix_devices[dev][chn].polarity == 1) newval = 100 - newval; - } mask = (1 << mix_devices[dev][chn].nbits) - 1; shift = mix_devices[dev][chn].bitpos; @@ -830,12 +783,10 @@ ad1816_mixer_get (ad1816_info * devc, int dev) DEBUGINFO(printk("ad1816: mixer_get called!\n")); /* range check + supported mixer check */ - if (dev < 0 || dev >= SOUND_MIXER_NRDEVICES ) { + if (dev < 0 || dev >= SOUND_MIXER_NRDEVICES ) return (-(EINVAL)); - } - if (!((1 << dev) & devc->supported_devices)) { + if (!((1 << dev) & devc->supported_devices)) return -(EINVAL); - } return devc->levels[dev]; } @@ -853,27 +804,21 @@ ad1816_mixer_set (ad1816_info * devc, int dev, int value) DEBUGINFO(printk("ad1816: mixer_set called!\n")); - if (dev < 0 || dev >= SOUND_MIXER_NRDEVICES ) { + if (dev < 0 || dev >= SOUND_MIXER_NRDEVICES ) return -(EINVAL); - } - if (left > 100) { + if (left > 100) left = 100; - } - if (left < 0) { + if (left < 0) left = 0; - } - if (right > 100) { + if (right > 100) right = 100; - } - if (right < 0) { + if (right < 0) right = 0; - } /* Mono control */ - if (mix_devices[dev][RIGHT_CHN].nbits == 0) { + if (mix_devices[dev][RIGHT_CHN].nbits == 0) right = left; - } retvol = left | (right << 8); /* Scale it */ @@ -882,14 +827,12 @@ ad1816_mixer_set (ad1816_info * devc, int dev, int value) right = mix_cvt[right]; /* reject all mixers that are not supported */ - if (!(devc->supported_devices & (1 << dev))) { + if (!(devc->supported_devices & (1 << dev))) return -(EINVAL); - } /* sanity check */ - if (mix_devices[dev][LEFT_CHN].nbits == 0) { + if (mix_devices[dev][LEFT_CHN].nbits == 0) return -(EINVAL); - } /* keep precise volume internal */ devc->levels[dev] = retvol; @@ -905,11 +848,10 @@ ad1816_mixer_set (ad1816_info * devc, int dev, int value) if ( regoffs==5 || regoffs==14 || regoffs==15 || regoffs==16 || regoffs==17 || regoffs==18 || regoffs==19 || regoffs==39) { - if (left==0) { + if (left==0) valmute |= 0x8000; - } else { + else valmute &= ~0x8000; - } } ad_write (devc, regoffs, valmute); /* mute */ @@ -918,9 +860,9 @@ ad1816_mixer_set (ad1816_info * devc, int dev, int value) */ /* Was just a mono channel */ - if (mix_devices[dev][RIGHT_CHN].nbits == 0) { + if (mix_devices[dev][RIGHT_CHN].nbits == 0) return retvol; - } + regoffs = mix_devices[dev][RIGHT_CHN].regno; val = ad_read (devc, regoffs); change_bits (&val, dev, RIGHT_CHN, right); @@ -929,11 +871,10 @@ ad1816_mixer_set (ad1816_info * devc, int dev, int value) if ( regoffs==5 || regoffs==14 || regoffs==15 || regoffs==16 || regoffs==17 || regoffs==18 || regoffs==19 || regoffs==39) { - if (right==0) { + if (right==0) valmute |= 0x80; - } else { + else valmute &= ~0x80; - } } ad_write (devc, regoffs, valmute); /* mute */ @@ -968,11 +909,9 @@ ad1816_mixer_reset (ad1816_info * devc) devc->supported_rec_devices = REC_DEVICES; - for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { - if (devc->supported_devices & (1 << i)) { + for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) + if (devc->supported_devices & (1 << i)) ad1816_mixer_set (devc, i, default_mixer_levels[i]); - } - } ad1816_set_recmask (devc, SOUND_MASK_MIC); } @@ -992,22 +931,19 @@ ad1816_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg) switch (cmd & 0xff){ case SOUND_MIXER_RECSRC: - if (get_user(val, (int *)arg)) { + if (get_user(val, (int *)arg)) return -EFAULT; - } val=ad1816_set_recmask (devc, val); - return put_user(val, (int *)arg); + return put_user(val, (int *)arg); break; default: - if (get_user(val, (int *)arg)){ + if (get_user(val, (int *)arg)) return -EFAULT; - } - if ((val=ad1816_mixer_set (devc, cmd & 0xff, val))<0) { + if ((val=ad1816_mixer_set (devc, cmd & 0xff, val))<0) return val; - } else { + else return put_user(val, (int *)arg); - } } } else { /* read ioctl */ @@ -1039,25 +975,22 @@ ad1816_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg) break; default: - if ((val=ad1816_mixer_get (devc, cmd & 0xff))<0) { + if ((val=ad1816_mixer_get (devc, cmd & 0xff))<0) return val; - } else { + else return put_user(val, (int *)arg); - } } } - } else { + } else /* not for mixer */ return -(EINVAL); - } } /* ------------------------------------------------------------------- */ /* Mixer structure */ -static struct mixer_operations ad1816_mixer_operations = -{ +static struct mixer_operations ad1816_mixer_operations = { "AD1816", "AD1816 Mixer", ad1816_mixer_ioctl @@ -1076,7 +1009,7 @@ static int __init probe_ad1816 ( struct address_info *hw_config ) int io_base=hw_config->io_base; int *osp=hw_config->osp; int tmp; - + printk("ad1816: AD1816 sounddriver Copyright (C) 1998 by Thorsten Knabe\n"); printk("ad1816: io=0x%x, irq=%d, dma=%d, dma2=%d, clockfreq=%d, options=%d isadmabug=%d\n", hw_config->io_base, @@ -1098,7 +1031,7 @@ static int __init probe_ad1816 ( struct address_info *hw_config ) printk ("ad1816: detect error - step 0\n"); return 0; } - + devc->base = io_base; devc->irq_ok = 0; devc->irq = 0; @@ -1126,7 +1059,8 @@ static int __init probe_ad1816 ( struct address_info *hw_config ) DEBUGLOG (printk ("ad1816: Chip is not an AD1816 (Test 2)\n")); return(0); } - + + /* writes to ireg 10 are copied to ireg 11 */ ad_write(devc,10,54321); if (ad_read(devc,11)!=54321) { @@ -1140,7 +1074,7 @@ static int __init probe_ad1816 ( struct address_info *hw_config ) DEBUGLOG (printk ("ad1816: Chip is not an AD1816 (Test 4)\n")); return(0); } - + /* bit in base +1 cannot be set to 1 */ tmp=inb(devc->base+1); outb(0xff,devc->base+1); @@ -1152,7 +1086,7 @@ static int __init probe_ad1816 ( struct address_info *hw_config ) DEBUGLOG (printk ("ad1816: detect() - Detected OK\n")); DEBUGLOG (printk ("ad1816: AD1816 Version: %d\n",ad_read(devc,45))); - + /* detection was successful */ return 1; } @@ -1330,6 +1264,22 @@ static int __initdata irq = -1; static int __initdata dma = -1; static int __initdata dma2 = -1; +#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +struct pci_dev *ad1816_dev = NULL, + *mpu_dev = NULL; + +static int activated = 1; + +static int isapnp = 1; +static int isapnpjump = 0; + +MODULE_PARM(isapnp, "i"); +MODULE_PARM(isapnpjump, "i"); + +#else +static int isapnp = 0; +#endif + MODULE_PARM(io,"i"); MODULE_PARM(irq,"i"); MODULE_PARM(dma,"i"); @@ -1337,12 +1287,132 @@ MODULE_PARM(dma2,"i"); MODULE_PARM(ad1816_clockfreq,"i"); MODULE_PARM(options,"i"); +#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE + +static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev) +{ + int err; + + if(dev->active) { + activated = 0; + return(dev); + } + + if((err = dev->activate(dev)) < 0) { + printk(KERN_ERR "ad1816: %s %s config failed (out of resources?)[%d]\n", + devname, resname, err); + dev->deactivate(dev); + return(NULL); + } + + return(dev); +} + +static struct pci_dev *ad1816_init_generic(struct pci_bus *bus, struct pci_dev *card, + struct address_info *hw_config) +{ + if((ad1816_dev = isapnp_find_dev(bus, card->vendor, card->device, NULL))) { + ad1816_dev->prepare(ad1816_dev); + + if((ad1816_dev = activate_dev("Analog Devices 1816(A)", "ad1816", ad1816_dev))) { + hw_config->io_base = ad1816_dev->resource[2].start; + hw_config->irq = ad1816_dev->irq_resource[0].start; + hw_config->dma = ad1816_dev->dma_resource[0].start; + hw_config->dma2 = ad1816_dev->dma_resource[1].start; + } + } + + return(ad1816_dev); +} + +static struct { + unsigned short vendor; + unsigned short function; + struct pci_dev * (*initfunc)(struct pci_bus*, struct pci_dev *, struct address_info *); + char *name; +} isapnp_ad1816_list[] __initdata = { + {ISAPNP_VENDOR('A','D','S'), ISAPNP_FUNCTION(0x7150), &ad1816_init_generic, "Analog Devices 1815" }, + {ISAPNP_VENDOR('A','D','S'), ISAPNP_FUNCTION(0x7180), &ad1816_init_generic, "Analog Devices 1816A" }, + {0} +}; + +static int __init ad1816_init_isapnp(struct address_info *hw_config, + struct pci_bus *bus, struct pci_dev *card, int slot) +{ + struct pci_dev *idev = NULL; + + /* You missed the init func? That's bad. */ + if(isapnp_ad1816_list[slot].initfunc) { + char *busname = bus->name[0] ? bus->name : isapnp_ad1816_list[slot].name; + + printk(KERN_INFO "ad1816: %s detected\n", busname); + + /* Initialize this baby. */ + if((idev = isapnp_ad1816_list[slot].initfunc(bus, card, hw_config))) { + /* We got it. */ + + printk(KERN_NOTICE "ad1816: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n", + busname, + hw_config->io_base, hw_config->irq, hw_config->dma, + hw_config->dma2); + return 1; + } else + printk(KERN_INFO "ad1816: Failed to initialize %s\n", busname); + } else + printk(KERN_ERR "ad1816: Bad entry in ad1816.c PnP table\n"); + + return 0; +} + +/* + * Actually this routine will detect and configure only the first card with successful + * initialization. isapnpjump could be used to jump to a specific entry. + * Please always add entries at the end of the array. + * Should this be fixed? - azummo + */ + +int __init ad1816_probe_isapnp(struct address_info *hw_config) +{ + int i; + + /* Count entries in isapnp_ad1816_list */ + for (i = 0; isapnp_ad1816_list[i].vendor != 0; i++) + ; + /* Check and adjust isapnpjump */ + if( isapnpjump < 0 || isapnpjump > ( i - 1 ) ) { + printk(KERN_ERR "ad1816: Valid range for isapnpjump is 0-%d. Adjusted to 0.\n", i-1); + isapnpjump = 0; + } + + for (i = isapnpjump; isapnp_ad1816_list[i].vendor != 0; i++) { + struct pci_dev *card = NULL; + + while ((card = isapnp_find_dev(NULL, isapnp_ad1816_list[i].vendor, + isapnp_ad1816_list[i].function, card))) + if(ad1816_init_isapnp(hw_config, card->bus, card, i)) + return 0; + } + + return -ENODEV; +} +#endif + static int __init init_ad1816(void) { - cfg.io_base = io; - cfg.irq = irq; - cfg.dma = dma; - cfg.dma2 = dma2; + +#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE + if(isapnp && (ad1816_probe_isapnp(&cfg) < 0) ) { + printk(KERN_NOTICE "ad1816: No ISAPnP cards found, trying standard ones...\n"); + isapnp = 0; + } +#endif + + if( isapnp == 0) { + cfg.io_base = io; + cfg.irq = irq; + cfg.dma = dma; + cfg.dma2 = dma2; + } if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.dma2 == -1) { printk(KERN_INFO "ad1816: dma, dma2, irq and io must be set.\n"); @@ -1352,9 +1422,11 @@ static int __init init_ad1816(void) if (probe_ad1816(&cfg) == 0) { return -ENODEV; } - + attach_ad1816(&cfg); SOUND_LOCK; + + return 0; } static void __exit cleanup_ad1816 (void) @@ -1370,6 +1442,11 @@ static void __exit cleanup_ad1816 (void) nr_ad1816_devs=0; SOUND_LOCK_END; +#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE + if(activated) + if(ad1816_dev) + ad1816_dev->deactivate(ad1816_dev); +#endif } module_init(init_ad1816); diff --git a/drivers/sound/dev_table.c b/drivers/sound/dev_table.c index 99a4d8f44962..0a1e2981c11f 100644 --- a/drivers/sound/dev_table.c +++ b/drivers/sound/dev_table.c @@ -210,6 +210,7 @@ void sound_unload_mixerdev(int dev) { mixer_devs[dev] = NULL; unregister_sound_mixer(dev<<4); + num_mixers--; } } diff --git a/drivers/sound/sb_common.c b/drivers/sound/sb_common.c index 25318c1acade..5fb40f46d3ff 100644 --- a/drivers/sound/sb_common.c +++ b/drivers/sound/sb_common.c @@ -908,10 +908,13 @@ void sb_dsp_unload(struct address_info *hw_config, int sbmpu) } if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI)) { + extern int sbmixnum; + if (devc->irq > 0) free_irq(devc->irq, devc); sound_unload_mixerdev(devc->my_mixerdev); + sbmixnum--; /* We don't have to do this bit any more the UART401 is its own master -- Krzysztof Halasa */ /* But we have to do it, if UART401 is not detected */ diff --git a/drivers/sound/trident.c b/drivers/sound/trident.c index b3a9f750402a..38afc31c9824 100644 --- a/drivers/sound/trident.c +++ b/drivers/sound/trident.c @@ -29,6 +29,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * History + * v0.14 Mar 15 2000 Ollie Lho + * 5.1 channel output support with channel binding. What's the Matrix ? + * v0.13.1 Mar 10 2000 Ollie Lho + * few minor bugs on dual codec support, needs more testing * v0.13 Mar 03 2000 Ollie Lho * new pci_* for 2.4 kernel, back ported to 2.2 * v0.12 Feb 23 2000 Ollie Lho @@ -62,14 +66,14 @@ * * ToDo * Clean up of low level channel register access code. (done) - * Fix the bug on dma buffer management in update_ptr, read/write, drain_dac (done) - * Dual AC97 codecs support (done partially, need channel binding to test) + * Fix the bug on dma buffer management in update_ptr, read/write, drain_dac (done) + * Dual AC97 codecs support (done) * Recording support (done) * Mmap support - * "Channel Binding" ioctl extension - * new pci device driver interface for 2.4 kernel + * "Channel Binding" ioctl extension (done) + * new pci device driver interface for 2.4 kernel (done) */ - + #include #include #include @@ -92,7 +96,7 @@ #include "trident.h" -#define DRIVER_VERSION "0.13" +#define DRIVER_VERSION "0.14" /* magic numbers to protect our data structures */ #define TRIDENT_CARD_MAGIC 0x5072696E /* "Prin" */ @@ -106,9 +110,15 @@ have 2 SDATA_IN lines (currently) */ #define NR_AC97 2 +/* minor number of /dev/dspW */ +#define SND_DEV_DSP8 3 + /* minor number of /dev/dspW */ #define SND_DEV_DSP16 5 +/* minor number of /dev/swmodem (temporary, experimental) */ +#define SND_DEV_SWMODEM 7 + static const unsigned sample_size[] = { 1, 2, 2, 4 }; static const unsigned sample_shift[] = { 0, 1, 1, 2 }; @@ -126,7 +136,7 @@ static char * card_names[] = { "SiS 7018 PCI Audio" }; -static struct pci_device_id trident_pci_tbl [] __devinitdata = { +static struct pci_device_id trident_pci_tbl [] __initdata = { {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TRIDENT_4D_DX}, {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX, @@ -256,6 +266,19 @@ struct trident_card { u32 irq; }; +/* table to map from CHANNELMASK to channel attribute for SiS 7018 */ +static u16 mask2attr [] = +{ + PCM_LR, PCM_LR, SURR_LR, CENTER_LFE, + HSET, MIC, MODEM_LINE1, MODEM_LINE2, + I2S_LR, SPDIF_LR +}; +/* table to map from channel attribute to CHANNELMASK for SiS 7018 */ +static int attr2mask [] = { + DSP_BIND_MODEM1, DSP_BIND_MODEM2, DSP_BIND_FRONT, DSP_BIND_HANDSET, + DSP_BIND_I2S, DSP_BIND_CENTER_LFE, DSP_BIND_SURR, DSP_BIND_SPDIF +}; + static struct trident_card *devs = NULL; static void trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val); @@ -596,11 +619,7 @@ static void trident_play_setup(struct trident_state *state) channel->eso = dmabuf->dmasize >> sample_shift[dmabuf->fmt]; channel->eso -= 1; - if (state->card->pci_id == PCI_DEVICE_ID_SI_7018) { - /* FIXME: channel attributes are configured by ioctls, but it is not - implemented so just set to ZERO for the moment */ - channel->attribute = 0; - } else { + if (state->card->pci_id != PCI_DEVICE_ID_SI_7018) { channel->attribute = 0; } @@ -660,12 +679,7 @@ static void trident_rec_setup(struct trident_state *state) channel->eso = dmabuf->dmasize >> sample_shift[dmabuf->fmt]; channel->eso -= 1; - if (state->card->pci_id == PCI_DEVICE_ID_SI_7018) { - /* FIXME: channel attributes are configured by ioctls, but it is not - implemented so just set to 0x8a80 for the moment, record from PCM L/R - input and mono = (left + right + 1)/2*/ - channel->attribute = 0x8A80; - } else { + if (state->card->pci_id != PCI_DEVICE_ID_SI_7018) { channel->attribute = 0; } @@ -1577,7 +1591,8 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm return 0; case SNDCTL_DSP_GETCAPS: - return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP, (int *)arg); + return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP|DSP_CAP_BIND, + (int *)arg); case SNDCTL_DSP_GETTRIGGER: val = 0; @@ -1656,6 +1671,28 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm return put_user((dmabuf->fmt & TRIDENT_FMT_16BIT) ? AFMT_S16_LE : AFMT_U8, (int *)arg); + case SNDCTL_DSP_GETCHANNELMASK: + return put_user(DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE, + (int *)arg); + + case SNDCTL_DSP_BIND_CHANNEL: + if (state->card->pci_id != PCI_DEVICE_ID_SI_7018) + return -EINVAL; + + get_user_ret(val, (int *)arg, -EFAULT); + if (val == DSP_BIND_QUERY) { + val = dmabuf->channel->attribute | 0x3c00; + val = attr2mask[val >> 8]; + } else { + dmabuf->ready = 0; + if (file->f_mode & FMODE_READ) + dmabuf->channel->attribute = (CHANNEL_REC|SRC_ENABLE); + if (file->f_mode & FMODE_WRITE) + dmabuf->channel->attribute = (CHANNEL_SPC_PB|SRC_ENABLE); + dmabuf->channel->attribute |= mask2attr[ffs(val)]; + } + return put_user(val, (int *)arg); + case SNDCTL_DSP_MAPINBUF: case SNDCTL_DSP_MAPOUTBUF: case SNDCTL_DSP_SETSYNCRO: @@ -1673,6 +1710,7 @@ static int trident_open(struct inode *inode, struct file *file) int minor = MINOR(inode->i_rdev); struct trident_card *card = devs; struct trident_state *state = NULL; + struct dmabuf *dmabuf = NULL; /* find an avaiable virtual channel (instance of /dev/dsp) */ while (card != NULL) { @@ -1683,6 +1721,7 @@ static int trident_open(struct inode *inode, struct file *file) if (state == NULL) return -ENOMEM; memset(state, 0, sizeof(struct trident_state)); + dmabuf = &state->dmabuf; goto found_virt; } } @@ -1694,7 +1733,7 @@ static int trident_open(struct inode *inode, struct file *file) found_virt: /* found a free virtual channel, allocate hardware channels */ - if ((state->dmabuf.channel = trident_alloc_pcm_channel(card)) == NULL) { + if ((dmabuf->channel = trident_alloc_pcm_channel(card)) == NULL) { kfree (card->states[i]); card->states[i] = NULL;; return -ENODEV; @@ -1704,7 +1743,7 @@ static int trident_open(struct inode *inode, struct file *file) state->virt = i; state->card = card; state->magic = TRIDENT_STATE_MAGIC; - init_waitqueue_head(&state->dmabuf.wait); + init_waitqueue_head(&dmabuf->wait); init_MUTEX(&state->open_sem); file->private_data = state; @@ -1714,24 +1753,34 @@ static int trident_open(struct inode *inode, struct file *file) should be default to unsigned 8-bits, mono, with sample rate 8kHz and /dev/dspW will accept 16-bits sample */ if (file->f_mode & FMODE_WRITE) { - state->dmabuf.fmt &= ~TRIDENT_FMT_MASK; - if ((minor & 0xf) == SND_DEV_DSP16) - state->dmabuf.fmt |= TRIDENT_FMT_16BIT; - state->dmabuf.ossfragshift = 0; - state->dmabuf.ossmaxfrags = 0; - state->dmabuf.subdivision = 0; + dmabuf->fmt &= ~TRIDENT_FMT_MASK; + if ((minor & 0x0f) == SND_DEV_DSP16) + dmabuf->fmt |= TRIDENT_FMT_16BIT; + dmabuf->ossfragshift = 0; + dmabuf->ossmaxfrags = 0; + dmabuf->subdivision = 0; + if (card->pci_id == PCI_DEVICE_ID_SI_7018) { + /* set default channel attribute to normal playback */ + dmabuf->channel->attribute = CHANNEL_PB; + } trident_set_dac_rate(state, 8000); } if (file->f_mode & FMODE_READ) { /* FIXME: Trident 4d can only record in singed 16-bits stereo, 48kHz sample, to be dealed with in trident_set_adc_rate() ?? */ - state->dmabuf.fmt &= ~TRIDENT_FMT_MASK; - if ((minor & 0xf) == SND_DEV_DSP16) - state->dmabuf.fmt |= TRIDENT_FMT_16BIT; - state->dmabuf.ossfragshift = 0; - state->dmabuf.ossmaxfrags = 0; - state->dmabuf.subdivision = 0; + dmabuf->fmt &= ~TRIDENT_FMT_MASK; + if ((minor & 0x0f) == SND_DEV_DSP16) + dmabuf->fmt |= TRIDENT_FMT_16BIT; + dmabuf->ossfragshift = 0; + dmabuf->ossmaxfrags = 0; + dmabuf->subdivision = 0; + if (card->pci_id == PCI_DEVICE_ID_SI_7018) { + /* set default channel attribute to 0x8a80, record from + PCM L/R FIFO and mono = (left + right + 1)/2*/ + dmabuf->channel->attribute = + (CHANNEL_REC|PCM_LR|MONO_MIX); + } trident_set_adc_rate(state, 8000); } @@ -1860,7 +1909,7 @@ static u16 trident_ac97_get(struct ac97_codec *codec, u8 reg) address = SI_AC97_READ; mask = SI_AC97_BUSY_READ | SI_AC97_AUDIO_BUSY; if (codec->id) - mask |= SI_AC97_SECONDARY; + mask |= SI_AC97_SECONDARY; busy = SI_AC97_BUSY_READ; break; case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX: @@ -1873,7 +1922,7 @@ static u16 trident_ac97_get(struct ac97_codec *codec, u8 reg) else address = NX_ACR2_AC97_R_PRIMARY; mask = NX_AC97_BUSY_READ; - busy = 0x0c00; + busy = NX_AC97_BUSY_READ | NX_AC97_BUSY_DATA; break; } @@ -1953,9 +2002,13 @@ static int __init trident_ac97_init(struct trident_card *card) case PCI_DEVICE_ID_SI_7018: /* disable AC97 GPIO interrupt */ outl(0x00, TRID_REG(card, SI_AC97_GPIO)); - /* stop AC97 cold reset process */ - outl(PCMOUT|SECONDARY_ID, TRID_REG(card, SI_SERIAL_INTF_CTRL)); - ready_2nd = inl(TRID_REG(card, SI_SERIAL_INTF_CTRL)); + /* when power up the AC link is in cold reset mode so stop it */ + outl(PCMOUT|SURROUT|CENTEROUT|LFEOUT|SECONDARY_ID, + TRID_REG(card, SI_SERIAL_INTF_CTRL)); + /* it take a long time to recover from a cold reset (especially when you have + more than one codec) */ + udelay(2000); + ready_2nd = inl(TRID_REG(card, SI_SERIAL_INTF_CTRL)); ready_2nd &= SI_AC97_SECONDARY_READY; break; case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX: @@ -1972,7 +2025,7 @@ static int __init trident_ac97_init(struct trident_card *card) for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) { if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL) - return -1; + return -ENOMEM; memset(codec, 0, sizeof(struct ac97_codec)); /* initialize some basic codec information, other fields will be filled @@ -2004,7 +2057,7 @@ static int __init trident_ac97_init(struct trident_card *card) /* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered untill "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */ -static int __devinit trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) +static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { unsigned long iobase; struct trident_card *card; @@ -2012,19 +2065,19 @@ static int __devinit trident_probe(struct pci_dev *pci_dev, const struct pci_dev if (!pci_dma_supported(pci_dev, TRIDENT_DMA_MASK)) { printk(KERN_ERR "trident: architecture does not support" " 30bit PCI busmaster DMA\n"); - return -1; + return -ENODEV; } iobase = pci_dev->resource[0].start; if (check_region(iobase, 256)) { printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n", iobase); - return -1; + return -ENODEV; } if ((card = kmalloc(sizeof(struct trident_card), GFP_KERNEL)) == NULL) { printk(KERN_ERR "trident: out of memory\n"); - return -1; + return -ENOMEM; } memset(card, 0, sizeof(*card)); @@ -2054,7 +2107,7 @@ static int __devinit trident_probe(struct pci_dev *pci_dev, const struct pci_dev printk(KERN_ERR "trident: unable to allocate irq %d\n", card->irq); release_region(card->iobase, 256); kfree(card); - return 0; + return -ENODEV; } /* register /dev/dsp */ if ((card->dev_audio = register_sound_dsp(&trident_audio_fops, -1)) < 0) { @@ -2062,7 +2115,7 @@ static int __devinit trident_probe(struct pci_dev *pci_dev, const struct pci_dev release_region(iobase, 256); free_irq(card->irq, card); kfree(card); - return -1; + return -ENODEV; } /* initilize AC97 codec and register /dev/mixer */ if (trident_ac97_init(card) <= 0) { @@ -2070,7 +2123,7 @@ static int __devinit trident_probe(struct pci_dev *pci_dev, const struct pci_dev release_region(iobase, 256); free_irq(card->irq, card); kfree(card); - return -1; + return -ENODEV; } outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL)); @@ -2083,7 +2136,7 @@ static int __devinit trident_probe(struct pci_dev *pci_dev, const struct pci_dev return 0; } -static void __devexit trident_remove(struct pci_dev *pci_dev) +static void __exit trident_remove(struct pci_dev *pci_dev) { int i; struct trident_card *card = pci_dev->driver_data; @@ -2120,15 +2173,22 @@ static struct pci_driver trident_pci_driver = { static int __init trident_init_module (void) { + if (!pci_present()) /* No PCI bus in this machine! */ + return -ENODEV; + printk(KERN_INFO "Trident 4DWave/SiS 7018 PCI Audio, version " DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n"); - return pci_module_init (&trident_pci_driver); + if (!pci_register_driver(&trident_pci_driver)) { + pci_unregister_driver(&trident_pci_driver); + return -ENODEV; + } + return 0; } static void __exit trident_cleanup_module (void) { - pci_unregister_driver (&trident_pci_driver); + pci_unregister_driver(&trident_pci_driver); } module_init(trident_init_module); diff --git a/drivers/sound/trident.h b/drivers/sound/trident.h index 6bbb25bd1594..847f85d873cf 100644 --- a/drivers/sound/trident.h +++ b/drivers/sound/trident.h @@ -62,6 +62,7 @@ #define DAC_RUNNING 0x01 #define ADC_RUNNING 0x02 + /* Register Addresses */ /* operational registers common to DX, NX, 7018 */ @@ -130,7 +131,7 @@ enum trident_dx_ac97_bits { enum trident_nx_ac97_bits { /* ACR1-3 */ NX_AC97_BUSY_WRITE = 0x0800, NX_AC97_BUSY_READ = 0x0800, - NX_AC97_WRITE_SECONDARY = 0x0100, + NX_AC97_BUSY_DATA = 0x0400, NX_AC97_WRITE_SECONDARY = 0x0100, /* ACR0 */ NX_AC97_SECONDARY_READY = 0x0040, NX_AC97_SECONDARY_RECORD = 0x0020, NX_AC97_SURROUND_OUTPUT = 0x0010, @@ -148,7 +149,7 @@ enum serial_intf_ctrl_bits { MICIN = 0x00000400, LINE2IN = 0x00000800, HEAD_SET_IN = 0x00001000, GPIOIN = 0x00002000, /* 7018 spec says id = 01 but the demo board routed to 10 - SECONDARY_ID= 0x00008000, */ + SECONDARY_ID= 0x00004000, */ SECONDARY_ID= 0x00004000, PCMOUT = 0x00010000, SURROUT = 0x00020000, CENTEROUT = 0x00040000, LFEOUT = 0x00080000, @@ -173,10 +174,18 @@ enum channel_control_bits { }; enum channel_attribute { - MODEM_LINE1, MODEM_LINE2, PCM_LR, HSET, - I2SLR, CENTER_LFE, SURR_LR, SPDIF_LR, - CHANNEL_PB = 0x00000000, CHANNEL_SPC_PB = 0x40000000, - CHANNEL_REC = 0x80000000, CHANNEL_REC_PB = 0xc0000000 + /* playback/record select */ + CHANNEL_PB = 0x0000, CHANNEL_SPC_PB = 0x4000, + CHANNEL_REC = 0x8000, CHANNEL_REC_PB = 0xc000, + /* playback destination/record source select */ + MODEM_LINE1 = 0x0000, MODEM_LINE2 = 0x0400, + PCM_LR = 0x0800, HSET = 0x0c00, + I2S_LR = 0x1000, CENTER_LFE = 0x1400, + SURR_LR = 0x1800, SPDIF_LR = 0x1c00, + MIC = 0x1400, + /* mist stuff */ + MONO_LEFT = 0x0000, MONO_RIGHT = 0x0100, + MONO_MIX = 0x0200, SRC_ENABLE = 0x0080, }; enum miscint_bits { @@ -190,12 +199,6 @@ enum miscint_bits { ST_IRQ_EN = 0x00800000, ACGPIO_IRQ = 0x01000000 }; -#define AC97_SIGMATEL_DAC2INVERT 0x6E -#define AC97_SIGMATEL_BIAS1 0x70 -#define AC97_SIGMATEL_BIAS2 0x72 -#define AC97_SIGMATEL_CIC1 0x76 -#define AC97_SIGMATEL_CIC2 0x78 - #define TRID_REG( trident, x ) ( (trident) -> iobase + (x) ) #define VALIDATE_MAGIC(FOO,MAG) \ diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c index 1aa665d1c8d9..2c2e7d32d2fc 100644 --- a/fs/autofs/inode.c +++ b/fs/autofs/inode.c @@ -253,7 +253,6 @@ fail_iput: fail_free: kfree(sbi); fail_unlock: -fail_dec: return NULL; } diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 815208e09a09..f755adc8cc8a 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -42,8 +42,10 @@ static int nfsctl_export(struct nfsctl_export *data); static int nfsctl_unexport(struct nfsctl_export *data); static int nfsctl_getfh(struct nfsctl_fhparm *, __u8 *); static int nfsctl_getfd(struct nfsctl_fdparm *, __u8 *); +#ifdef notyet static int nfsctl_getfs(struct nfsctl_fsparm *, struct knfsd_fh *); -/* static int nfsctl_ugidupdate(struct nfsctl_ugidmap *data); */ +static int nfsctl_ugidupdate(struct nfsctl_ugidmap *data); +#endif static int initialized = 0; diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 2f315ccd92eb..fc9555b77d07 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c @@ -347,19 +347,19 @@ int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned char *data; int mask = (1 << hd->minor_shift) - 1; int sector_size = get_hardsect_size(dev) / 512; -#ifdef CONFIG_BLK_DEV_IDE +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) int tested_for_xlate = 0; read_mbr: -#endif /* CONFIG_BLK_DEV_IDE */ +#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_IDE_MODULE) */ if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) { if (warn_no_part) printk(" unable to read partition table\n"); return -1; } data = bh->b_data; -#ifdef CONFIG_BLK_DEV_IDE +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) check_table: -#endif /* CONFIG_BLK_DEV_IDE */ +#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_IDE_MODULE) */ /* Use bforget(), because we may have changed the disk geometry */ if (*(unsigned short *) (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) { bforget(bh); @@ -367,7 +367,7 @@ check_table: } p = (struct partition *) (0x1be + data); -#ifdef CONFIG_BLK_DEV_IDE +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) if (!tested_for_xlate++) { /* Do this only once per disk */ /* * Look for various forms of IDE disk geometry translation @@ -423,7 +423,7 @@ check_table: (void) ide_xlate_1024(dev, 2, heads, " [PTBL]"); } } -#endif /* CONFIG_BLK_DEV_IDE */ +#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_IDE_MODULE) */ /* Look for partitions in two passes: First find the primary partitions, and the DOS-type extended partitions. diff --git a/include/asm-alpha/core_cia.h b/include/asm-alpha/core_cia.h index 418aa34920b2..abd667ac7867 100644 --- a/include/asm-alpha/core_cia.h +++ b/include/asm-alpha/core_cia.h @@ -8,8 +8,13 @@ #include /* - * CIA is the internal name for the 2117x chipset which provides + * CIA is the internal name for the 21171 chipset which provides * memory controller and PCI access for the 21164 chip based systems. + * Also supported here is the 21172 (CIA-2) and 21174 (PYXIS). + * + * The lineage is a bit confused, since the 21174 was reportedly started + * from the 21171 Pass 1 mask, and so is missing bug fixes that appear + * in 21171 Pass 2 and 21172, but it also contains additional features. * * This file is based on: * @@ -22,24 +27,8 @@ * */ -/*------------------------------------------------------------------------** -** ** -** EB164 I/O procedures ** -** ** -** inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers ** -** inportbxt: 8 bits only ** -** inport: alias of inportw ** -** outport: alias of outportw ** -** ** -** inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers ** -** inmembxt: 8 bits only ** -** inmem: alias of inmemw ** -** outmem: alias of outmemw ** -** ** -**------------------------------------------------------------------------*/ - - -/* CIA ADDRESS BIT DEFINITIONS +/* + * CIA ADDRESS BIT DEFINITIONS * * 3333 3333 3322 2222 2222 1111 1111 11 * 9876 5432 1098 7654 3210 9876 5432 1098 7654 3210 @@ -78,91 +67,168 @@ #define CIA_MEM_R3_MASK 0x03ffffff /* SPARSE Mem region 3 mask is 26 bits */ /* - * 21171-CA Control and Status Registers (p4-1) + * 21171-CA Control and Status Registers + */ +#define CIA_IOC_CIA_REV (IDENT_ADDR + 0x8740000080UL) +# define CIA_REV_MASK 0xff +#define CIA_IOC_PCI_LAT (IDENT_ADDR + 0x87400000C0UL) +#define CIA_IOC_CIA_CTRL (IDENT_ADDR + 0x8740000100UL) +# define CIA_CTRL_PCI_EN (1 << 0) +# define CIA_CTRL_PCI_LOCK_EN (1 << 1) +# define CIA_CTRL_PCI_LOOP_EN (1 << 2) +# define CIA_CTRL_FST_BB_EN (1 << 3) +# define CIA_CTRL_PCI_MST_EN (1 << 4) +# define CIA_CTRL_PCI_MEM_EN (1 << 5) +# define CIA_CTRL_PCI_REQ64_EN (1 << 6) +# define CIA_CTRL_PCI_ACK64_EN (1 << 7) +# define CIA_CTRL_ADDR_PE_EN (1 << 8) +# define CIA_CTRL_PERR_EN (1 << 9) +# define CIA_CTRL_FILL_ERR_EN (1 << 10) +# define CIA_CTRL_MCHK_ERR_EN (1 << 11) +# define CIA_CTRL_ECC_CHK_EN (1 << 12) +# define CIA_CTRL_ASSERT_IDLE_BC (1 << 13) +# define CIA_CTRL_COM_IDLE_BC (1 << 14) +# define CIA_CTRL_CSR_IOA_BYPASS (1 << 15) +# define CIA_CTRL_IO_FLUSHREQ_EN (1 << 16) +# define CIA_CTRL_CPU_FLUSHREQ_EN (1 << 17) +# define CIA_CTRL_ARB_CPU_EN (1 << 18) +# define CIA_CTRL_EN_ARB_LINK (1 << 19) +# define CIA_CTRL_RD_TYPE_SHIFT 20 +# define CIA_CTRL_RL_TYPE_SHIFT 24 +# define CIA_CTRL_RM_TYPE_SHIFT 28 +# define CIA_CTRL_EN_DMA_RD_PERF (1 << 31) +#define CIA_IOC_CIA_CNFG (IDENT_ADDR + 0x8740000140UL) +# define CIA_CNFG_IOA_BWEN (1 << 0) +# define CIA_CNFG_PCI_MWEN (1 << 4) +# define CIA_CNFG_PCI_DWEN (1 << 5) +# define CIA_CNFG_PCI_WLEN (1 << 8) +#define CIA_IOC_FLASH_CTRL (IDENT_ADDR + 0x8740000200UL) +#define CIA_IOC_HAE_MEM (IDENT_ADDR + 0x8740000400UL) +#define CIA_IOC_HAE_IO (IDENT_ADDR + 0x8740000440UL) +#define CIA_IOC_CFG (IDENT_ADDR + 0x8740000480UL) +#define CIA_IOC_CACK_EN (IDENT_ADDR + 0x8740000600UL) +# define CIA_CACK_EN_LOCK_EN (1 << 0) +# define CIA_CACK_EN_MB_EN (1 << 1) +# define CIA_CACK_EN_SET_DIRTY_EN (1 << 2) +# define CIA_CACK_EN_BC_VICTIM_EN (1 << 3) + + +/* + * 21171-CA Diagnostic Registers */ -#define CIA_IOC_CIA_REV (IDENT_ADDR + 0x8740000080UL) -#define CIA_IOC_PCI_LAT (IDENT_ADDR + 0x87400000C0UL) -#define CIA_IOC_CIA_CTRL (IDENT_ADDR + 0x8740000100UL) -#define CIA_IOC_CIA_CNFG (IDENT_ADDR + 0x8740000140UL) -#define CIA_IOC_HAE_MEM (IDENT_ADDR + 0x8740000400UL) -#define CIA_IOC_HAE_IO (IDENT_ADDR + 0x8740000440UL) -#define CIA_IOC_CFG (IDENT_ADDR + 0x8740000480UL) -#define CIA_IOC_CACK_EN (IDENT_ADDR + 0x8740000600UL) +#define CIA_IOC_CIA_DIAG (IDENT_ADDR + 0x8740002000UL) +#define CIA_IOC_DIAG_CHECK (IDENT_ADDR + 0x8740003000UL) /* - * 21171-CA Diagnostic Registers (p4-2) + * 21171-CA Performance Monitor registers */ -#define CIA_IOC_CIA_DIAG (IDENT_ADDR + 0x8740002000UL) -#define CIA_IOC_DIAG_CHECK (IDENT_ADDR + 0x8740003000UL) +#define CIA_IOC_PERF_MONITOR (IDENT_ADDR + 0x8740004000UL) +#define CIA_IOC_PERF_CONTROL (IDENT_ADDR + 0x8740004040UL) /* - * 21171-CA Performance Monitor registers (p4-3) + * 21171-CA Error registers */ -#define CIA_IOC_PERF_MONITOR (IDENT_ADDR + 0x8740004000UL) -#define CIA_IOC_PERF_CONTROL (IDENT_ADDR + 0x8740004040UL) +#define CIA_IOC_CPU_ERR0 (IDENT_ADDR + 0x8740008000UL) +#define CIA_IOC_CPU_ERR1 (IDENT_ADDR + 0x8740008040UL) +#define CIA_IOC_CIA_ERR (IDENT_ADDR + 0x8740008200UL) +# define CIA_ERR_COR_ERR (1 << 0) +# define CIA_ERR_UN_COR_ERR (1 << 1) +# define CIA_ERR_CPU_PE (1 << 2) +# define CIA_ERR_MEM_NEM (1 << 3) +# define CIA_ERR_PCI_SERR (1 << 4) +# define CIA_ERR_PERR (1 << 5) +# define CIA_ERR_PCI_ADDR_PE (1 << 6) +# define CIA_ERR_RCVD_MAS_ABT (1 << 7) +# define CIA_ERR_RCVD_TAR_ABT (1 << 8) +# define CIA_ERR_PA_PTE_INV (1 << 9) +# define CIA_ERR_FROM_WRT_ERR (1 << 10) +# define CIA_ERR_IOA_TIMEOUT (1 << 11) +# define CIA_ERR_LOST_CORR_ERR (1 << 16) +# define CIA_ERR_LOST_UN_CORR_ERR (1 << 17) +# define CIA_ERR_LOST_CPU_PE (1 << 18) +# define CIA_ERR_LOST_MEM_NEM (1 << 19) +# define CIA_ERR_LOST_PERR (1 << 21) +# define CIA_ERR_LOST_PCI_ADDR_PE (1 << 22) +# define CIA_ERR_LOST_RCVD_MAS_ABT (1 << 23) +# define CIA_ERR_LOST_RCVD_TAR_ABT (1 << 24) +# define CIA_ERR_LOST_PA_PTE_INV (1 << 25) +# define CIA_ERR_LOST_FROM_WRT_ERR (1 << 26) +# define CIA_ERR_LOST_IOA_TIMEOUT (1 << 27) +# define CIA_ERR_VALID (1 << 31) +#define CIA_IOC_CIA_STAT (IDENT_ADDR + 0x8740008240UL) +#define CIA_IOC_ERR_MASK (IDENT_ADDR + 0x8740008280UL) +#define CIA_IOC_CIA_SYN (IDENT_ADDR + 0x8740008300UL) +#define CIA_IOC_MEM_ERR0 (IDENT_ADDR + 0x8740008400UL) +#define CIA_IOC_MEM_ERR1 (IDENT_ADDR + 0x8740008440UL) +#define CIA_IOC_PCI_ERR0 (IDENT_ADDR + 0x8740008800UL) +#define CIA_IOC_PCI_ERR1 (IDENT_ADDR + 0x8740008840UL) +#define CIA_IOC_PCI_ERR3 (IDENT_ADDR + 0x8740008880UL) /* - * 21171-CA Error registers (p4-3) + * 21171-CA System configuration registers */ -#define CIA_IOC_CPU_ERR0 (IDENT_ADDR + 0x8740008000UL) -#define CIA_IOC_CPU_ERR1 (IDENT_ADDR + 0x8740008040UL) -#define CIA_IOC_CIA_ERR (IDENT_ADDR + 0x8740008200UL) -#define CIA_IOC_CIA_STAT (IDENT_ADDR + 0x8740008240UL) -#define CIA_IOC_ERR_MASK (IDENT_ADDR + 0x8740008280UL) -#define CIA_IOC_CIA_SYN (IDENT_ADDR + 0x8740008300UL) -#define CIA_IOC_MEM_ERR0 (IDENT_ADDR + 0x8740008400UL) -#define CIA_IOC_MEM_ERR1 (IDENT_ADDR + 0x8740008440UL) -#define CIA_IOC_PCI_ERR0 (IDENT_ADDR + 0x8740008800UL) -#define CIA_IOC_PCI_ERR1 (IDENT_ADDR + 0x8740008840UL) -#define CIA_IOC_PCI_ERR3 (IDENT_ADDR + 0x8740008880UL) +#define CIA_IOC_MCR (IDENT_ADDR + 0x8750000000UL) +#define CIA_IOC_MBA0 (IDENT_ADDR + 0x8750000600UL) +#define CIA_IOC_MBA2 (IDENT_ADDR + 0x8750000680UL) +#define CIA_IOC_MBA4 (IDENT_ADDR + 0x8750000700UL) +#define CIA_IOC_MBA6 (IDENT_ADDR + 0x8750000780UL) +#define CIA_IOC_MBA8 (IDENT_ADDR + 0x8750000800UL) +#define CIA_IOC_MBAA (IDENT_ADDR + 0x8750000880UL) +#define CIA_IOC_MBAC (IDENT_ADDR + 0x8750000900UL) +#define CIA_IOC_MBAE (IDENT_ADDR + 0x8750000980UL) +#define CIA_IOC_TMG0 (IDENT_ADDR + 0x8750000B00UL) +#define CIA_IOC_TMG1 (IDENT_ADDR + 0x8750000B40UL) +#define CIA_IOC_TMG2 (IDENT_ADDR + 0x8750000B80UL) /* - * 2117A-CA PCI Address Translation Registers. + * 2117A-CA PCI Address and Scatter-Gather Registers. */ -#define CIA_IOC_PCI_TBIA (IDENT_ADDR + 0x8760000100UL) +#define CIA_IOC_PCI_TBIA (IDENT_ADDR + 0x8760000100UL) + +#define CIA_IOC_PCI_W0_BASE (IDENT_ADDR + 0x8760000400UL) +#define CIA_IOC_PCI_W0_MASK (IDENT_ADDR + 0x8760000440UL) +#define CIA_IOC_PCI_T0_BASE (IDENT_ADDR + 0x8760000480UL) -#define CIA_IOC_PCI_W0_BASE (IDENT_ADDR + 0x8760000400UL) -#define CIA_IOC_PCI_W0_MASK (IDENT_ADDR + 0x8760000440UL) -#define CIA_IOC_PCI_T0_BASE (IDENT_ADDR + 0x8760000480UL) +#define CIA_IOC_PCI_W1_BASE (IDENT_ADDR + 0x8760000500UL) +#define CIA_IOC_PCI_W1_MASK (IDENT_ADDR + 0x8760000540UL) +#define CIA_IOC_PCI_T1_BASE (IDENT_ADDR + 0x8760000580UL) -#define CIA_IOC_PCI_W1_BASE (IDENT_ADDR + 0x8760000500UL) -#define CIA_IOC_PCI_W1_MASK (IDENT_ADDR + 0x8760000540UL) -#define CIA_IOC_PCI_T1_BASE (IDENT_ADDR + 0x8760000580UL) +#define CIA_IOC_PCI_W2_BASE (IDENT_ADDR + 0x8760000600UL) +#define CIA_IOC_PCI_W2_MASK (IDENT_ADDR + 0x8760000640UL) +#define CIA_IOC_PCI_T2_BASE (IDENT_ADDR + 0x8760000680UL) -#define CIA_IOC_PCI_W2_BASE (IDENT_ADDR + 0x8760000600UL) -#define CIA_IOC_PCI_W2_MASK (IDENT_ADDR + 0x8760000640UL) -#define CIA_IOC_PCI_T2_BASE (IDENT_ADDR + 0x8760000680UL) +#define CIA_IOC_PCI_W3_BASE (IDENT_ADDR + 0x8760000700UL) +#define CIA_IOC_PCI_W3_MASK (IDENT_ADDR + 0x8760000740UL) +#define CIA_IOC_PCI_T3_BASE (IDENT_ADDR + 0x8760000780UL) -#define CIA_IOC_PCI_W3_BASE (IDENT_ADDR + 0x8760000700UL) -#define CIA_IOC_PCI_W3_MASK (IDENT_ADDR + 0x8760000740UL) -#define CIA_IOC_PCI_T3_BASE (IDENT_ADDR + 0x8760000780UL) +#define CIA_IOC_PCI_W_DAC (IDENT_ADDR + 0x87600007C0UL) /* - * 21171-CA System configuration registers (p4-3) + * 2117A-CA Address Translation Registers. */ -#define CIA_IOC_MCR (IDENT_ADDR + 0x8750000000UL) -#define CIA_IOC_MBA0 (IDENT_ADDR + 0x8750000600UL) -#define CIA_IOC_MBA2 (IDENT_ADDR + 0x8750000680UL) -#define CIA_IOC_MBA4 (IDENT_ADDR + 0x8750000700UL) -#define CIA_IOC_MBA6 (IDENT_ADDR + 0x8750000780UL) -#define CIA_IOC_MBA8 (IDENT_ADDR + 0x8750000800UL) -#define CIA_IOC_MBAA (IDENT_ADDR + 0x8750000880UL) -#define CIA_IOC_MBAC (IDENT_ADDR + 0x8750000900UL) -#define CIA_IOC_MBAE (IDENT_ADDR + 0x8750000980UL) -#define CIA_IOC_TMG0 (IDENT_ADDR + 0x8750000B00UL) -#define CIA_IOC_TMG1 (IDENT_ADDR + 0x8750000B40UL) -#define CIA_IOC_TMG2 (IDENT_ADDR + 0x8750000B80UL) + +/* 8 tag registers, the first 4 of which are lockable. */ +#define CIA_IOC_TB_TAGn(n) \ + (IDENT_ADDR + 0x8760000800UL + (n)*0x40) + +/* 4 page registers per tag register. */ +#define CIA_IOC_TBn_PAGEm(n,m) \ + (IDENT_ADDR + 0x8760001000UL + (n)*0x100 + (m)*0x40) /* * Memory spaces: */ -#define CIA_IACK_SC (IDENT_ADDR + 0x8720000000UL) -#define CIA_CONF (IDENT_ADDR + 0x8700000000UL) +#define CIA_IACK_SC (IDENT_ADDR + 0x8720000000UL) +#define CIA_CONF (IDENT_ADDR + 0x8700000000UL) #define CIA_IO (IDENT_ADDR + 0x8580000000UL) #define CIA_SPARSE_MEM (IDENT_ADDR + 0x8000000000UL) #define CIA_SPARSE_MEM_R2 (IDENT_ADDR + 0x8400000000UL) #define CIA_SPARSE_MEM_R3 (IDENT_ADDR + 0x8500000000UL) #define CIA_DENSE_MEM (IDENT_ADDR + 0x8600000000UL) +#define CIA_BW_MEM (IDENT_ADDR + 0x8800000000UL) +#define CIA_BW_IO (IDENT_ADDR + 0x8900000000UL) +#define CIA_BW_CFG_0 (IDENT_ADDR + 0x8a00000000UL) +#define CIA_BW_CFG_1 (IDENT_ADDR + 0x8b00000000UL) /* * ALCOR's GRU ASIC registers @@ -182,23 +248,19 @@ #define XLT_GRU_INT_REQ_BITS 0x80003fffUL #define GRU_INT_REQ_BITS (alpha_mv.sys.cia.gru_int_req_bits+0) - /* - * Bit definitions for I/O Controller status register 0: + * PYXIS interrupt control registers */ -#define CIA_IOC_STAT0_CMD 0xf -#define CIA_IOC_STAT0_ERR (1<<4) -#define CIA_IOC_STAT0_LOST (1<<5) -#define CIA_IOC_STAT0_THIT (1<<6) -#define CIA_IOC_STAT0_TREF (1<<7) -#define CIA_IOC_STAT0_CODE_SHIFT 8 -#define CIA_IOC_STAT0_CODE_MASK 0x7 -#define CIA_IOC_STAT0_P_NBR_SHIFT 13 -#define CIA_IOC_STAT0_P_NBR_MASK 0x7ffff - -#if !CIA_ONE_HAE_WINDOW -#define CIA_HAE_ADDRESS CIA_IOC_HAE_MEM -#endif +#define PYXIS_INT_REQ (IDENT_ADDR + 0x87A0000000UL) +#define PYXIS_INT_MASK (IDENT_ADDR + 0x87A0000040UL) +#define PYXIS_INT_HILO (IDENT_ADDR + 0x87A00000C0UL) +#define PYXIS_INT_ROUTE (IDENT_ADDR + 0x87A0000140UL) +#define PYXIS_GPO (IDENT_ADDR + 0x87A0000180UL) +#define PYXIS_INT_CNFG (IDENT_ADDR + 0x87A00001C0UL) +#define PYXIS_RT_COUNT (IDENT_ADDR + 0x87A0000200UL) +#define PYXIS_INT_TIME (IDENT_ADDR + 0x87A0000240UL) +#define PYXIS_IIC_CTRL (IDENT_ADDR + 0x87A00002C0UL) +#define PYXIS_RESET (IDENT_ADDR + 0x8780000900UL) /* * Data structure for handling CIA machine checks. @@ -206,52 +268,6 @@ /* System-specific info. */ struct el_CIA_sysdata_mcheck { -#if 0 - /* ??? Where did this come from. It appears to bear no - relation to the cia logout written in the milo sources. - Who knows what happens in the srm console... */ - unsigned long coma_gcr; - unsigned long coma_edsr; - unsigned long coma_ter; - unsigned long coma_elar; - unsigned long coma_ehar; - unsigned long coma_ldlr; - unsigned long coma_ldhr; - unsigned long coma_base0; - unsigned long coma_base1; - unsigned long coma_base2; - unsigned long coma_cnfg0; - unsigned long coma_cnfg1; - unsigned long coma_cnfg2; - unsigned long epic_dcsr; - unsigned long epic_pear; - unsigned long epic_sear; - unsigned long epic_tbr1; - unsigned long epic_tbr2; - unsigned long epic_pbr1; - unsigned long epic_pbr2; - unsigned long epic_pmr1; - unsigned long epic_pmr2; - unsigned long epic_harx1; - unsigned long epic_harx2; - unsigned long epic_pmlt; - unsigned long epic_tag0; - unsigned long epic_tag1; - unsigned long epic_tag2; - unsigned long epic_tag3; - unsigned long epic_tag4; - unsigned long epic_tag5; - unsigned long epic_tag6; - unsigned long epic_tag7; - unsigned long epic_data0; - unsigned long epic_data1; - unsigned long epic_data2; - unsigned long epic_data3; - unsigned long epic_data4; - unsigned long epic_data5; - unsigned long epic_data6; - unsigned long epic_data7; -#else unsigned long cpu_err0; unsigned long cpu_err1; unsigned long cia_err; @@ -263,7 +279,6 @@ struct el_CIA_sysdata_mcheck { unsigned long pci_err0; unsigned long pci_err1; unsigned long pci_err2; -#endif }; @@ -282,6 +297,8 @@ struct el_CIA_sysdata_mcheck { * get at PCI memory and I/O. */ +#define vucp volatile unsigned char * +#define vusp volatile unsigned short * #define vip volatile int * #define vuip volatile unsigned int * #define vulp volatile unsigned long * @@ -325,6 +342,44 @@ __EXTERN_INLINE void cia_outl(unsigned int b, unsigned long addr) mb(); } +__EXTERN_INLINE unsigned int cia_bwx_inb(unsigned long addr) +{ + /* ??? I wish I could get rid of this. But there's no ioremap + equivalent for I/O space. PCI I/O can be forced into the + CIA BWX I/O region, but that doesn't take care of legacy + ISA crap. */ + + return __kernel_ldbu(*(vucp)(addr+CIA_BW_IO)); +} + +__EXTERN_INLINE void cia_bwx_outb(unsigned char b, unsigned long addr) +{ + __kernel_stb(b, *(vucp)(addr+CIA_BW_IO)); + mb(); +} + +__EXTERN_INLINE unsigned int cia_bwx_inw(unsigned long addr) +{ + return __kernel_ldwu(*(vusp)(addr+CIA_BW_IO)); +} + +__EXTERN_INLINE void cia_bwx_outw(unsigned short b, unsigned long addr) +{ + __kernel_stw(b, *(vusp)(addr+CIA_BW_IO)); + mb(); +} + +__EXTERN_INLINE unsigned int cia_bwx_inl(unsigned long addr) +{ + return *(vuip)(addr+CIA_BW_IO); +} + +__EXTERN_INLINE void cia_bwx_outl(unsigned int b, unsigned long addr) +{ + *(vuip)(addr+CIA_BW_IO) = b; + mb(); +} + /* * Memory functions. 64-bit and 32-bit accesses are done through @@ -362,15 +417,7 @@ __EXTERN_INLINE unsigned long cia_readb(unsigned long addr) { unsigned long result; -#if !CIA_ONE_HAE_WINDOW - unsigned long msb; - /* Note that CIA_DENSE_MEM has no bits not masked in these - operations, so we don't have to subtract it back out. */ - msb = addr & 0xE0000000; - set_hae(msb); -#endif addr &= CIA_MEM_R1_MASK; - result = *(vip) ((addr << 5) + CIA_SPARSE_MEM + 0x00); return __kernel_extbl(result, addr & 3); } @@ -379,15 +426,7 @@ __EXTERN_INLINE unsigned long cia_readw(unsigned long addr) { unsigned long result; -#if !CIA_ONE_HAE_WINDOW - unsigned long msb; - /* Note that CIA_DENSE_MEM has no bits not masked in these - operations, so we don't have to subtract it back out. */ - msb = addr & 0xE0000000; - set_hae(msb); -#endif addr &= CIA_MEM_R1_MASK; - result = *(vip) ((addr << 5) + CIA_SPARSE_MEM + 0x08); return __kernel_extwl(result, addr & 3); } @@ -396,15 +435,7 @@ __EXTERN_INLINE void cia_writeb(unsigned char b, unsigned long addr) { unsigned long w; -#if !CIA_ONE_HAE_WINDOW - unsigned long msb; - /* Note that CIA_DENSE_MEM has no bits not masked in these - operations, so we don't have to subtract it back out. */ - msb = addr & 0xE0000000; - set_hae(msb); -#endif addr &= CIA_MEM_R1_MASK; - w = __kernel_insbl(b, addr & 3); *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x00) = w; } @@ -413,15 +444,7 @@ __EXTERN_INLINE void cia_writew(unsigned short b, unsigned long addr) { unsigned long w; -#if !CIA_ONE_HAE_WINDOW - unsigned long msb; - /* Note that CIA_DENSE_MEM has no bits not masked in these - operations, so we don't have to subtract it back out. */ - msb = addr & 0xE0000000; - set_hae(msb); -#endif addr &= CIA_MEM_R1_MASK; - w = __kernel_inswl(b, addr & 3); *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x08) = w; } @@ -451,44 +474,121 @@ __EXTERN_INLINE unsigned long cia_ioremap(unsigned long addr) return addr + CIA_DENSE_MEM; } +__EXTERN_INLINE unsigned long cia_bwx_readb(unsigned long addr) +{ + return __kernel_ldbu(*(vucp)addr); +} + +__EXTERN_INLINE unsigned long cia_bwx_readw(unsigned long addr) +{ + return __kernel_ldwu(*(vusp)addr); +} + +__EXTERN_INLINE unsigned long cia_bwx_readl(unsigned long addr) +{ + return *(vuip)addr; +} + +__EXTERN_INLINE unsigned long cia_bwx_readq(unsigned long addr) +{ + return *(vulp)addr; +} + +__EXTERN_INLINE void cia_bwx_writeb(unsigned char b, unsigned long addr) +{ + __kernel_stb(b, *(vucp)addr); +} + +__EXTERN_INLINE void cia_bwx_writew(unsigned short b, unsigned long addr) +{ + __kernel_stw(b, *(vusp)addr); +} + +__EXTERN_INLINE void cia_bwx_writel(unsigned int b, unsigned long addr) +{ + *(vuip)addr = b; +} + +__EXTERN_INLINE void cia_bwx_writeq(unsigned long b, unsigned long addr) +{ + *(vulp)addr = b; +} + +__EXTERN_INLINE unsigned long cia_bwx_ioremap(unsigned long addr) +{ + return addr + CIA_BW_MEM; +} + __EXTERN_INLINE int cia_is_ioaddr(unsigned long addr) { return addr >= IDENT_ADDR + 0x8000000000UL; } +#undef vucp +#undef vusp #undef vip #undef vuip #undef vulp #ifdef __WANT_IO_DEF -#define __inb cia_inb -#define __inw cia_inw -#define __inl cia_inl -#define __outb cia_outb -#define __outw cia_outw -#define __outl cia_outl - -#define __readb cia_readb -#define __readw cia_readw -#define __writeb cia_writeb -#define __writew cia_writew -#define __readl cia_readl -#define __readq cia_readq -#define __writel cia_writel -#define __writeq cia_writeq -#define __ioremap cia_ioremap -#define __is_ioaddr cia_is_ioaddr - -#define inb(port) \ - (__builtin_constant_p((port))?__inb(port):_inb(port)) -#define outb(x, port) \ - (__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) +#ifdef CONFIG_ALPHA_PYXIS +# define __inb cia_bwx_inb +# define __inw cia_bwx_inw +# define __inl cia_bwx_inl +# define __outb cia_bwx_outb +# define __outw cia_bwx_outw +# define __outl cia_bwx_outl +# define __readb cia_bwx_readb +# define __readw cia_bwx_readw +# define __writeb cia_bwx_writeb +# define __writew cia_bwx_writew +# define __readl cia_bwx_readl +# define __readq cia_bwx_readq +# define __writel cia_bwx_writel +# define __writeq cia_bwx_writeq +# define __ioremap cia_bwx_ioremap +# define inb(port) __inb((port)) +# define inw(port) __inw((port)) +# define inl(port) __inl((port)) +# define outb(x, port) __outb((x),(port)) +# define outw(x, port) __outw((x),(port)) +# define outl(x, port) __outl((x),(port)) +# define __raw_readb(addr) __readb((addr)) +# define __raw_readw(addr) __readw((addr)) +# define __raw_writeb(b, addr) __writeb((b),(addr)) +# define __raw_writew(b, addr) __writew((b),(addr)) +# define __raw_readl(a) __readl((unsigned long)(a)) +# define __raw_readq(a) __readq((unsigned long)(a)) +# define __raw_writel(v,a) __writel((v),(unsigned long)(a)) +# define __raw_writeq(v,a) __writeq((v),(unsigned long)(a)) +#else +# define __inb cia_inb +# define __inw cia_inw +# define __inl cia_inl +# define __outb cia_outb +# define __outw cia_outw +# define __outl cia_outl +# define __readb cia_readb +# define __readw cia_readw +# define __writeb cia_writeb +# define __writew cia_writew +# define __readl cia_readl +# define __readq cia_readq +# define __writel cia_writel +# define __writeq cia_writeq +# define __ioremap cia_ioremap +# define inb(port) \ + (__builtin_constant_p((port))?__inb(port):_inb(port)) +# define outb(x, port) \ + (__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) +# define __raw_readl(a) __readl((unsigned long)(a)) +# define __raw_readq(a) __readq((unsigned long)(a)) +# define __raw_writel(v,a) __writel((v),(unsigned long)(a)) +# define __raw_writeq(v,a) __writeq((v),(unsigned long)(a)) +#endif /* PYXIS */ -#define __raw_readl(a) __readl((unsigned long)(a)) -#define __raw_readq(a) __readq((unsigned long)(a)) -#define __raw_writel(v,a) __writel((v),(unsigned long)(a)) -#define __raw_writeq(v,a) __writeq((v),(unsigned long)(a)) +#define __is_ioaddr cia_is_ioaddr #endif /* __WANT_IO_DEF */ diff --git a/include/asm-alpha/core_pyxis.h b/include/asm-alpha/core_pyxis.h deleted file mode 100644 index 18b523ef4650..000000000000 --- a/include/asm-alpha/core_pyxis.h +++ /dev/null @@ -1,444 +0,0 @@ -#ifndef __ALPHA_PYXIS__H__ -#define __ALPHA_PYXIS__H__ - -#include -#include - -/* - * PYXIS is the internal name for a core logic chipset which provides - * memory controller and PCI access for the 21164A chip based systems. - * - * This file is based on: - * - * Pyxis Chipset Spec - * 14-Jun-96 - * Rev. X2.0 - * - */ - -/*------------------------------------------------------------------------** -** ** -** I/O procedures ** -** ** -** inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers ** -** inportbxt: 8 bits only ** -** inport: alias of inportw ** -** outport: alias of outportw ** -** ** -** inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers ** -** inmembxt: 8 bits only ** -** inmem: alias of inmemw ** -** outmem: alias of outmemw ** -** ** -**------------------------------------------------------------------------*/ - - -/* PYXIS ADDRESS BIT DEFINITIONS - * - * 3333 3333 3322 2222 2222 1111 1111 11 - * 9876 5432 1098 7654 3210 9876 5432 1098 7654 3210 - * ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- - * 1 000 - * ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- - * | |\| - * | Byte Enable --+ | - * | Transfer Length --+ - * +-- IO space, not cached - * - * Byte Transfer - * Enable Length Transfer Byte Address - * adr<6:5> adr<4:3> Length Enable Adder - * --------------------------------------------- - * 00 00 Byte 1110 0x000 - * 01 00 Byte 1101 0x020 - * 10 00 Byte 1011 0x040 - * 11 00 Byte 0111 0x060 - * - * 00 01 Word 1100 0x008 - * 01 01 Word 1001 0x028 <= Not supported in this code. - * 10 01 Word 0011 0x048 - * - * 00 10 Tribyte 1000 0x010 - * 01 10 Tribyte 0001 0x030 - * - * 10 11 Longword 0000 0x058 - * - * Note that byte enables are asserted low. - * - */ - -#define PYXIS_MEM_R1_MASK 0x1fffffff /* SPARSE Mem region 1 mask is 29 bits */ -#define PYXIS_MEM_R2_MASK 0x07ffffff /* SPARSE Mem region 2 mask is 27 bits */ -#define PYXIS_MEM_R3_MASK 0x03ffffff /* SPARSE Mem region 3 mask is 26 bits */ - -/* - * General Registers - */ -#define PYXIS_REV (IDENT_ADDR + 0x8740000080UL) -#define PYXIS_PCI_LAT (IDENT_ADDR + 0x87400000C0UL) -#define PYXIS_CTRL (IDENT_ADDR + 0x8740000100UL) -#define PYXIS_CTRL1 (IDENT_ADDR + 0x8740000140UL) -#define PYXIS_FLASH_CTRL (IDENT_ADDR + 0x8740000200UL) - -#define PYXIS_HAE_MEM (IDENT_ADDR + 0x8740000400UL) -#define PYXIS_HAE_IO (IDENT_ADDR + 0x8740000440UL) -#define PYXIS_CFG (IDENT_ADDR + 0x8740000480UL) - -/* - * Diagnostic Registers - */ -#define PYXIS_DIAG (IDENT_ADDR + 0x8740002000UL) -#define PYXIS_DIAG_CHECK (IDENT_ADDR + 0x8740003000UL) - -/* - * Performance Monitor registers - */ -#define PYXIS_PERF_MONITOR (IDENT_ADDR + 0x8740004000UL) -#define PYXIS_PERF_CONTROL (IDENT_ADDR + 0x8740004040UL) - -/* - * Error registers - */ -#define PYXIS_ERR (IDENT_ADDR + 0x8740008200UL) -#define PYXIS_STAT (IDENT_ADDR + 0x8740008240UL) -#define PYXIS_ERR_MASK (IDENT_ADDR + 0x8740008280UL) -#define PYXIS_SYN (IDENT_ADDR + 0x8740008300UL) -#define PYXIS_ERR_DATA (IDENT_ADDR + 0x8740008308UL) - -#define PYXIS_MEAR (IDENT_ADDR + 0x8740008400UL) -#define PYXIS_MESR (IDENT_ADDR + 0x8740008440UL) -#define PYXIS_PCI_ERR0 (IDENT_ADDR + 0x8740008800UL) -#define PYXIS_PCI_ERR1 (IDENT_ADDR + 0x8740008840UL) -#define PYXIS_PCI_ERR2 (IDENT_ADDR + 0x8740008880UL) - -/* - * PCI Address Translation Registers. - */ -#define PYXIS_TBIA (IDENT_ADDR + 0x8760000100UL) - -#define PYXIS_W0_BASE (IDENT_ADDR + 0x8760000400UL) -#define PYXIS_W0_MASK (IDENT_ADDR + 0x8760000440UL) -#define PYXIS_T0_BASE (IDENT_ADDR + 0x8760000480UL) - -#define PYXIS_W1_BASE (IDENT_ADDR + 0x8760000500UL) -#define PYXIS_W1_MASK (IDENT_ADDR + 0x8760000540UL) -#define PYXIS_T1_BASE (IDENT_ADDR + 0x8760000580UL) - -#define PYXIS_W2_BASE (IDENT_ADDR + 0x8760000600UL) -#define PYXIS_W2_MASK (IDENT_ADDR + 0x8760000640UL) -#define PYXIS_T2_BASE (IDENT_ADDR + 0x8760000680UL) - -#define PYXIS_W3_BASE (IDENT_ADDR + 0x8760000700UL) -#define PYXIS_W3_MASK (IDENT_ADDR + 0x8760000740UL) -#define PYXIS_T3_BASE (IDENT_ADDR + 0x8760000780UL) - -/* - * Memory Control registers - */ -#define PYXIS_MCR (IDENT_ADDR + 0x8750000000UL) - -/* - * Memory spaces: - */ -#define PYXIS_IACK_SC (IDENT_ADDR + 0x8720000000UL) -#define PYXIS_CONF (IDENT_ADDR + 0x8700000000UL) -#define PYXIS_IO (IDENT_ADDR + 0x8580000000UL) -#define PYXIS_SPARSE_MEM (IDENT_ADDR + 0x8000000000UL) -#define PYXIS_SPARSE_MEM_R2 (IDENT_ADDR + 0x8400000000UL) -#define PYXIS_SPARSE_MEM_R3 (IDENT_ADDR + 0x8500000000UL) -#define PYXIS_DENSE_MEM (IDENT_ADDR + 0x8600000000UL) - -/* - * Byte/Word PCI Memory Spaces: - */ -#define PYXIS_BW_MEM (IDENT_ADDR + 0x8800000000UL) -#define PYXIS_BW_IO (IDENT_ADDR + 0x8900000000UL) -#define PYXIS_BW_CFG_0 (IDENT_ADDR + 0x8a00000000UL) -#define PYXIS_BW_CFG_1 (IDENT_ADDR + 0x8b00000000UL) - -/* - * Interrupt Control registers - */ -#define PYXIS_INT_REQ (IDENT_ADDR + 0x87A0000000UL) -#define PYXIS_INT_MASK (IDENT_ADDR + 0x87A0000040UL) -#define PYXIS_INT_HILO (IDENT_ADDR + 0x87A00000C0UL) -#define PYXIS_INT_ROUTE (IDENT_ADDR + 0x87A0000140UL) -#define PYXIS_GPO (IDENT_ADDR + 0x87A0000180UL) -#define PYXIS_INT_CNFG (IDENT_ADDR + 0x87A00001C0UL) -#define PYXIS_RT_COUNT (IDENT_ADDR + 0x87A0000200UL) -#define PYXIS_INT_TIME (IDENT_ADDR + 0x87A0000240UL) -#define PYXIS_IIC_CTRL (IDENT_ADDR + 0x87A00002C0UL) -#define PYXIS_RESET (IDENT_ADDR + 0x8780000900UL) - -/* - * Bit definitions for I/O Controller status register 0: - */ -#define PYXIS_STAT0_CMD 0xf -#define PYXIS_STAT0_ERR (1<<4) -#define PYXIS_STAT0_LOST (1<<5) -#define PYXIS_STAT0_THIT (1<<6) -#define PYXIS_STAT0_TREF (1<<7) -#define PYXIS_STAT0_CODE_SHIFT 8 -#define PYXIS_STAT0_CODE_MASK 0x7 -#define PYXIS_STAT0_P_NBR_SHIFT 13 -#define PYXIS_STAT0_P_NBR_MASK 0x7ffff - -#define PYXIS_HAE_ADDRESS PYXIS_HAE_MEM - -/* - * Data structure for handling PYXIS machine checks: - */ -struct el_PYXIS_sysdata_mcheck { -#if 0 - /* ??? Where did this come from. It appears to bear no - relation to the pyxis logout written in the milo sources. - Who knows what happens in the srm console... */ - u_long coma_gcr; - u_long coma_edsr; - u_long coma_ter; - u_long coma_elar; - u_long coma_ehar; - u_long coma_ldlr; - u_long coma_ldhr; - u_long coma_base0; - u_long coma_base1; - u_long coma_base2; - u_long coma_cnfg0; - u_long coma_cnfg1; - u_long coma_cnfg2; - u_long epic_dcsr; - u_long epic_pear; - u_long epic_sear; - u_long epic_tbr1; - u_long epic_tbr2; - u_long epic_pbr1; - u_long epic_pbr2; - u_long epic_pmr1; - u_long epic_pmr2; - u_long epic_harx1; - u_long epic_harx2; - u_long epic_pmlt; - u_long epic_tag0; - u_long epic_tag1; - u_long epic_tag2; - u_long epic_tag3; - u_long epic_tag4; - u_long epic_tag5; - u_long epic_tag6; - u_long epic_tag7; - u_long epic_data0; - u_long epic_data1; - u_long epic_data2; - u_long epic_data3; - u_long epic_data4; - u_long epic_data5; - u_long epic_data6; - u_long epic_data7; -#else - unsigned long cpu_err0; - unsigned long cpu_err1; - unsigned long cia_err; - unsigned long cia_stat; - unsigned long err_mask; - unsigned long cia_syn; - unsigned long mem_err0; - unsigned long mem_err1; - unsigned long pci_err0; - unsigned long pci_err1; - unsigned long pci_err2; -#endif -}; - - -#ifdef __KERNEL__ - -#ifndef __EXTERN_INLINE -#define __EXTERN_INLINE extern inline -#define __IO_EXTERN_INLINE -#endif - -/* - * I/O functions: - * - * PYXIS, the 21174 PCI/memory support chipset for the EV56 (21164A) - * and PCA56 (21164PC) processors, can use either a sparse address - * mapping scheme, or the so-called byte-word PCI address space, to - * get at PCI memory and I/O. - */ - -#define vucp volatile unsigned char * -#define vusp volatile unsigned short * -#define vip volatile int * -#define vuip volatile unsigned int * -#define vulp volatile unsigned long * - -__EXTERN_INLINE unsigned int pyxis_inb(unsigned long addr) -{ - /* ??? I wish I could get rid of this. But there's no ioremap - equivalent for I/O space. PCI I/O can be forced into the - PYXIS I/O region, but that doesn't take care of legacy ISA crap. */ - - return __kernel_ldbu(*(vucp)(addr+PYXIS_BW_IO)); -} - -__EXTERN_INLINE void pyxis_outb(unsigned char b, unsigned long addr) -{ - __kernel_stb(b, *(vucp)(addr+PYXIS_BW_IO)); - mb(); -} - -__EXTERN_INLINE unsigned int pyxis_inw(unsigned long addr) -{ - return __kernel_ldwu(*(vusp)(addr+PYXIS_BW_IO)); -} - -__EXTERN_INLINE void pyxis_outw(unsigned short b, unsigned long addr) -{ - __kernel_stw(b, *(vusp)(addr+PYXIS_BW_IO)); - mb(); -} - -__EXTERN_INLINE unsigned int pyxis_inl(unsigned long addr) -{ - return *(vuip)(addr+PYXIS_BW_IO); -} - -__EXTERN_INLINE void pyxis_outl(unsigned int b, unsigned long addr) -{ - *(vuip)(addr+PYXIS_BW_IO) = b; - mb(); -} - - -/* - * Memory functions. 64-bit and 32-bit accesses are done through - * dense memory space, everything else through sparse space. - * - * For reading and writing 8 and 16 bit quantities we need to - * go through one of the three sparse address mapping regions - * and use the HAE_MEM CSR to provide some bits of the address. - * The following few routines use only sparse address region 1 - * which gives 1Gbyte of accessible space which relates exactly - * to the amount of PCI memory mapping *into* system address space. - * See p 6-17 of the specification but it looks something like this: - * - * 21164 Address: - * - * 3 2 1 - * 9876543210987654321098765432109876543210 - * 1ZZZZ0.PCI.QW.Address............BBLL - * - * ZZ = SBZ - * BB = Byte offset - * LL = Transfer length - * - * PCI Address: - * - * 3 2 1 - * 10987654321098765432109876543210 - * HHH....PCI.QW.Address........ 00 - * - * HHH = 31:29 HAE_MEM CSR - * - */ - -__EXTERN_INLINE unsigned long pyxis_readb(unsigned long addr) -{ - return __kernel_ldbu(*(vucp)addr); -} - -__EXTERN_INLINE unsigned long pyxis_readw(unsigned long addr) -{ - return __kernel_ldwu(*(vusp)addr); -} - -__EXTERN_INLINE unsigned long pyxis_readl(unsigned long addr) -{ - return *(vuip)addr; -} - -__EXTERN_INLINE unsigned long pyxis_readq(unsigned long addr) -{ - return *(vulp)addr; -} - -__EXTERN_INLINE void pyxis_writeb(unsigned char b, unsigned long addr) -{ - __kernel_stb(b, *(vucp)addr); -} - -__EXTERN_INLINE void pyxis_writew(unsigned short b, unsigned long addr) -{ - __kernel_stw(b, *(vusp)addr); -} - -__EXTERN_INLINE void pyxis_writel(unsigned int b, unsigned long addr) -{ - *(vuip)addr = b; -} - -__EXTERN_INLINE void pyxis_writeq(unsigned long b, unsigned long addr) -{ - *(vulp)addr = b; -} - -__EXTERN_INLINE unsigned long pyxis_ioremap(unsigned long addr) -{ - return addr + PYXIS_BW_MEM; -} - -__EXTERN_INLINE int pyxis_is_ioaddr(unsigned long addr) -{ - return addr >= IDENT_ADDR + 0x8740000000UL; -} - -#undef vucp -#undef vusp -#undef vip -#undef vuip -#undef vulp - -#ifdef __WANT_IO_DEF - -#define __inb pyxis_inb -#define __inw pyxis_inw -#define __inl pyxis_inl -#define __outb pyxis_outb -#define __outw pyxis_outw -#define __outl pyxis_outl -#define __readb pyxis_readb -#define __readw pyxis_readw -#define __writeb pyxis_writeb -#define __writew pyxis_writew -#define __readl pyxis_readl -#define __readq pyxis_readq -#define __writel pyxis_writel -#define __writeq pyxis_writeq -#define __ioremap pyxis_ioremap -#define __is_ioaddr pyxis_is_ioaddr - -#define inb(port) __inb((port)) -#define inw(port) __inw((port)) -#define inl(port) __inl((port)) -#define outb(x, port) __outb((x),(port)) -#define outw(x, port) __outw((x),(port)) -#define outl(x, port) __outl((x),(port)) -#define __raw_readb(addr) __readb((addr)) -#define __raw_readw(addr) __readw((addr)) -#define __raw_writeb(b, addr) __writeb((b),(addr)) -#define __raw_writew(b, addr) __writew((b),(addr)) -#define __raw_readl(a) __readl((unsigned long)(a)) -#define __raw_readq(a) __readq((unsigned long)(a)) -#define __raw_writel(v,a) __writel((v),(unsigned long)(a)) -#define __raw_writeq(v,a) __writeq((v),(unsigned long)(a)) - -#endif /* __WANT_IO_DEF */ - -#ifdef __IO_EXTERN_INLINE -#undef __EXTERN_INLINE -#undef __IO_EXTERN_INLINE -#endif - -#endif /* __KERNEL__ */ - -#endif /* __ALPHA_PYXIS__H__ */ diff --git a/include/asm-alpha/delay.h b/include/asm-alpha/delay.h index 8db687bd4973..b6789cb359a3 100644 --- a/include/asm-alpha/delay.h +++ b/include/asm-alpha/delay.h @@ -4,74 +4,48 @@ #include /* - * Copyright (C) 1993 Linus Torvalds + * Copyright (C) 1993, 2000 Linus Torvalds * * Delay routines, using a pre-computed "loops_per_second" value. */ -/* We can make the delay loop inline, but we have to be very careful wrt - scheduling for ev6 machines, so that we keep a consistent number of - iterations for all invocations. */ - -extern __inline__ void -__delay(unsigned long loops) -{ - __asm__ __volatile__( - ".align 4\n" - "1: subq %0,1,%0\n" - " bge %0,1b\n" - " nop" - : "=r" (loops) : "0"(loops)); -} - /* - * division by multiplication: you don't have to worry about - * loss of precision. - * - * Use only for very small delays ( < 1 msec). Should probably use a - * lookup table, really, as the multiplications take much too long with - * short delays. This is a "reasonable" implementation, though (and the - * first constant multiplications gets optimized away if the delay is - * a constant). + * Use only for very small delays (< 1 msec). * - * Optimize small constants further by exposing the second multiplication - * to the compiler. In addition, mulq is 2 cycles faster than umulh. + * The active part of our cycle counter is only 32-bits wide, and + * we're treating the difference between two marks as signed. On + * a 1GHz box, that's about 2 seconds. */ extern __inline__ void -__udelay(unsigned long usecs, unsigned long lps) +__delay(int loops) { - /* compute (usecs * 2**64 / 10**6) * loops_per_sec / 2**64 */ - - usecs *= 0x000010c6f7a0b5edUL; /* 2**64 / 1000000 */ - __asm__("umulh %1,%2,%0" :"=r" (usecs) :"r" (usecs),"r" (lps)); - __delay(usecs); + int tmp; + __asm__ __volatile__( + " rpcc %0\n" + " addl %1,%0,%1\n" + "1: rpcc %0\n" + " subl %1,%0,%0\n" + " bgt %0,1b" + : "=&r" (tmp), "=r" (loops) : "1"(loops)); } extern __inline__ void -__small_const_udelay(unsigned long usecs, unsigned long lps) +udelay(unsigned long usecs) { - /* compute (usecs * 2**32 / 10**6) * loops_per_sec / 2**32 */ - - usecs *= 0x10c6; /* 2^32 / 10^6 */ - usecs *= lps; - usecs >>= 32; - __delay(usecs); -} + unsigned long lps; #ifdef __SMP__ -#define udelay(usecs) \ - (__builtin_constant_p(usecs) && usecs < 0x100000000UL \ - ? __small_const_udelay(usecs, \ - cpu_data[smp_processor_id()].loops_per_sec) \ - : __udelay(usecs, \ - cpu_data[smp_processor_id()].loops_per_sec)) + lps = cpu_data[smp_processor_id()].loops_per_sec; #else -#define udelay(usecs) \ - (__builtin_constant_p(usecs) && usecs < 0x100000000UL \ - ? __small_const_udelay(usecs, loops_per_sec) \ - : __udelay(usecs, loops_per_sec)) + lps = loops_per_sec; #endif + /* Compute (usecs * 2**32 / 10**6) * loops_per_sec / 2**32. */ + + usecs *= 0x10c6; /* 2^32 / 10^6 */ + usecs *= lps; + __delay((long)usecs >> 32); +} #endif /* defined(__ALPHA_DELAY_H) */ diff --git a/include/asm-alpha/io.h b/include/asm-alpha/io.h index 59eeb9545738..3d5a3451a8ed 100644 --- a/include/asm-alpha/io.h +++ b/include/asm-alpha/io.h @@ -166,8 +166,6 @@ extern void _sethae (unsigned long addr); /* cached version */ # include #elif defined(CONFIG_ALPHA_POLARIS) # include -#elif defined(CONFIG_ALPHA_PYXIS) -# include #elif defined(CONFIG_ALPHA_T2) # include #elif defined(CONFIG_ALPHA_TSUNAMI) diff --git a/include/asm-alpha/mman.h b/include/asm-alpha/mman.h index ddfe6bda47da..3e9b58d98a99 100644 --- a/include/asm-alpha/mman.h +++ b/include/asm-alpha/mman.h @@ -31,6 +31,13 @@ #define MCL_CURRENT 8192 /* lock all currently mapped pages */ #define MCL_FUTURE 16384 /* lock all additions to address space */ +#define MADV_NORMAL 0 /* no further special treatment */ +#define MADV_RANDOM 1 /* expect random page references */ +#define MADV_SEQUENTIAL 2 /* expect sequential page references */ +#define MADV_WILLNEED 3 /* will need these pages */ +#define MADV_SPACEAVAIL 5 /* ensure resources are available */ +#define MADV_DONTNEED 6 /* dont need these pages */ + /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS #define MAP_FILE 0 diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h index 1a68d43a335e..8f89479b5f3a 100644 --- a/include/asm-alpha/pci.h +++ b/include/asm-alpha/pci.h @@ -39,6 +39,11 @@ struct pci_controler { #define PCIBIOS_MIN_IO alpha_mv.min_io_address #define PCIBIOS_MIN_MEM alpha_mv.min_mem_address +extern inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} + /* IOMMU controls. */ /* Allocate and map kernel buffer using consistant mode DMA for PCI diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h index e80f0ae3b599..93ed9ed855d7 100644 --- a/include/asm-alpha/unistd.h +++ b/include/asm-alpha/unistd.h @@ -311,6 +311,8 @@ #define __NR_setresgid 371 #define __NR_getresgid 372 #define __NR_dipc 373 +#define __NR_pivot_root 374 +#define __NR_mincore 375 #if defined(__LIBRARY__) && defined(__GNUC__) diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h index 542487cf6288..c835f4c17deb 100644 --- a/include/asm-arm/pci.h +++ b/include/asm-arm/pci.h @@ -1,12 +1,17 @@ #ifndef ASMARM_PCI_H #define ASMARM_PCI_H +#ifdef __KERNEL__ + #define pcibios_assign_all_busses() 0 #define PCIBIOS_MIN_IO 0x8000 #define PCIBIOS_MIN_MEM 0x40000000 -#ifdef __KERNEL__ +extern inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} #include #include diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h index 1e55ec60fe47..d6d0311b7204 100644 --- a/include/asm-i386/pci.h +++ b/include/asm-i386/pci.h @@ -1,6 +1,8 @@ #ifndef __i386_PCI_H #define __i386_PCI_H +#ifdef __KERNEL__ + /* Can be used to override the logic in pci_scan_bus for skipping already-configured bus numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the loader */ @@ -10,7 +12,7 @@ #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 -#ifdef __KERNEL__ +void pcibios_set_master(struct pci_dev *dev); /* Dynamic DMA mapping stuff. * i386 has everything mapped statically. @@ -164,4 +166,3 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask) #endif /* __KERNEL__ */ #endif /* __i386_PCI_H */ - diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h index de50f98f0627..bbabe63e8038 100644 --- a/include/asm-ia64/pci.h +++ b/include/asm-ia64/pci.h @@ -11,6 +11,11 @@ #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 +extern inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} + /* * Dynamic DMA mapping API. * IA-64 has everything mapped statically. diff --git a/include/asm-m68k/pci.h b/include/asm-m68k/pci.h index 76915264d52f..efbaf41b5dfc 100644 --- a/include/asm-m68k/pci.h +++ b/include/asm-m68k/pci.h @@ -35,4 +35,9 @@ struct pci_bus_info #define pcibios_assign_all_busses() 0 +extern inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} + #endif /* _ASM_M68K_PCI_H */ diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h index 829dcaa064fd..aaa5c8fb78ef 100644 --- a/include/asm-mips/pci.h +++ b/include/asm-mips/pci.h @@ -7,6 +7,8 @@ #ifndef _ASM_PCI_H #define _ASM_PCI_H +#ifdef __KERNEL__ + /* Can be used to override the logic in pci_scan_bus for skipping already-configured bus numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the loader */ @@ -16,7 +18,10 @@ #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 -#ifdef __KERNEL__ +extern inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} /* * Dynamic DMA mapping stuff. diff --git a/include/asm-mips64/pci.h b/include/asm-mips64/pci.h index cf01a83e1c2d..7769fef70bb3 100644 --- a/include/asm-mips64/pci.h +++ b/include/asm-mips64/pci.h @@ -7,6 +7,8 @@ #ifndef _ASM_PCI_H #define _ASM_PCI_H +#ifdef __KERNEL__ + /* Can be used to override the logic in pci_scan_bus for skipping already-configured bus numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the loader */ @@ -16,7 +18,10 @@ #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 -#ifdef __KERNEL__ +extern inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} /* * Dynamic DMA mapping stuff. diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index d543c90cc76c..479f8ba2ceac 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -10,6 +10,11 @@ #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 +extern inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} + /* Dynamic DMA Mapping stuff * ++ajoshi */ diff --git a/include/asm-sh/pci.h b/include/asm-sh/pci.h index e8f6e1d66f83..bf8fe93f54ce 100644 --- a/include/asm-sh/pci.h +++ b/include/asm-sh/pci.h @@ -1,13 +1,18 @@ #ifndef __ASM_SH_PCI_H #define __ASM_SH_PCI_H +#ifdef __KERNEL__ + /* Can be used to override the logic in pci_scan_bus for skipping already-configured bus numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the loader */ #define pcibios_assign_all_busses() 0 -#ifdef __KERNEL__ +extern inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} /* Dynamic DMA mapping stuff. * SuperH has everything mapped statically like x86. diff --git a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h index 80ea9d11d0df..f96225e2ad1d 100644 --- a/include/asm-sparc/pci.h +++ b/include/asm-sparc/pci.h @@ -1,6 +1,8 @@ #ifndef __SPARC_PCI_H #define __SPARC_PCI_H +#ifdef __KERNEL__ + /* Can be used to override the logic in pci_scan_bus for skipping * already-configured bus numbers - to be used for buggy BIOSes * or architectures with incomplete PCI setup by the loader. @@ -10,7 +12,10 @@ #define PCIBIOS_MIN_IO 0UL #define PCIBIOS_MIN_MEM 0UL -#ifdef __KERNEL__ +extern inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} /* Dynamic DMA mapping stuff. */ diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h index 96ef1a5853d6..db3cd58319d9 100644 --- a/include/asm-sparc64/atomic.h +++ b/include/asm-sparc64/atomic.h @@ -1,61 +1,32 @@ -/* $Id: atomic.h,v 1.19 1999/07/03 22:11:17 davem Exp $ +/* $Id: atomic.h,v 1.20 2000/03/16 16:44:44 davem Exp $ * atomic.h: Thankfully the V9 is at least reasonable for this * stuff. * - * Copyright (C) 1996, 1997 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) */ #ifndef __ARCH_SPARC64_ATOMIC__ #define __ARCH_SPARC64_ATOMIC__ -/* Make sure gcc doesn't try to be clever and move things around - * on us. We need to use _exactly_ the address the user gave us, - * not some alias that contains the same information. - */ -#define __atomic_fool_gcc(x) ((struct { int a[100]; } *)x) - typedef struct { int counter; } atomic_t; #define ATOMIC_INIT(i) { (i) } #define atomic_read(v) ((v)->counter) #define atomic_set(v, i) (((v)->counter) = i) -#define atomic_add_return(__i, __v) \ -({ register atomic_t *__V asm("g1"); \ - register int __I asm("g2"); \ - __V = (__v); __I = (__i); \ - __asm__ __volatile__("sethi %%hi(__atomic_add), %%g3\n\t" \ - "jmpl %%g3 + %%lo(__atomic_add), %%g3\n\t" \ - " nop\n1:" \ - : "=&r" (__I) \ - : "0" (__I), "r" (__V) \ - : "g3", "g5", "g7", "cc", "memory"); \ - __I; \ -}) - -#define atomic_sub_return(__i, __v) \ -({ register atomic_t *__V asm("g1"); \ - register int __I asm("g2"); \ - __V = (__v); __I = (__i); \ - __asm__ __volatile__("sethi %%hi(__atomic_sub), %%g3\n\t" \ - "jmpl %%g3 + %%lo(__atomic_sub), %%g3\n\t" \ - " nop\n1:" \ - : "=&r" (__I) \ - : "0" (__I), "r" (__V) \ - : "g3", "g5", "g7", "cc", "memory"); \ - __I; \ -}) - -#define atomic_add(i, v) atomic_add_return(i, v) -#define atomic_sub(i, v) atomic_sub_return(i, v) - -#define atomic_dec_return(v) atomic_sub_return(1,(v)) -#define atomic_inc_return(v) atomic_add_return(1,(v)) - -#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) -#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) - -#define atomic_inc(v) atomic_add(1,(v)) -#define atomic_dec(v) atomic_sub(1,(v)) +extern int __atomic_add(int, atomic_t *); +extern int __atomic_sub(int, atomic_t *); + +#define atomic_add(i, v) ((void)__atomic_add(i, v)) +#define atomic_sub(i, v) ((void)__atomic_sub(i, v)) + +#define atomic_dec_return(v) __atomic_sub(1, v) +#define atomic_inc_return(v) __atomic_add(1, v) + +#define atomic_sub_and_test(i, v) (__atomic_sub(i, v) == 0) +#define atomic_dec_and_test(v) (__atomic_sub(1, v) == 0) + +#define atomic_inc(v) ((void)__atomic_add(1, v)) +#define atomic_dec(v) ((void)__atomic_sub(1, v)) #endif /* !(__ARCH_SPARC64_ATOMIC__) */ diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h index 0d1ca71cde60..6840476ddee0 100644 --- a/include/asm-sparc64/parport.h +++ b/include/asm-sparc64/parport.h @@ -1,4 +1,4 @@ -/* $Id: parport.h,v 1.8 2000/03/14 04:37:53 davem Exp $ +/* $Id: parport.h,v 1.9 2000/03/16 07:47:27 davem Exp $ * parport.h: sparc64 specific parport initialization and dma. * * Copyright (C) 1999 Eddie C. Dost (ecd@skynet.be) diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h index 267cbf797c26..1fd24a47f236 100644 --- a/include/asm-sparc64/pci.h +++ b/include/asm-sparc64/pci.h @@ -1,6 +1,8 @@ #ifndef __SPARC64_PCI_H #define __SPARC64_PCI_H +#ifdef __KERNEL__ + /* Can be used to override the logic in pci_scan_bus for skipping * already-configured bus numbers - to be used for buggy BIOSes * or architectures with incomplete PCI setup by the loader. @@ -10,7 +12,10 @@ #define PCIBIOS_MIN_IO 0UL #define PCIBIOS_MIN_MEM 0UL -#ifdef __KERNEL__ +extern inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} /* Dynamic DMA mapping stuff. */ diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h index 1d7b0e31c1bc..85ae21c9d9a9 100644 --- a/include/asm-sparc64/semaphore.h +++ b/include/asm-sparc64/semaphore.h @@ -90,7 +90,7 @@ extern __inline__ void down(struct semaphore * sem) ba,pt %%xcc, 2b restore %%l3, %%g0, %%g3 .previous\n" - : : "r" (__atomic_fool_gcc(sem)), "i" (__down) + : : "r" (sem), "i" (__down) : "g5", "g7", "memory", "cc"); } @@ -126,7 +126,7 @@ extern __inline__ int down_interruptible(struct semaphore *sem) restore %%o0, %%g0, %0 .previous\n" : "=r" (ret) - : "0" (ret), "r" (__atomic_fool_gcc(sem)), "i" (__down_interruptible) + : "0" (ret), "r" (sem), "i" (__down_interruptible) : "g5", "g7", "memory", "cc"); return ret; } @@ -162,7 +162,7 @@ extern inline int down_trylock(struct semaphore *sem) restore %%o0, %%g0, %0 .previous\n" : "=r" (ret) - : "0" (ret), "r" (__atomic_fool_gcc(sem)), "i" (__down_trylock) + : "0" (ret), "r" (sem), "i" (__down_trylock) : "g5", "g7", "memory", "cc"); return ret; } @@ -196,7 +196,7 @@ extern __inline__ void up(struct semaphore * sem) ba,pt %%xcc, 2b restore %%l3, %%g0, %%g3 .previous\n" - : : "r" (__atomic_fool_gcc(sem)), "i" (__up) + : : "r" (sem), "i" (__up) : "g5", "g7", "memory", "cc"); } @@ -309,7 +309,7 @@ extern inline void down_read(struct rw_semaphore *sem) ba,pt %%xcc, 2b restore %%l3, %%g0, %%g3 .previous\n" - : : "r" (__atomic_fool_gcc(sem)), "i" (__down_read_failed) + : : "r" (sem), "i" (__down_read_failed) : "g5", "g7", "memory", "cc"); #if WAITQUEUE_DEBUG if (test_le_bit(1, &sem->granted)) @@ -348,7 +348,7 @@ extern inline void down_write(struct rw_semaphore *sem) ba,pt %%xcc, 2b restore %%l3, %%g0, %%g3 .previous\n" - : : "r" (__atomic_fool_gcc(sem)), "i" (__down_write_failed) + : : "r" (sem), "i" (__down_write_failed) : "g5", "g7", "memory", "cc"); #if WAITQUEUE_DEBUG if (atomic_read(&sem->writers)) @@ -394,7 +394,7 @@ extern inline void __up_read(struct rw_semaphore *sem) ba,pt %%xcc, 2b restore %%l3, %%g0, %%g3 .previous\n" - : : "r" (__atomic_fool_gcc(sem)), "i" (__rwsem_wake) + : : "r" (sem), "i" (__rwsem_wake) : "g5", "g7", "memory", "cc"); } @@ -430,7 +430,7 @@ extern inline void __up_write(struct rw_semaphore *sem) ba,pt %%xcc, 2b restore %%l3, %%g0, %%g3 .previous\n" - : : "r" (__atomic_fool_gcc(sem)), "i" (__rwsem_wake) + : : "r" (sem), "i" (__rwsem_wake) : "g5", "g7", "memory", "cc"); } diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h index c4e571564919..ea34fbefe733 100644 --- a/include/asm-sparc64/spinlock.h +++ b/include/asm-sparc64/spinlock.h @@ -110,41 +110,15 @@ extern int _spin_trylock (spinlock_t *lock); typedef unsigned int rwlock_t; #define RW_LOCK_UNLOCKED 0 -#define read_lock(__rw_lck) \ -do { register rwlock_t *__X asm("g1"); \ - __asm__ __volatile__("sethi %%hi(__read_lock), %%g3\n\t" \ - "jmpl %%g3 + %%lo(__read_lock), %%g3\n\t" \ - " nop\n1:" \ - : : "r" (__X = (__rw_lck)) \ - : "g3", "g5", "g7", "cc", "memory"); \ -} while(0) - -#define read_unlock(__rw_lck) \ -do { register rwlock_t *__X asm("g1"); \ - __asm__ __volatile__("sethi %%hi(__read_unlock), %%g3\n\t" \ - "jmpl %%g3 + %%lo(__read_unlock), %%g3\n\t" \ - " nop\n1:" \ - : : "r" (__X = (__rw_lck)) \ - : "g3", "g5", "g7", "cc", "memory"); \ -} while(0) - -#define write_lock(__rw_lck) \ -do { register rwlock_t *__X asm("g1"); \ - __asm__ __volatile__("sethi %%hi(__write_lock), %%g3\n\t" \ - "jmpl %%g3 + %%lo(__write_lock), %%g3\n\t" \ - " nop\n1:" \ - : : "r" (__X = (__rw_lck)) \ - : "g2", "g3", "g5", "g7", "cc", "memory"); \ -} while(0) - -#define write_unlock(__rw_lck) \ -do { register rwlock_t *__X asm("g1"); \ - __asm__ __volatile__("sethi %%hi(__write_unlock), %%g3\n\t" \ - "jmpl %%g3 + %%lo(__write_unlock), %%g3\n\t" \ - " nop\n1:" \ - : : "r" (__X = (__rw_lck)) \ - : "g2", "g3", "g5", "g7", "cc", "memory"); \ -} while(0) +extern void __read_lock(rwlock_t *); +extern void __read_unlock(rwlock_t *); +extern void __write_lock(rwlock_t *); +extern void __write_unlock(rwlock_t *); + +#define read_lock(p) __read_lock(p) +#define read_unlock(p) __read_unlock(p) +#define write_lock(p) __write_lock(p) +#define write_unlock(p) __write_unlock(p) #else /* !(SPIN_LOCK_DEBUG) */ diff --git a/include/linux/ac97_codec.h b/include/linux/ac97_codec.h index 50c75c3a846b..da8730aefc9a 100644 --- a/include/linux/ac97_codec.h +++ b/include/linux/ac97_codec.h @@ -39,6 +39,21 @@ #define AC97_RESERVED_3A 0x003A /* Reserved */ /* range 0x3c-0x58 - MODEM */ +#define AC97_EXTENDED_MODEM_ID 0x003C +#define AC97_EXTEND_MODEM_STAT 0x003E +#define AC97_LINE1_RATE 0x0040 +#define AC97_LINE2_RATE 0x0042 +#define AC97_HANDSET_RATE 0x0044 +#define AC97_LINE1_LEVEL 0x0046 +#define AC97_LINE2_LEVEL 0x0048 +#define AC97_HANDSET_LEVEL 0x004A +#define AC97_GPIO_CONFIG 0x004C +#define AC97_GPIO_POLARITY 0x004E +#define AC97_GPIO_STICKY 0x0050 +#define AC97_GPIO_WAKE_UP 0x0052 +#define AC97_GPIO_STATUS 0x0054 +#define AC97_MISC_MODEM_STAT 0x0056 +#define AC97_RESERVED_58 0x0058 /* registers 0x005a - 0x007a are vendor reserved */ @@ -150,6 +165,9 @@ struct ac97_codec { /* saved OSS mixer states */ unsigned int mixer_state[SOUND_MIXER_NRDEVICES]; + + /* Software Modem interface */ + int (*modem_ioctl)(struct ac97_codec *codec, unsigned int cmd, unsigned long arg); }; extern int ac97_read_proc (char *page_out, char **start, off_t off, diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h index 3509c5cb99d6..94030b18de95 100644 --- a/include/linux/hdreg.h +++ b/include/linux/hdreg.h @@ -193,6 +193,8 @@ struct hd_geometry { #define HDIO_SET_NICE 0x0329 /* set nice flags */ #define HDIO_UNREGISTER_HWIF 0x032a /* unregister interface */ +#define __NEW_HD_DRIVE_ID + /* structure returned by HDIO_GET_IDENTITY, as per ANSI ATA2 rev.2f spec */ struct hd_driveid { unsigned short config; /* lots of obsolete bit flags */ @@ -256,7 +258,7 @@ struct hd_driveid { unsigned short CurAPMvalues; /* current APM values */ unsigned short word92; /* reserved (word 92) */ unsigned short hw_config; /* hardware config */ - unsigned short words94_125[33];/* reserved words 94-125 */ + unsigned short words94_125[31];/* reserved words 94-125 */ unsigned short last_lun; /* reserved (word 126) */ unsigned short word127; /* reserved (word 127) */ unsigned short dlf; /* device lock function diff --git a/include/linux/pci.h b/include/linux/pci.h index 413def0a94c7..472c9d87ed64 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -293,8 +293,6 @@ #define PCI_DMA_FROMDEVICE 2 #define PCI_DMA_NONE 3 -#include - #define DEVICE_COUNT_COMPATIBLE 4 #define DEVICE_COUNT_IRQ 2 #define DEVICE_COUNT_DMA 2 @@ -542,6 +540,10 @@ void pci_remove_device(struct pci_dev *); struct pci_driver *pci_dev_driver(const struct pci_dev *); const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev); +/* Include architecture-dependent settings and functions */ + +#include + /* * If the system does not have PCI, clearly these return errors. Define * these as simple inline functions to avoid hair in drivers. @@ -580,6 +582,7 @@ extern inline int pci_module_init(struct pci_driver *drv) { return -ENODEV; } extern inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;} extern inline int pci_register_driver(struct pci_driver *drv) { return 0;} extern inline void pci_unregister_driver(struct pci_driver *drv) { } +extern inline int scsi_to_pci_dma_dir(unsigned char scsi_dir) { return scsi_dir; } #else diff --git a/include/linux/soundcard.h b/include/linux/soundcard.h index 2d5128dc4314..ca8ad780d1df 100644 --- a/include/linux/soundcard.h +++ b/include/linux/soundcard.h @@ -552,6 +552,7 @@ typedef struct { # define AFMT_U16_LE 0x00000080 /* Little endian U16 */ # define AFMT_U16_BE 0x00000100 /* Big endian U16 */ # define AFMT_MPEG 0x00000200 /* MPEG (2) audio */ +# define AFMT_AC3 0x00000400 /* Dolby Digital AC3 */ /* * Buffer status queries. @@ -581,11 +582,14 @@ typedef struct audio_buf_info { /* but usually not */ # define DSP_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */ # define DSP_CAP_MMAP 0x00002000 /* Supports mmap() */ +# define DSP_CAP_MULTI 0x00004000 /* support multiple open */ +# define DSP_CAP_BIND 0x00008000 /* channel binding to front/rear/cneter/lfe */ + #define SNDCTL_DSP_GETTRIGGER _SIOR ('P',16, int) #define SNDCTL_DSP_SETTRIGGER _SIOW ('P',16, int) # define PCM_ENABLE_INPUT 0x00000001 -# define PCM_ENABLE_OUTPUT 0x00000002 +# define PCM_ENABLE_OUTPUT 0x00000002 typedef struct count_info { int bytes; /* Total # of bytes processed */ @@ -606,6 +610,19 @@ typedef struct buffmem_desc { #define SNDCTL_DSP_SETDUPLEX _SIO ('P', 22) #define SNDCTL_DSP_GETODELAY _SIOR ('P', 23, int) +#define SNDCTL_DSP_GETCHANNELMASK _SIOWR('P', 64, int) +#define SNDCTL_DSP_BIND_CHANNEL _SIOWR('P', 65, int) +# define DSP_BIND_QUERY 0x00000000 +# define DSP_BIND_FRONT 0x00000001 +# define DSP_BIND_SURR 0x00000002 +# define DSP_BIND_CENTER_LFE 0x00000004 +# define DSP_BIND_HANDSET 0x00000008 +# define DSP_BIND_MIC 0x00000010 +# define DSP_BIND_MODEM1 0x00000020 +# define DSP_BIND_MODEM2 0x00000040 +# define DSP_BIND_I2S 0x00000080 +# define DSP_BIND_SPDIF 0x00000100 + /* * Application's profile defines the way how playback underrun situations should be handled. * diff --git a/net/khttpd/security.c b/net/khttpd/security.c index df346aadb1b3..bd578941d757 100644 --- a/net/khttpd/security.c +++ b/net/khttpd/security.c @@ -115,7 +115,7 @@ struct file *OpenFileForSecurity(char *Filename) - filp = filp_open(Filename,00,O_RDONLY); + filp = filp_open(Filename, 0, O_RDONLY, NULL); if ((IS_ERR(filp))||(filp==NULL)||(filp->f_dentry==NULL)) diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index d63024983a7a..97e323d0cb23 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -636,7 +636,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) dprintk("svc: incomplete TCP record (%d of %d)\n", len, svsk->sk_reclen); svc_sock_received(svsk, ready); - len = -EAGAIN; /* record not complete */ + return -EAGAIN; /* record not complete */ } /* Frob argbuf */ diff --git a/scripts/Makefile b/scripts/Makefile index 66311cbd0031..d6d231d73fa6 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -40,6 +40,6 @@ docproc: docproc.o ${HOSTCC} -o docproc docproc.o clean: - rm -f *~ kconfig.tk *.o tkparse mkdep split-include + rm -f *~ kconfig.tk *.o tkparse mkdep split-include docproc include $(TOPDIR)/Rules.make