diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-07-08 00:53:00 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-07-08 00:53:00 +0000 |
commit | b8553086288629b4efb77e97f5582e08bc50ad65 (patch) | |
tree | 0a19bd1c21e148f35c7a0f76baa4f7a056b966b0 /arch/sparc64/kernel | |
parent | 75b6d92f2dd5112b02f4e78cf9f35f9825946ef0 (diff) |
Merge with 2.4.0-test3-pre4.
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/irq.c | 37 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sabre.c | 31 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc.c | 7 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc32.c | 17 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sunos32.c | 10 |
5 files changed, 55 insertions, 47 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index eb6f789f6..a4904efb3 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.87 2000/05/09 17:40:13 davem Exp $ +/* $Id: irq.c,v 1.88 2000/06/26 19:40:27 davem Exp $ * irq.c: UltraSparc IRQ handling/init/registry. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -62,6 +62,19 @@ unsigned int __up_workvec[16] __attribute__ ((aligned (64))); #define irq_work(__cpu, __pil) &(cpu_data[(__cpu)].irq_worklists[(__pil)]) #endif +#ifdef CONFIG_PCI +/* This is a table of physical addresses used to deal with SA_DMA_SYNC. + * It is used for PCI only to synchronize DMA transfers with IRQ delivery + * for devices behind busses other than APB on Sabre systems. + * + * Currently these physical addresses are just config space accesses + * to the command register for that device. + */ +unsigned long pci_dma_wsync; +unsigned long dma_sync_reg_table[256]; +unsigned char dma_sync_reg_table_entry = 0; +#endif + /* This is based upon code in the 32-bit Sparc kernel written mostly by * David Redman (djhr@tadpole.co.uk). */ @@ -280,8 +293,6 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) /* * Check wether we _should_ use DMA Write Sync * (for devices behind bridges behind APB). - * - * XXX: Not implemented, yet. */ if (bucket->flags & IBF_DMA_SYNC) irqflags |= SA_DMA_SYNC; @@ -719,14 +730,14 @@ void handler_irq(int irq, struct pt_regs *regs) /* 'cpu' is the MID (ie. UPAID), calculate the MID * of our buddy. */ - if(should_forward != 0) { + if (should_forward != 0) { buddy = cpu_number_map(cpu) + 1; if (buddy >= NR_CPUS || (buddy = cpu_logical_map(buddy)) == -1) buddy = cpu_logical_map(0); /* Voo-doo programming. */ - if(cpu_data[buddy].idle_volume < FORWARD_VOLUME) + if (cpu_data[buddy].idle_volume < FORWARD_VOLUME) should_forward = 0; buddy <<= 26; } @@ -752,25 +763,29 @@ void handler_irq(int irq, struct pt_regs *regs) #else bp = __bucket(xchg32(irq_work(cpu, irq), 0)); #endif - for( ; bp != NULL; bp = nbp) { + for ( ; bp != NULL; bp = nbp) { unsigned char flags = bp->flags; nbp = __bucket(bp->irq_chain); - if((flags & IBF_ACTIVE) != 0) { - if((flags & IBF_MULTI) == 0) { + if ((flags & IBF_ACTIVE) != 0) { + if ((flags & IBF_DMA_SYNC) != 0) { + upa_readl(dma_sync_reg_table[bp->synctab_ent]); + upa_readq(pci_dma_wsync); + } + if ((flags & IBF_MULTI) == 0) { struct irqaction *ap = bp->irq_info; ap->handler(__irq(bp), ap->dev_id, regs); } else { void **vector = (void **)bp->irq_info; int ent; - for(ent = 0; ent < 4; ent++) { + for (ent = 0; ent < 4; ent++) { struct irqaction *ap = vector[ent]; - if(ap != NULL) + if (ap != NULL) ap->handler(__irq(bp), ap->dev_id, regs); } } /* Only the dummy bucket lacks IMAP/ICLR. */ - if(bp->pil != 0) { + if (bp->pil != 0) { #ifdef CONFIG_SMP /* Ok, here is what is going on: * 1) Retargeting IRQs on Starfire is very diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 99f7ba8ad..f3a5adbec 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -1,4 +1,4 @@ -/* $Id: pci_sabre.c,v 1.19 2000/04/15 13:07:51 davem Exp $ +/* $Id: pci_sabre.c,v 1.20 2000/06/26 19:40:27 davem Exp $ * pci_sabre.c: Sabre specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) @@ -641,14 +641,28 @@ static unsigned int __init sabre_irq_build(struct pci_controller_info *p, bucket = __bucket(build_irq(pil, inofixup, iclr, imap)); bucket->flags |= IBF_PCI; - /* XXX We still need to code up support for this in irq.c - * XXX It's easy to code up since only one SIMBA can exist - * XXX in a machine and this is where the sync register is. -DaveM - */ if (pdev) { struct pcidev_cookie *pcp = pdev->sysdata; - if (pdev->bus->number != pcp->pbm->pci_first_busno) + + /* When a device lives behind a bridge deeper in the + * PCI bus topology than APB, a special sequence must + * run to make sure all pending DMA transfers at the + * time of IRQ delivery are visible in the coherency + * domain by the cpu. This sequence is to perform + * a read on the far side of the non-APB bridge, then + * perform a read of Sabre's DMA write-sync register. + * + * Currently, the PCI_CONFIG register for the device + * is used for this read from the far side of the bridge. + */ + if (pdev->bus->number != pcp->pbm->pci_first_busno) { bucket->flags |= IBF_DMA_SYNC; + bucket->synctab_ent = dma_sync_reg_table_entry++; + dma_sync_reg_table[bucket->synctab_ent] = + (unsigned long) sabre_pci_config_mkaddr( + pcp->pbm, + pdev->bus->number, pdev->devfn, PCI_COMMAND); + } } return __irq(bucket); } @@ -1399,7 +1413,10 @@ void __init sabre_init(int pnode) * First REG in property is base of entire SABRE register space. */ p->controller_regs = pr_regs[0].phys_addr; - printk("PCI: Found SABRE, main regs at %016lx\n", p->controller_regs); + pci_dma_wsync = p->controller_regs + SABRE_WRSYNC; + + printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n", + p->controller_regs, pci_dma_wsync); /* Error interrupts are enabled later after the bus scan. */ sabre_write(p->controller_regs + SABRE_PCICTRL, diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 2aff3033a..42ba3907b 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.41 2000/06/22 11:42:25 davem Exp $ +/* $Id: sys_sparc.c,v 1.42 2000/06/26 23:20:24 davem Exp $ * linux/arch/sparc64/kernel/sys_sparc.c * * This file contains various random system calls that @@ -92,14 +92,12 @@ asmlinkage int sparc_pipe(struct pt_regs *regs) int fd[2]; int error; - lock_kernel(); error = do_pipe(fd); if (error) goto out; regs->u_regs[UREG_I1] = fd[1]; error = fd[0]; out: - unlock_kernel(); return error; } @@ -227,8 +225,6 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, len = PAGE_ALIGN(len); retval = -EINVAL; - lock_kernel(); - if (current->thread.flags & SPARC_FLAG_32BIT) { if (len > 0xf0000000UL || ((flags & MAP_FIXED) && addr > 0xf0000000UL - len)) @@ -245,7 +241,6 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, up(¤t->mm->mmap_sem); out_putf: - unlock_kernel(); if (file) fput(file); out: diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index e27892de3..607633aec 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.152 2000/06/22 17:44:47 davem Exp $ +/* $Id: sys_sparc32.c,v 1.153 2000/06/26 23:20:24 davem Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -1266,14 +1266,12 @@ asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, buf.count = 0; buf.dirent = dirent; - lock_kernel(); error = vfs_readdir(file, fillonedir, &buf); if (error < 0) goto out_putf; error = buf.count; out_putf: - unlock_kernel(); fput(file); out: return error; @@ -1333,7 +1331,6 @@ asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, un buf.count = count; buf.error = 0; - lock_kernel(); error = vfs_readdir(file, filldir, &buf); if (error < 0) goto out_putf; @@ -1344,7 +1341,6 @@ asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, un error = count - buf.count; } out_putf: - unlock_kernel(); fput(file); out: return error; @@ -1587,7 +1583,6 @@ asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf) struct nameidata nd; int error; - lock_kernel(); error = user_path_walk(filename, &nd); if (!error) { struct inode *inode = nd.dentry->d_inode; @@ -1602,7 +1597,6 @@ asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf) path_release(&nd); } - unlock_kernel(); return error; } @@ -1611,7 +1605,6 @@ asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf) struct nameidata nd; int error; - lock_kernel(); error = user_path_walk_link(filename, &nd); if (!error) { struct inode *inode = nd.dentry->d_inode; @@ -1626,7 +1619,6 @@ asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf) path_release(&nd); } - unlock_kernel(); return error; } @@ -1635,15 +1627,13 @@ asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf) struct file *f; int err = -EBADF; - lock_kernel(); f = fget(fd); if (f) { - struct dentry *dentry = f->f_dentry; - struct inode *inode = dentry->d_inode; + struct inode *inode = f->f_dentry->d_inode; if (inode->i_op && inode->i_op->revalidate) - err = inode->i_op->revalidate(dentry); + err = inode->i_op->revalidate(f->f_dentry); else err = 0; if (!err) @@ -1651,7 +1641,6 @@ asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf) fput(f); } - unlock_kernel(); return err; } diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 70adfe21a..bad3d5e2f 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sunos32.c,v 1.49 2000/06/22 11:42:25 davem Exp $ +/* $Id: sys_sunos32.c,v 1.50 2000/06/26 23:20:24 davem Exp $ * sys_sunos32.c: SunOS binary compatability layer on sparc64. * * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -68,7 +68,6 @@ asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 of struct file *file = NULL; unsigned long retval, ret_type; - lock_kernel(); if(flags & MAP_NORESERVE) { static int cnt; if (cnt++ < 10) @@ -113,7 +112,6 @@ out_putf: if (file) fput(file); out: - unlock_kernel(); return (u32) retval; } @@ -321,8 +319,6 @@ asmlinkage int sunos_getdents(unsigned int fd, u32 u_dirent, int cnt) if(!file) goto out; - lock_kernel(); - error = -EINVAL; if(cnt < (sizeof(struct sunos_dirent) + 255)) goto out_putf; @@ -344,7 +340,6 @@ asmlinkage int sunos_getdents(unsigned int fd, u32 u_dirent, int cnt) } out_putf: - unlock_kernel(); fput(file); out: return error; @@ -406,8 +401,6 @@ asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent, if(!file) goto out; - lock_kernel(); - error = -EINVAL; if(cnt < (sizeof(struct sunos_direntry) + 255)) goto out_putf; @@ -429,7 +422,6 @@ asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent, } out_putf: - unlock_kernel(); fput(file); out: return error; |