]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.129pre5 2.1.129pre5
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:17:20 +0000 (15:17 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:17:20 +0000 (15:17 -0500)
93 files changed:
CREDITS
MAINTAINERS
arch/i386/kernel/entry.S
arch/sparc/kernel/entry.S
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/kernel/sun4d_smp.c
arch/sparc/kernel/sun4m_smp.c
arch/sparc/mm/fault.c
arch/sparc/mm/generic.c
arch/sparc/mm/io-unit.c
arch/sparc64/config.in
arch/sparc64/defconfig
arch/sparc64/kernel/ioctl32.c
arch/sparc64/kernel/psycho.c
arch/sparc64/kernel/rtrap.S
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/sys32.S
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/mm/fault.c
arch/sparc64/mm/generic.c
arch/sparc64/mm/ultra.S
arch/sparc64/solaris/Makefile
arch/sparc64/solaris/fs.c
arch/sparc64/solaris/misc.c
arch/sparc64/solaris/socket.c [new file with mode: 0644]
arch/sparc64/solaris/systbl.S
drivers/block/Config.in
drivers/block/genhd.c
drivers/block/ns87415.c
drivers/char/Makefile
drivers/char/cyclades.c
drivers/char/mem.c
drivers/char/misc.c
drivers/misc/parport_ax.c
drivers/net/net_init.c
drivers/net/sgiseeq.c
drivers/net/sunhme.c
drivers/net/sunhme.h
drivers/sbus/audio/Makefile
drivers/sbus/audio/amd7930.c
drivers/sbus/audio/amd7930.h
drivers/sbus/audio/audio.c
drivers/sbus/audio/cs4231.c
drivers/sbus/audio/cs4231.h
drivers/sbus/audio/dbri.c
drivers/sbus/audio/dbri.h
drivers/sbus/char/Makefile
drivers/sbus/char/envctrl.c
drivers/sbus/char/pcikbd.c
drivers/sbus/char/sab82532.c
drivers/sbus/char/su.c
drivers/sbus/char/zs.c
drivers/scsi/esp.c
drivers/sound/Makefile
fs/Config.in
fs/autofs/autofs_i.h
fs/autofs/root.c
fs/autofs/waitq.c
fs/fat/inode.c
fs/namei.c
include/asm-alpha/namei.h
include/asm-arm/namei.h
include/asm-i386/namei.h
include/asm-i386/unistd.h
include/asm-m68k/namei.h
include/asm-mips/namei.h
include/asm-sparc/asm_offsets.h
include/asm-sparc/io-unit.h
include/asm-sparc/namei.h
include/asm-sparc/smp.h
include/asm-sparc/spinlock.h
include/asm-sparc64/asm_offsets.h
include/asm-sparc64/dma.h
include/asm-sparc64/namei.h
include/asm-sparc64/pgtable.h
include/asm-sparc64/spinlock.h
include/linux/auto_fs.h
include/linux/lp.h
include/linux/tty.h
init/main.c
mm/Makefile
mm/filemap.c
mm/mrecow.c [new file with mode: 0644]
mm/swapfile.c
mm/vmscan.c
net/ipv4/af_inet.c
net/ipv4/raw.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv6/raw.c
net/ipv6/udp.c

diff --git a/CREDITS b/CREDITS
index 29eac8681b96cea7eaf71ea449a41fb9ffb35943..f4996fbda1b0e628393eefe68913cb2db8178e34 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -429,7 +429,7 @@ S: Belgium
 N: Cort Dougan
 E: cort@cs.nmt.edu
 W: http://www.cs.nmt.edu/~cort/
-D: PowerPC PReP port
+D: PowerPC
 S: Computer Science Department
 S: New Mexico Tech
 S: Socorro, New Mexico 87801
index 9a2a813ef4c628ab52dda6a69fc86bbb91aa2563..bafcd31654aeecfeb5223dc182a8352302f68099 100644 (file)
@@ -387,7 +387,7 @@ S:  Maintained
 LINUX FOR POWERPC (PREP)
 P:     Cort Dougan
 M:     cort@cs.nmt.edu
-W:     http://www.cs.nmt.edu/~linuxppc/
+W:     http://linuxppc.cs.nmt.edu/
 S:     Maintained
 
 LINUX FOR POWER MACINTOSH
index aa95a0b60b34aa30e73d8415f690e603efb86ab9..fd6ca20590b15ab778dd44017a1636b60d4a587b 100644 (file)
@@ -559,6 +559,7 @@ ENTRY(sys_call_table)
        .long SYMBOL_NAME(sys_sendfile)
        .long SYMBOL_NAME(sys_ni_syscall)               /* streams1 */
        .long SYMBOL_NAME(sys_ni_syscall)               /* streams2 */
+       .long SYMBOL_NAME(sys_mrecow)           /* 190 */
 
        /*
         * NOTE!! This doesn' thave to be exact - we just have
@@ -566,6 +567,6 @@ ENTRY(sys_call_table)
         * entries. Don't panic if you notice that this hasn't
         * been shrunk every time we add a new system call.
         */
-       .rept NR_syscalls-189
+       .rept NR_syscalls-190
                .long SYMBOL_NAME(sys_ni_syscall)
        .endr
index 66ae020548a9cd98421e03723592973b32b1cea9..d628c0c8d5026c01584e8240c8ee3a5321c38642 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.152 1998/07/29 16:32:24 jj Exp $
+/* $Id: entry.S,v 1.153 1998/11/11 15:12:33 jj Exp $
  * arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -313,7 +313,8 @@ real_irq_continue:
 patch_handler_irq:
        call    C_LABEL(handler_irq)
         add    %sp, REGWIN_SZ, %o1     ! pt_regs ptr
-       wr      %l0, PSR_ET, %psr
+       or      %l0, PSR_PIL, %g2       ! restore PIL after handler_irq
+       wr      %g2, PSR_ET, %psr       ! keep ET up
        WRITE_PAUSE
 
        RESTORE_ALL
index a23b84a443964d29a183b7171df59025d7333385..43f963217f6296567c68b848fd551b88eb8e2754 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sparc_ksyms.c,v 1.72 1998/10/22 15:15:08 ecd Exp $
+/* $Id: sparc_ksyms.c,v 1.73 1998/11/06 13:49:54 jj Exp $
  * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -41,6 +41,7 @@
 #endif
 #include <asm/a.out.h>
 #include <asm/spinlock.h>
+#include <asm/io-unit.h>
 
 struct poll {
        int fd;
@@ -157,6 +158,8 @@ EXPORT_SYMBOL(request_fast_irq);
 EXPORT_SYMBOL(sparc_alloc_io);
 EXPORT_SYMBOL(sparc_free_io);
 EXPORT_SYMBOL(io_remap_page_range);
+EXPORT_SYMBOL(iounit_map_dma_init);
+EXPORT_SYMBOL(iounit_map_dma_page);
 
 /* Btfixup stuff cannot have versions, it would be complicated too much */
 #ifndef __SMP__
index 1078323d00dc288577c3f7c917139804cab7fb4b..af0aaf58d7af4b582ea5c2d1985ff33597cf9dff 100644 (file)
@@ -168,10 +168,6 @@ __initfunc(void smp4d_boot_cpus(void))
 
        printk("Entering SMP Mode...\n");
        
-       smp_penguin_ctable.which_io = 0;
-       smp_penguin_ctable.phys_addr = (unsigned int) srmmu_ctx_table_phys;
-       smp_penguin_ctable.reg_size = 0;
-
        for (i = 0; i < NR_CPUS; i++)
                cpu_offset[i] = (char *)&cpu_data[i] - (char *)&cpu_data;
                
@@ -220,7 +216,16 @@ __initfunc(void smp4d_boot_cpus(void))
                        for (no = 0; no < linux_num_cpus; no++)
                                if (linux_cpus[no].mid == i)
                                        break;
-                       
+
+                       /*
+                        * Initialize the contexts table
+                        * Since the call to prom_startcpu() trashes the structure,
+                        * we need to re-initialize it for each cpu
+                        */
+                       smp_penguin_ctable.which_io = 0;
+                       smp_penguin_ctable.phys_addr = (unsigned int) srmmu_ctx_table_phys;
+                       smp_penguin_ctable.reg_size = 0;
+
                        /* whirrr, whirrr, whirrrrrrrrr... */
                        SMP_PRINTK(("Starting CPU %d at %p task %d node %08x\n", i, entry, cpucount, linux_cpus[no].prom_node));
                        local_flush_cache_all();
@@ -230,10 +235,10 @@ __initfunc(void smp4d_boot_cpus(void))
                        SMP_PRINTK(("prom_startcpu returned :)\n"));
 
                        /* wheee... it's going... */
-                       for(timeout = 0; timeout < 5000000; timeout++) {
+                       for(timeout = 0; timeout < 10000; timeout++) {
                                if(cpu_callin_map[i])
                                        break;
-                               udelay(100);
+                               udelay(200);
                        }
                        
                        if(cpu_callin_map[i]) {
index 8e0056c3f371f631e6c07c48034892c6337ea817..183ea73235edc3c7c7e2e965942ca9f6da4edb05 100644 (file)
@@ -143,10 +143,6 @@ __initfunc(void smp4m_boot_cpus(void))
 
        printk("Entering SMP Mode...\n");
 
-       smp_penguin_ctable.which_io = 0;
-       smp_penguin_ctable.phys_addr = (unsigned int) srmmu_ctx_table_phys;
-       smp_penguin_ctable.reg_size = 0;
-
        for (i = 0; i < NR_CPUS; i++)
                cpu_offset[i] = (char *)&cpu_data[i] - (char *)&cpu_data;
 
@@ -189,6 +185,15 @@ __initfunc(void smp4m_boot_cpus(void))
                        /* See trampoline.S for details... */
                        entry += ((i-1) * 3);
 
+                       /*
+                        * Initialize the contexts table
+                        * Since the call to prom_startcpu() trashes the structure,
+                        * we need to re-initialize it for each cpu
+                        */
+                       smp_penguin_ctable.which_io = 0;
+                       smp_penguin_ctable.phys_addr = (unsigned int) srmmu_ctx_table_phys;
+                       smp_penguin_ctable.reg_size = 0;
+
                        /* whirrr, whirrr, whirrrrrrrrr... */
                        printk("Starting CPU %d at %p\n", i, entry);
                        mid_xlate[i] = (linux_cpus[i].mid & ~8);
@@ -197,10 +202,10 @@ __initfunc(void smp4m_boot_cpus(void))
                                      &smp_penguin_ctable, 0, (char *)entry);
 
                        /* wheee... it's going... */
-                       for(timeout = 0; timeout < 5000000; timeout++) {
+                       for(timeout = 0; timeout < 10000; timeout++) {
                                if(cpu_callin_map[i])
                                        break;
-                               udelay(100);
+                               udelay(200);
                        }
                        if(cpu_callin_map[i]) {
                                /* Another "Red Snapper". */
index a1324af83778c422f798af712385a003bae86800..3c8ffbfae78fb6025cad6af6e3efdfda9ba95722 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.95 1998/09/18 19:50:32 davem Exp $
+/* $Id: fault.c,v 1.96 1998/11/08 11:13:56 davem Exp $
  * fault.c:  Page fault handlers for the Sparc.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -231,7 +231,8 @@ good_area:
                if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
                        goto bad_area;
        }
-       handle_mm_fault(current, vma, address, write);
+       if (!handle_mm_fault(current, vma, address, write))
+               goto do_sigbus;
        up(&mm->mmap_sem);
        return;
        /*
@@ -241,7 +242,7 @@ good_area:
 bad_area:
        up(&mm->mmap_sem);
        /* Is this in ex_table? */
-       
+do_kernel_fault:
        g2 = regs->u_regs[UREG_G2];
        if (!from_user && (fixup = search_exception_table (regs->pc, &g2))) {
                if (fixup > 10) { /* Values below are reserved for other things */
@@ -279,6 +280,15 @@ bad_area:
                return;
        }
        unhandled_fault (address, tsk, regs);
+       return;
+
+do_sigbus:
+       up(&mm->mmap_sem);
+       tsk->tss.sig_address = address;
+       tsk->tss.sig_desc = SUBSIG_MISCERROR;
+       force_sig(SIGBUS, tsk);
+       if (! from_user)
+               goto do_kernel_fault;
 }
 
 asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
@@ -372,7 +382,8 @@ good_area:
        else
                if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
                        goto bad_area;
-       handle_mm_fault(current, vma, address, write);
+       if (!handle_mm_fault(current, vma, address, write))
+               goto do_sigbus;
        up(&mm->mmap_sem);
        return;
 bad_area:
@@ -385,6 +396,12 @@ bad_area:
        tsk->tss.sig_desc = SUBSIG_NOMAPPING;
        send_sig(SIGSEGV, tsk, 1);
        return;
+
+do_sigbus:
+       up(&mm->mmap_sem);
+       tsk->tss.sig_address = address;
+       tsk->tss.sig_desc = SUBSIG_MISCERROR;
+       force_sig(SIGBUS, tsk);
 }
 
 void window_overflow_fault(void)
index 4ad1810e3169df73cb826de20f0612f9e2282297..ea94a8f60aaff5d1c5734b22ec6afb6a4dbf69a6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: generic.c,v 1.5 1996/12/18 06:43:23 tridge Exp $
+/* $Id: generic.c,v 1.6 1998/10/27 23:28:00 davem Exp $
  * generic.c: Generic Sparc mm routines that are not dependent upon
  *            MMU type but are Sparc specific.
  *
@@ -41,10 +41,11 @@ static inline void forget_pte(pte_t page)
                unsigned long addr = pte_page(page);
                if (MAP_NR(addr) >= max_mapnr || PageReserved(mem_map+MAP_NR(addr)))
                        return;
-               free_page(addr);
-               if (current->mm->rss <= 0)
-                       return;
-               current->mm->rss--;
+               /* 
+                * free_page() used to be able to clear swap cache
+                * entries.  We may now have to do it manually.  
+                */
+               free_page_and_swap_cache(addr);
                return;
        }
        swap_free(pte_val(page));
index 41bd72671728d8f6e5e3d43c07025675cb5b0392..6cd8c9b7c25991f3cee534933dbbfc589bce2826 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: io-unit.c,v 1.11 1998/04/13 07:26:37 davem Exp $
+/* $Id: io-unit.c,v 1.13 1998/11/08 11:13:57 davem Exp $
  * io-unit.c:  IO-UNIT specific routines for memory management.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek    (jj@sunsite.mff.cuni.cz)
@@ -231,3 +231,51 @@ __initfunc(void ld_mmu_iounit(void))
        BTFIXUPSET_CALL(mmu_map_dma_area, iounit_map_dma_area, BTFIXUPCALL_NORM);
 #endif
 }
+
+__u32 iounit_map_dma_init(struct linux_sbus *sbus, int size)
+{
+       int i, j, k, npages;
+       unsigned long rotor, scan, limit;
+       unsigned long flags;
+       __u32 ret;
+       struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
+
+        npages = (size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
+       i = 0x0213;
+       spin_lock_irqsave(&iounit->lock, flags);
+next:  j = (i & 15);
+       rotor = iounit->rotor[j - 1];
+       limit = iounit->limit[j];
+       scan = rotor;
+nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan);
+       if (scan + npages > limit) {
+               if (limit != rotor) {
+                       limit = rotor;
+                       scan = iounit->limit[j - 1];
+                       goto nexti;
+               }
+               i >>= 4;
+               if (!(i & 15))
+                       panic("iounit_map_dma_init: Couldn't find free iopte slots for %d bytes\n", size);
+               goto next;
+       }
+       for (k = 1, scan++; k < npages; k++)
+               if (test_bit(scan++, iounit->bmap))
+                       goto nexti;
+       iounit->rotor[j - 1] = (scan < limit) ? scan : iounit->limit[j - 1];
+       scan -= npages;
+       ret = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT);
+       for (k = 0; k < npages; k++, scan++)
+               set_bit(scan, iounit->bmap);
+       spin_unlock_irqrestore(&iounit->lock, flags);
+       return ret;
+}
+
+__u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct linux_sbus *sbus)
+{
+       int scan = (vaddr - IOUNIT_DMA_BASE) >> PAGE_SHIFT;
+       struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
+       
+       iounit->page_table[scan] = MKIOPTE(mmu_v2p(((unsigned long)addr) & PAGE_MASK));
+       return vaddr + (((unsigned long)addr) & ~PAGE_MASK);
+}
index 62847fa6f15f93be7499e593b1254fa3faf8ef17..6898144e8eed37dae51df019907394b2514c50c3 100644 (file)
@@ -224,7 +224,10 @@ if [ "$CONFIG_NET" = "y" ]; then
                tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS
                if [ "$CONFIG_PCI" = "y" ]; then
                        tristate 'Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5
-                       tristate '3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX
+# Turned off until updated 3c59x.c driver
+# gets approved by Linus...  --DAVEM
+#
+#                      tristate '3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX
                fi
 #              bool 'FDDI driver support' CONFIG_FDDI
 #              if [ "$CONFIG_FDDI" = "y" ]; then
index 3a0e0c63c9a32713eed0ff9df96724ce3f1693bd..a6024f1443d0ac33168486e7749a56dad590d898 100644 (file)
@@ -198,7 +198,7 @@ CONFIG_SCSI_AIC7XXX=y
 # CONFIG_AIC7XXX_PROC_STATS is not set
 CONFIG_AIC7XXX_RESET_DELAY=5
 CONFIG_SCSI_NCR53C8XX=y
-CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=4
 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
 CONFIG_SCSI_NCR53C8XX_SYNC=10
 # CONFIG_SCSI_NCR53C8XX_PROFILE is not set
index 10a011558f181eb1bc8eef7112919f90b5a414d7..7fc05b1c607fd7ce6dabc10ce7d9db3008b3cccb 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.53 1998/10/26 08:01:01 jj Exp $
+/* $Id: ioctl32.c,v 1.54 1998/11/11 17:09:04 jj Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997  Jakub Jelinek  (jj@sunsite.mff.cuni.cz)
@@ -34,6 +34,7 @@
 #include <linux/tty.h>
 #include <linux/vt_kern.h>
 #include <linux/fb.h>
+#include <linux/ext2_fs.h>
 
 #include <scsi/scsi.h>
 /* Ugly hack. */
        __ret;                          \
 })
 
+/* Aiee. Someone does not find a difference between int and long */
+#define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
+#define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)
+#define EXT2_IOC32_GETVERSION             _IOR('v', 1, int)
+#define EXT2_IOC32_SETVERSION             _IOW('v', 2, int)
+
 extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
 
 static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -94,6 +101,18 @@ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
                return -EFAULT;
        return err;
 }
+
+static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       /* These are just misnamed, they actually get/put from/to user an int */
+       switch (cmd) {
+       case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;
+       case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;
+       case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;
+       case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;
+       }
+       return sys_ioctl(fd, cmd, arg);
+}
  
 struct timeval32 {
        int tv_sec;
@@ -1551,6 +1570,13 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
                error = do_kdfontop_ioctl(filp, (struct console_font_op32 *)arg);
                goto out;
                
+       case EXT2_IOC32_GETFLAGS:
+       case EXT2_IOC32_SETFLAGS:
+       case EXT2_IOC32_GETVERSION:
+       case EXT2_IOC32_SETVERSION:
+               error = do_ext2_ioctl(fd, cmd, arg);
+               goto out;
+               
        /* List here exlicitly which ioctl's are known to have
         * compatable types passed or none at all...
         */
@@ -1865,7 +1891,7 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
        case AUTOFS_IOC_CATATONIC:
        case AUTOFS_IOC_PROTOVER:
        case AUTOFS_IOC_EXPIRE:
-
+       
                error = sys_ioctl (fd, cmd, arg);
                goto out;
 
index 0934b3abcb3949e974629550f829291fefa75479..96b1ac2e9de7b9b836fe6363007583e264704a91 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: psycho.c,v 1.65 1998/10/20 14:41:28 ecd Exp $
+/* $Id: psycho.c,v 1.66 1998/11/02 22:27:45 davem Exp $
  * psycho.c: Ultra/AX U2P PCI controller support.
  *
  * Copyright (C) 1997 David S. Miller (davem@caipfs.rutgers.edu)
@@ -1406,9 +1406,9 @@ __initfunc(static void fixup_regs(struct pci_dev *pdev,
        dprintf("REG_FIXUP[%04x,%04x]: ", pdev->vendor, pdev->device);
        for(preg = 0; preg < 6; preg++) {
                if(pdev->base_address[preg] != 0)
-                       prom_printf("%d[%016lx] ", preg, pdev->base_address[preg]);
+                       dprintf("%d[%016lx] ", preg, pdev->base_address[preg]);
        }
-       prom_printf("\n");
+       dprintf("\n");
 #endif
 }
 
@@ -1930,8 +1930,8 @@ static inline int
 out_of_range(struct linux_pbm_info *pbm, unsigned char bus, unsigned char devfn)
 {
        return ((pbm->parent == 0) ||
-               ((pbm == &pbm->parent->pbm_B) && (bus == pbm->pci_first_busno) && PCI_SLOT(devfn) > 4) ||
-               ((pbm == &pbm->parent->pbm_A) && (bus == pbm->pci_first_busno) && PCI_SLOT(devfn) > 6) ||
+               ((pbm == &pbm->parent->pbm_B) && (bus == pbm->pci_first_busno) && PCI_SLOT(devfn) > 8) ||
+               ((pbm == &pbm->parent->pbm_A) && (bus == pbm->pci_first_busno) && PCI_SLOT(devfn) > 8) ||
                (pci_probe_enable == 0));
 }
 
index 0088d219090d58957df20f6675344d11dcb61a0d..a3137ee509fd3cd120ae0c4b7676f59baeb15cad 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: rtrap.S,v 1.44 1998/10/21 22:27:22 davem Exp $
+/* $Id: rtrap.S,v 1.45 1998/11/09 15:33:29 davem Exp $
  * rtrap.S: Preparing for return from trap on Sparc V9.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -172,7 +172,13 @@ check_user_wins:
                wrpr                    %l7, PSTATE_IE, %pstate
                call                    update_perfctrs
                 nop
-               ba,a,pt                 %xcc, check_user_wins
+               wrpr                    %l7, 0x0, %pstate
+               lduh                    [%g6 + AOFF_task_tss + AOFF_thread_w_saved], %o2
+               brz,pt                  %o2, 1f
+                sethi                  %hi(TSTATE_PEF), %l6
+               wrpr                    %l7, PSTATE_IE, %pstate
+               call                    fault_in_user_windows
+                add                    %sp, STACK_BIAS + REGWIN_SZ, %o0
 
 1:
                andcc                   %l1, %l6, %g0
index d68f489f2974a614727691b7d54c46ed6ce924c7..a42505edc4b4308e115721156065a4b8602f8bbf 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.48 1998/10/20 03:09:08 jj Exp $
+/* $Id: sparc64_ksyms.c,v 1.49 1998/10/28 08:11:28 jj Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -257,6 +257,9 @@ EXPORT_SYMBOL(svr4_setcontext);
 EXPORT_SYMBOL(prom_cpu_nodes);
 EXPORT_SYMBOL(sys_ioctl);
 EXPORT_SYMBOL(sys32_ioctl);
+EXPORT_SYMBOL(get_unmapped_area);
+EXPORT_SYMBOL(move_addr_to_kernel);
+EXPORT_SYMBOL(move_addr_to_user);
 #endif
 
 /* Special internal versions of library functions. */
index dcba30496b118f946b66c5f8aef9193ba27524c0..fd1ff6a0b62c41dc8c5a92a9bb82fec81b8f2f5f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sys32.S,v 1.7 1998/09/11 10:39:46 jj Exp $
+/* $Id: sys32.S,v 1.8 1998/10/28 08:10:37 jj Exp $
  * sys32.S: I-cache tricks for 32-bit compatability layer simple
  *          conversions.
  *
        .align          32
        .globl          sys32_mmap
 sys32_mmap:
-       srl             %o0, 0, %o0                     ! IEU0  Group
-       sethi           %hi(0xffffffff), %g2            ! IEU1
-       srl             %o1, 0, %o1                     ! IEU0  Group
-       or              %g2, %lo(0xffffffff), %g2       ! IEU1
-       srl             %o2, 0, %o2                     ! IEU0  Group
-       sethi           %hi(sys_mmap), %g1              ! IEU1
-       and             %o3, %g2, %o3                   ! IEU0  Group
-       and             %o4, %g2, %o4                   ! IEU1
-       jmpl            %g1 + %lo(sys_mmap), %g0        ! CTI   Group brk forced
-        and            %o5, %g2, %o5                   ! IEU0
+       srl             %o4, 0, %o4
+       sethi           %hi(sys_mmap), %g1
+       jmpl            %g1 + %lo(sys_mmap), %g0
+        srl            %o5, 0, %o5
 
        .align          32
        .globl          sys32_lseek
@@ -36,14 +30,12 @@ sys32_chmod:
        sethi           %hi(0xffff), %g2
        sethi           %hi(sys_chmod), %g1
        orcc            %g2, %lo(0xffff), %g2
-       srl             %o0, 0, %o0
        jmpl            %g1 + %lo(sys_chmod), %g0
         and            %o1, %g2, %o1
 sys32_chown:
        sethi           %hi(0xffff), %g2
        sethi           %hi(sys_chown), %g1
        orcc            %g2, %lo(0xffff), %g2
-       srl             %o0, 0, %o0
        and             %o1, %g2, %o1
        jmpl            %g1 + %lo(sys_chown), %g0
         and            %o2, %g2, %o2
@@ -51,7 +43,6 @@ sys32_lchown:
        sethi           %hi(0xffff), %g2
        sethi           %hi(sys_lchown), %g1
        orcc            %g2, %lo(0xffff), %g2
-       srl             %o0, 0, %o0
        and             %o1, %g2, %o1
        jmpl            %g1 + %lo(sys_lchown), %g0
         and            %o2, %g2, %o2
@@ -59,27 +50,21 @@ sys32_mknod:
        sethi           %hi(0xffff), %g2
        sethi           %hi(sys_mknod), %g1
        orcc            %g2, %lo(0xffff), %g2
-       srl             %o0, 0, %o0
        jmpl            %g1 + %lo(sys_mknod), %g0
         and            %o2, %g2, %o2
 
        .align          32
        .globl          sys32_sendto, sys32_recvfrom, sys32_getsockopt
 sys32_sendto:
-       srl             %o1, 0, %o1
        sethi           %hi(sys_sendto), %g1
-       srl             %o2, 0, %o2
        jmpl            %g1 + %lo(sys_sendto), %g0
         srl            %o4, 0, %o4
 sys32_recvfrom:
-       srl             %o1, 0, %o1
-       sethi           %hi(sys_recvfrom), %g1
-       srl             %o2, 0, %o2
        srl             %o4, 0, %o4
+       sethi           %hi(sys_recvfrom), %g1
        jmpl            %g1 + %lo(sys_recvfrom), %g0
         srl            %o5, 0, %o5
 sys32_getsockopt:
-       srl             %o3, 0, %o3
        sethi           %hi(sys_getsockopt), %g1
        jmpl            %g1 + %lo(sys_getsockopt), %g0
         srl            %o4, 0, %o4
index bca09a5be9a3b158265c95fdb5e629a0b6a37b91..1a49380f17a567ac96f64752346bff4ddb53e836 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.98 1998/10/26 20:01:11 davem Exp $
+/* $Id: sys_sparc32.c,v 1.100 1998/11/08 11:14:00 davem Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -1110,10 +1110,11 @@ asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
 {
        fd_set_buffer *fds;
        struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
-       unsigned long timeout, nn;
+       unsigned long nn;
+       long timeout;
        int ret;
 
-       timeout = ~0UL;
+       timeout = MAX_SCHEDULE_TIMEOUT;
        if (tvp) {
                time_t sec, usec;
 
@@ -1124,8 +1125,6 @@ asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
 
                timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
                timeout += sec * HZ;
-               if (timeout)
-                       timeout += jiffies + 1;
        }
 
        ret = -ENOMEM;
@@ -1147,12 +1146,11 @@ asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
        zero_fd_set(n, fds->res_out);
        zero_fd_set(n, fds->res_ex);
 
-       ret = do_select(n, fds, timeout);
+       ret = do_select(n, fds, &timeout);
 
        if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
-               unsigned long timeout = current->timeout - jiffies - 1;
                time_t sec = 0, usec = 0;
-               if ((long) timeout > 0) {
+               if (timeout) {
                        sec = timeout / HZ;
                        usec = timeout % HZ;
                        usec *= (1000000/HZ);
@@ -1160,7 +1158,6 @@ asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
                put_user(sec, &tvp->tv_sec);
                put_user(usec, &tvp->tv_usec);
        }
-       current->timeout = 0;
 
        if (ret < 0)
                goto out;
@@ -3533,15 +3530,15 @@ extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
 typedef __kernel_ssize_t32 ssize_t32;
 
 asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
-                                __kernel_size_t32 count, u32 pos)
+                                __kernel_size_t32 count, u32 poshi, u32 poslo)
 {
-       return sys_pread(fd, ubuf, count, pos);
+       return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
 asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
-                                 __kernel_size_t32 count, u32 pos)
+                                 __kernel_size_t32 count, u32 poshi, u32 poslo)
 {
-       return sys_pwrite(fd, ubuf, count, pos);
+       return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
 
index a4cf4aa60ec6d19d42c97299e17fea12f012a89d..737872fb276321472bc0dab48b8f4e77d34039c3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.25 1998/10/19 21:52:26 davem Exp $
+/* $Id: fault.c,v 1.26 1998/11/08 11:14:03 davem Exp $
  * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -155,7 +155,8 @@ good_area:
                        goto bad_area;
        }
        current->mm->segments = (void *) (address & PAGE_SIZE);
-       handle_mm_fault(current, vma, address, write);
+       if (!handle_mm_fault(current, vma, address, write))
+               goto do_sigbus;
        up(&mm->mmap_sem);
        return;
        /*
@@ -165,6 +166,7 @@ good_area:
 bad_area:
        up(&mm->mmap_sem);
 
+do_kernel_fault:
        {
                unsigned long g2 = regs->u_regs[UREG_G2];
 
@@ -204,4 +206,13 @@ bad_area:
                }
                unhandled_fault (address, current, regs);
        }
+       return;
+
+do_sigbus:
+       up(&mm->mmap_sem);
+       current->tss.sig_address = address;
+       current->tss.sig_desc = SUBSIG_MISCERROR;
+       force_sig(SIGBUS, current);
+       if (regs->tstate & TSTATE_PRIV)
+               goto do_kernel_fault;
 }
index 730e8cb323aa0b36c52fdccd645ff91f74d3e3cf..0b869a2f2d3502f6371541087d5c66b06907fbba 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: generic.c,v 1.2 1997/07/01 09:11:42 jj Exp $
+/* $Id: generic.c,v 1.3 1998/10/27 23:28:07 davem Exp $
  * generic.c: Generic Sparc mm routines that are not dependent upon
  *            MMU type but are Sparc specific.
  *
@@ -41,10 +41,11 @@ static inline void forget_pte(pte_t page)
                unsigned long addr = pte_page(page);
                if (MAP_NR(addr) >= max_mapnr || PageReserved(mem_map+MAP_NR(addr)))
                        return;
-               free_page(addr);
-               if (current->mm->rss <= 0)
-                       return;
-               current->mm->rss--;
+               /* 
+                * free_page() used to be able to clear swap cache
+                * entries.  We may now have to do it manually.  
+                */
+               free_page_and_swap_cache(addr);
                return;
        }
        swap_free(pte_val(page));
index c836f6200e29d8d55eb072a9c14093a86043f4a4..4362a15b4bf2bb90391bab0e8c798b14e274dd19 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.29 1998/10/22 03:05:51 davem Exp $
+/* $Id: ultra.S,v 1.31 1998/11/07 06:39:21 davem Exp $
  * ultra.S: Don't expand these all over the place...
  *
  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -62,35 +62,37 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
        and             %o4, 0x3ff, %o5
        cmp             %o5, %o0
        bne,pt          %icc, 2f
-        andn           %o4, 0x3ff, %o4
-/*IC6*/        cmp             %o4, %o1
+/*IC6*/         andn           %o4, 0x3ff, %o4
+       cmp             %o4, %o1
        blu,pt          %xcc, 2f
         cmp            %o4, %o3
        blu,pn          %xcc, 4f
 2:      ldxa           [%g2] ASI_DTLB_TAG_READ, %o4
        and             %o4, 0x3ff, %o5
        cmp             %o5, %o0
-       andn            %o4, 0x3ff, %o4
-/*IC7*/        bne,pt          %icc, 3f
+/*IC7*/        andn            %o4, 0x3ff, %o4
+       bne,pt          %icc, 3f
         cmp            %o4, %o1
        blu,pt          %xcc, 3f
         cmp            %o4, %o3
        blu,pn          %xcc, 5f
         nop
 3:     brnz,pt         %g2, 1b
-        sub            %g2, (1 << 3), %g2
-/*IC8*/        retl
+/*IC8*/         sub            %g2, (1 << 3), %g2
+       retl
         wrpr           %g1, 0x0, %pstate
 4:     stxa            %g0, [%g3] ASI_IMMU
        stxa            %g0, [%g2] ASI_ITLB_DATA_ACCESS
        ba,pt           %xcc, 2b
         flush          %g6
 5:     stxa            %g0, [%g3] ASI_DMMU
-       stxa            %g0, [%g2] ASI_DTLB_DATA_ACCESS
+/*IC9*/        stxa            %g0, [%g2] ASI_DTLB_DATA_ACCESS
        ba,pt           %xcc, 3b
         flush          %g6
+
+       .align          32
 __flush_tlb_mm_slow:
-/*IC9*/        rdpr            %pstate, %g1
+/*IC10*/rdpr           %pstate, %g1
        wrpr            %g1, PSTATE_IE, %pstate
        stxa            %o0, [%o1] ASI_DMMU
        stxa            %g0, [%g3] ASI_DMMU_DEMAP
@@ -98,21 +100,25 @@ __flush_tlb_mm_slow:
        flush           %g6
        stxa            %g2, [%o1] ASI_DMMU
        flush           %g6
-/*IC10*/retl
+/*IC11*/retl
         wrpr           %g1, 0, %pstate
+
+       .align          32
 __flush_tlb_page_slow:
-       rdpr            %pstate, %g1
+/*IC12*/rdpr           %pstate, %g1
        wrpr            %g1, PSTATE_IE, %pstate
        stxa            %o0, [%o2] ASI_DMMU
        stxa            %g0, [%g3] ASI_DMMU_DEMAP
        stxa            %g0, [%g3] ASI_IMMU_DEMAP
        flush           %g6
-/*IC11*/stxa           %g2, [%o2] ASI_DMMU
+       stxa            %g2, [%o2] ASI_DMMU
        flush           %g6
-       retl
+/*IC13*/retl
         wrpr           %g1, 0, %pstate
+
+       .align          32
 __flush_tlb_range_pbp_slow:
-       rdpr            %pstate, %g1
+/*IC13*/rdpr           %pstate, %g1
        wrpr            %g1, PSTATE_IE, %pstate
        stxa            %o0, [%o2] ASI_DMMU
 2:     stxa            %g0, [%g5 + %o5] ASI_DMMU_DEMAP
@@ -120,7 +126,7 @@ __flush_tlb_range_pbp_slow:
        brnz,pt         %o5, 2b
         sub            %o5, %o4, %o5
        flush           %g6
-/*IC13*/stxa           %g2, [%o2] ASI_DMMU
+/*IC14*/stxa           %g2, [%o2] ASI_DMMU
        flush           %g6
        retl
         wrpr           %g1, 0x0, %pstate
@@ -128,24 +134,26 @@ __flush_tlb_range_pbp_slow:
        .align          32
        .globl          flush_icache_page
 flush_icache_page:     /* %o0 = phys_page */
-       sethi           %hi(1 << 13), %o2       ! I-cache valid/set bit
+       sethi           %hi(1 << 13), %o2       ! IC_set bit
+       mov             1, %g1
        srlx            %o0, 5, %o0             ! phys-addr comparitor
-       clr             %o1                     ! I-cache address
+       clr             %o1                     ! IC_addr
+       sllx            %g1, 36, %g1
+       sub             %g1, 1, %g2
+       andn            %g2, 0xff, %g2          ! IC_tag mask
+       nop
+
 1:     ldda            [%o1] ASI_IC_TAG, %o4
-       andcc           %o5, %o2, %g0
-       be,pn           %xcc, 2f
-        andn           %o5, %o2, %o5
+       and             %o5, %g2, %o5
        cmp             %o5, %o0
-
        be,pn           %xcc, iflush1
-2:      ldda           [%o1 + %o2] ASI_IC_TAG, %o4
-4:     andcc           %o5, %o2, %g0
-       be,pn           %xcc, 3f
-        andn           %o5, %o2, %o5
+        nop
+2:     ldda            [%o1 + %o2] ASI_IC_TAG, %o4
+       and             %o5, %g2, %o5
        cmp             %o5, %o0
+
        be,pn           %xcc, iflush2
         nop
-
 3:     add             %o1, 0x20, %o1
        cmp             %o1, %o2
        bne,pt          %xcc, 1b
@@ -153,11 +161,11 @@ flush_icache_page:        /* %o0 = phys_page */
        retl
         nop
 iflush1:stxa           %g0, [%o1] ASI_IC_TAG
-       membar          #Sync
-       ba,a,pt         %xcc, 4b
+       ba,pt           %xcc, 2b
+        flush          %g6
 iflush2:stxa           %g0, [%o1 + %o2] ASI_IC_TAG
-       membar          #Sync
-       ba,a,pt         %xcc, 3b
+       ba,pt           %xcc, 3b
+        flush          %g6
 
 #ifdef __SMP__
        /* These are all called by the slaves of a cross call, at
index 57af7507fff524d5ca166b13f0370fbc6a382d48..5e5a6aff842166eeb56eb7d04003452210277089 100644 (file)
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := solaris.o
-O_OBJS   := entry64.o fs.o misc.o signal.o systbl.o ioctl.o ipc.o socksys.o timod.o
+O_OBJS   := entry64.o fs.o misc.o signal.o systbl.o socket.o ioctl.o ipc.o socksys.o timod.o
 ifeq ($(CONFIG_SOLARIS_EMUL),m)
 M_OBJS   := $(O_TARGET)
 CPPFLAGS = $(MODFLAGS)
index 3980f1d6788ade752637aef98d6021d8992c06a2..3631d43b26fd2c405ee4b2500ba141c2d3adaac9 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: fs.c,v 1.10 1998/05/09 06:15:45 davem Exp $
+/* $Id: fs.c,v 1.11 1998/10/28 08:12:04 jj Exp $
  * fs.c: fs related syscall emulation for Solaris
  *
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  */
 
 #include <linux/types.h>
@@ -55,6 +55,26 @@ struct sol_stat {
        s32             st_pad4[8];     /* expansion area */
 };
 
+struct sol_stat64 {
+       u32             st_dev;
+       s32             st_pad1[3];     /* network id */
+       u64             st_ino;
+       u32             st_mode;
+       u32             st_nlink;
+       u32             st_uid;
+       u32             st_gid;
+       u32             st_rdev;
+       s32             st_pad2[2];
+       s64             st_size;
+       timestruct_t    st_atime;
+       timestruct_t    st_mtime;
+       timestruct_t    st_ctime;
+       s64             st_blksize;
+       s32             st_blocks;
+       char            st_fstype[16];
+       s32             st_pad4[4];     /* expansion area */
+};
+
 #define UFSMAGIC (((unsigned)'u'<<24)||((unsigned)'f'<<16)||((unsigned)'s'<<8))
 
 static inline int putstat(struct sol_stat *ubuf, struct stat *kbuf)
@@ -80,6 +100,29 @@ static inline int putstat(struct sol_stat *ubuf, struct stat *kbuf)
        return 0;
 }
 
+static inline int putstat64(struct sol_stat64 *ubuf, struct stat *kbuf)
+{
+       if (put_user (R4_DEV(kbuf->st_dev), &ubuf->st_dev)      ||
+           __put_user (kbuf->st_ino, &ubuf->st_ino)            ||
+           __put_user (kbuf->st_mode, &ubuf->st_mode)          ||
+           __put_user (kbuf->st_nlink, &ubuf->st_nlink)        ||
+           __put_user (kbuf->st_uid, &ubuf->st_uid)            ||
+           __put_user (kbuf->st_gid, &ubuf->st_gid)            ||
+           __put_user (R4_DEV(kbuf->st_rdev), &ubuf->st_rdev)  ||
+           __put_user (kbuf->st_size, &ubuf->st_size)          ||
+           __put_user (kbuf->st_atime, &ubuf->st_atime.tv_sec) ||
+           __put_user (0, &ubuf->st_atime.tv_nsec)             ||
+           __put_user (kbuf->st_mtime, &ubuf->st_mtime.tv_sec) ||
+           __put_user (0, &ubuf->st_mtime.tv_nsec)             ||
+           __put_user (kbuf->st_ctime, &ubuf->st_ctime.tv_sec) ||
+           __put_user (0, &ubuf->st_ctime.tv_nsec)             ||
+           __put_user (kbuf->st_blksize, &ubuf->st_blksize)    ||
+           __put_user (kbuf->st_blocks, &ubuf->st_blocks)      ||
+           __put_user (UFSMAGIC, (unsigned *)ubuf->st_fstype))
+               return -EFAULT;
+       return 0;
+}
+
 asmlinkage int solaris_stat(u32 filename, u32 statbuf)
 {
        int ret;
@@ -108,6 +151,28 @@ asmlinkage int solaris_xstat(int vers, u32 filename, u32 statbuf)
        return solaris_stat(filename, statbuf);
 }
 
+asmlinkage int solaris_stat64(u32 filename, u32 statbuf)
+{
+       int ret;
+       struct stat s;
+       char *filenam;
+       mm_segment_t old_fs = get_fs();
+       int (*sys_newstat)(char *,struct stat *) = 
+               (int (*)(char *,struct stat *))SYS(stat);
+       
+       filenam = getname32 (filename);
+       ret = PTR_ERR(filenam);
+       if (!IS_ERR(filenam)) {
+               set_fs (KERNEL_DS);
+               ret = sys_newstat(filenam, &s);
+               set_fs (old_fs);
+               putname32 (filenam);
+               if (putstat64 ((struct sol_stat64 *)A(statbuf), &s))
+                       return -EFAULT;
+       }
+       return ret;
+}
+
 asmlinkage int solaris_lstat(u32 filename, u32 statbuf)
 {
        int ret;
@@ -135,6 +200,28 @@ asmlinkage int solaris_lxstat(int vers, u32 filename, u32 statbuf)
        return solaris_lstat(filename, statbuf);
 }
 
+asmlinkage int solaris_lstat64(u32 filename, u32 statbuf)
+{
+       int ret;
+       struct stat s;
+       char *filenam;
+       mm_segment_t old_fs = get_fs();
+       int (*sys_newlstat)(char *,struct stat *) = 
+               (int (*)(char *,struct stat *))SYS(lstat);
+       
+       filenam = getname32 (filename);
+       ret = PTR_ERR(filenam);
+       if (!IS_ERR(filenam)) {
+               set_fs (KERNEL_DS);
+               ret = sys_newlstat(filenam, &s);
+               set_fs (old_fs);
+               putname32 (filenam);
+               if (putstat64 ((struct sol_stat64 *)A(statbuf), &s))
+                       return -EFAULT;
+       }
+       return ret;
+}
+
 asmlinkage int solaris_fstat(unsigned int fd, u32 statbuf)
 {
        int ret;
@@ -156,6 +243,22 @@ asmlinkage int solaris_fxstat(int vers, u32 fd, u32 statbuf)
        return solaris_fstat(fd, statbuf);
 }
 
+asmlinkage int solaris_fstat64(unsigned int fd, u32 statbuf)
+{
+       int ret;
+       struct stat s;
+       mm_segment_t old_fs = get_fs();
+       int (*sys_newfstat)(unsigned,struct stat *) = 
+               (int (*)(unsigned,struct stat *))SYS(fstat);
+       
+       set_fs (KERNEL_DS);
+       ret = sys_newfstat(fd, &s);
+       set_fs (old_fs);
+       if (putstat64 ((struct sol_stat64 *)A(statbuf), &s))
+               return -EFAULT;
+       return ret;
+}
+
 asmlinkage int solaris_mknod(u32 path, u32 mode, s32 dev)
 {
        int (*sys_mknod)(const char *,int,dev_t) = 
@@ -172,6 +275,14 @@ asmlinkage int solaris_xmknod(int vers, u32 path, u32 mode, s32 dev)
        return solaris_mknod(path, mode, dev);
 }
 
+asmlinkage int solaris_getdents64(unsigned int fd, void *dirent, unsigned int count)
+{
+       int (*sys_getdents)(unsigned int, void *, unsigned int) =
+               (int (*)(unsigned int, void *, unsigned int))SYS(getdents);
+               
+       return sys_getdents(fd, dirent, count);
+}
+
 /* This statfs thingie probably will go in the near future, but... */
 
 struct sol_statfs {
@@ -276,6 +387,23 @@ struct sol_statvfs {
        u32     f_filler[16];
 };
 
+struct sol_statvfs64 {
+       u32     f_bsize;
+       u32     f_frsize;
+       u64     f_blocks;
+       u64     f_bfree;
+       u64     f_bavail;
+       u64     f_files;
+       u64     f_ffree;
+       u64     f_favail;
+       u32     f_fsid;
+       char    f_basetype[16];
+       u32     f_flag;
+       u32     f_namemax;
+       char    f_fstr[32];
+       u32     f_filler[16];
+};
+
 static int report_statvfs(struct inode *inode, u32 buf)
 {
        struct statfs s;
@@ -313,6 +441,43 @@ static int report_statvfs(struct inode *inode, u32 buf)
        return error;
 }
 
+static int report_statvfs64(struct inode *inode, u32 buf)
+{
+       struct statfs s;
+       mm_segment_t old_fs = get_fs();
+       int error;
+       struct sol_statvfs64 *ss = (struct sol_statvfs64 *)A(buf);
+                       
+       set_fs (KERNEL_DS);
+       error = inode->i_sb->s_op->statfs(inode->i_sb, &s, sizeof(struct statfs));
+       set_fs (old_fs);
+       if (!error) {
+               const char *p = inode->i_sb->s_type->name;
+               int i = 0;
+               int j = strlen (p);
+               
+               if (j > 15) j = 15;
+               if (IS_RDONLY(inode)) i = 1;
+               if (IS_NOSUID(inode)) i |= 2;
+               if (put_user (s.f_bsize, &ss->f_bsize)          ||
+                   __put_user (0, &ss->f_frsize)               ||
+                   __put_user (s.f_blocks, &ss->f_blocks)      ||
+                   __put_user (s.f_bfree, &ss->f_bfree)        ||
+                   __put_user (s.f_bavail, &ss->f_bavail)      ||
+                   __put_user (s.f_files, &ss->f_files)        ||
+                   __put_user (s.f_ffree, &ss->f_ffree)        ||
+                   __put_user (s.f_ffree, &ss->f_favail)       ||
+                   __put_user (R4_DEV(inode->i_sb->s_dev), &ss->f_fsid) ||
+                   __copy_to_user (ss->f_basetype,p,j)         ||
+                   __put_user (0, (char *)&ss->f_basetype[j])  ||
+                   __put_user (s.f_namelen, &ss->f_namemax)    ||
+                   __put_user (i, &ss->f_flag)                 ||                  
+                   __clear_user (&ss->f_fstr, 32))
+                       return -EFAULT;
+       }
+       return error;
+}
+
 asmlinkage int solaris_statvfs(u32 path, u32 buf)
 {
        struct dentry * dentry;
@@ -362,12 +527,62 @@ out:
        return error;
 }
 
+asmlinkage int solaris_statvfs64(u32 path, u32 buf)
+{
+       struct dentry * dentry;
+       int error;
+
+       lock_kernel();
+       dentry = namei((const char *)A(path));
+       error = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
+               struct inode * inode = dentry->d_inode;
+
+               error = -ENOSYS;
+               if (inode->i_sb->s_op->statfs)
+                       error = report_statvfs64(inode, buf);
+               dput(dentry);
+       }
+       unlock_kernel();
+       return error;
+}
+
+asmlinkage int solaris_fstatvfs64(unsigned int fd, u32 buf)
+{
+       struct inode * inode;
+       struct dentry * dentry;
+       struct file * file;
+       int error;
+
+       lock_kernel();
+       error = -EBADF;
+       file = fget(fd);
+       if (!file)
+               goto out;
+
+       if (!(dentry = file->f_dentry))
+               error = -ENOENT;
+       else if (!(inode = dentry->d_inode))
+               error = -ENOENT;
+       else if (!inode->i_sb)
+               error = -ENODEV;
+       else if (!inode->i_sb->s_op->statfs)
+               error = -ENOSYS;
+       else
+               error = report_statvfs64(inode, buf);
+       fput(file);
+out:
+       unlock_kernel();
+       return error;
+}
+
 asmlinkage int solaris_open(u32 filename, int flags, u32 mode)
 {
        int (*sys_open)(const char *,int,int) = 
                (int (*)(const char *,int,int))SYS(open);
        int fl = flags & 0xf;
-       
+
+/*     if (flags & 0x2000) - allow LFS                 */
        if (flags & 0x8050) fl |= O_SYNC;
        if (flags & 0x80) fl |= O_NONBLOCK;
        if (flags & 0x100) fl |= O_CREAT;
@@ -558,78 +773,20 @@ asmlinkage int solaris_facl(unsigned int fd, int cmd, int nentries, u32 aclbufp)
        return -ENOSYS;
 }
 
-asmlinkage int solaris_pread(int fd, u32 buf, u32 nbyte, s32 offset)
+asmlinkage int solaris_pread(unsigned int fd, char *buf, u32 count, u32 pos)
 {
-       off_t temp;
-       int retval;
-       struct file * file;
-       long (*sys_read)(unsigned int, char *, unsigned long) =
-               (long (*)(unsigned int, char *, unsigned long))SYS(read);
-       long (*sys_lseek)(unsigned int, off_t, unsigned int) =
-               (long (*)(unsigned int, off_t, unsigned int))SYS(lseek);
-       
-       lock_kernel();
-       retval = -EBADF;
-       file = fget(fd);
-       if (!file)
-               goto bad;
-
-       temp = file->f_pos;
-       if (temp != offset) {
-               retval = sys_lseek(fd, offset, 0);
-               if (retval < 0)
-                       goto out_putf;
-       }
-       retval = sys_read(fd, (char *)A(buf), nbyte);
-       if (file->f_pos != temp) {
-               if (!retval)
-                       retval = sys_lseek(fd, temp, 0);
-               else
-                       sys_lseek(fd, temp, 0);
-       }
-
-out_putf:
-       fput(file);
-bad:
-       unlock_kernel();
-       return retval;
+       ssize_t (*sys_pread)(unsigned int, char *, size_t, loff_t) =
+               (ssize_t (*)(unsigned int, char *, size_t, loff_t))SYS(pread);
+               
+       return sys_pread(fd, buf, count, (loff_t)pos);
 }
 
-asmlinkage int solaris_pwrite(int fd, u32 buf, u32 nbyte, s32 offset)
+asmlinkage int solaris_pwrite(unsigned int fd, char *buf, u32 count, u32 pos)
 {
-       off_t temp;
-       int retval;
-       struct file * file;
-       long (*sys_write)(unsigned int, char *, unsigned long) =
-               (long (*)(unsigned int, char *, unsigned long))SYS(read);
-       long (*sys_lseek)(unsigned int, off_t, unsigned int) =
-               (long (*)(unsigned int, off_t, unsigned int))SYS(lseek);
-       
-       lock_kernel();
-       retval = -EBADF;
-        file = fget(fd);
-       if (!file)
-               goto bad;
-
-       temp = file->f_pos;
-       if (temp != offset) {
-               retval = sys_lseek(fd, offset, 0);
-               if (retval < 0)
-                       goto out_putf;
-       }
-       retval = sys_write(fd, (char *)A(buf), nbyte);
-       if (file->f_pos != temp) {
-               if (!retval)
-                       retval = sys_lseek(fd, temp, 0);
-               else
-                       sys_lseek(fd, temp, 0);
-       }
-
-out_putf:
-       fput(file);
-bad:
-       unlock_kernel();
-       return retval;
+       ssize_t (*sys_pwrite)(unsigned int, char *, size_t, loff_t) =
+               (ssize_t (*)(unsigned int, char *, size_t, loff_t))SYS(pwrite);
+               
+       return sys_pwrite(fd, buf, count, (loff_t)pos);
 }
 
 /* POSIX.1 names */
index 8e0ce81daa285e2c989a4e3e65af6a48fff0e945..c29b79f6857ce2c8b4b7ed32f11c96390afc1a34 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: misc.c,v 1.12 1998/06/16 04:37:08 davem Exp $
+/* $Id: misc.c,v 1.13 1998/10/28 08:11:58 jj Exp $
  * misc.c: Miscelaneous syscall emulation for Solaris
  *
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  */
 
 #include <linux/module.h> 
@@ -11,6 +11,9 @@
 #include <linux/limits.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/timex.h>
 
 #include <asm/uaccess.h>
 #include <asm/string.h>
@@ -43,16 +46,86 @@ int solaris_err_table[] = {
 /* 120 */ 22, 22, 88, 86, 85, 22, 22,
 };
 
+#define SOLARIS_NR_OPEN        256
+
+static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 off)
+{
+       struct file *file = NULL;
+       unsigned long retval, ret_type;
+
+       lock_kernel();
+       current->personality |= PER_SVR4;
+       if (flags & MAP_NORESERVE) {
+               static int cnt = 0;
+               
+               if (cnt < 5) {
+                       printk("%s:  unimplemented Solaris MAP_NORESERVE mmap() flag\n",
+                              current->comm);
+                       cnt++;
+               }
+               flags &= ~MAP_NORESERVE;
+       }
+       retval = -EBADF;
+       if(!(flags & MAP_ANONYMOUS)) {
+               if(fd >= SOLARIS_NR_OPEN)
+                       goto out;
+               file = fget(fd);
+               if (!file)
+                       goto out;
+               if (file->f_dentry && file->f_dentry->d_inode) {
+                       struct inode * inode = file->f_dentry->d_inode;
+                       if(MAJOR(inode->i_rdev) == MEM_MAJOR &&
+                          MINOR(inode->i_rdev) == 5) {
+                               flags |= MAP_ANONYMOUS;
+                               fput(file);
+                               file = NULL;
+                       }
+               }
+       }
+
+       retval = -ENOMEM;
+       if(!(flags & MAP_FIXED) && !addr) {
+               unsigned long attempt = get_unmapped_area(addr, len);
+               if(!attempt || (attempt >= 0xf0000000UL))
+                       goto out_putf;
+               addr = (u32) attempt;
+       }
+       if(!(flags & MAP_FIXED))
+               addr = 0;
+       ret_type = flags & _MAP_NEW;
+       flags &= ~_MAP_NEW;
+
+       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+       retval = do_mmap(file,
+                        (unsigned long) addr, (unsigned long) len,
+                        (unsigned long) prot, (unsigned long) flags, off);
+       if(!ret_type)
+               retval = ((retval < 0xf0000000) ? 0 : retval);
+out_putf:
+       if (file)
+               fput(file);
+out:
+       unlock_kernel();
+       return (u32) retval;
+}
+
 asmlinkage u32 solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off)
 {
-       u32 (*sunos_mmap)(u32,u32,u32,u32,u32,u32) = 
-               (u32 (*)(u32,u32,u32,u32,u32,u32))SUNOS(71);
-       u32 ret;
+       return do_solaris_mmap(addr, len, prot, flags, fd, (u64) off);
+}
+
+asmlinkage u32 solaris_mmap64(struct pt_regs *regs, u32 len, u32 prot, u32 flags, u32 fd, u32 offhi)
+{
+       u32 offlo;
        
-       ret = sunos_mmap(addr,len,prot,flags,fd,off);
-       /* sunos_mmap sets personality to PER_BSD */
-       current->personality = PER_SVR4;
-       return ret;
+       if (regs->u_regs[UREG_G1]) {
+               if (get_user (offlo, (u32 *)(long)((u32)regs->u_regs[UREG_I6] + 0x5c)))
+                       return -EFAULT;
+       } else {
+               if (get_user (offlo, (u32 *)(long)((u32)regs->u_regs[UREG_I6] + 0x60)))
+                       return -EFAULT;
+       }
+       return do_solaris_mmap((u32)regs->u_regs[UREG_I0], len, prot, flags, fd, (((u64)offhi)<<32)|offlo);
 }
 
 asmlinkage int solaris_brk(u32 brk)
@@ -326,6 +399,18 @@ asmlinkage int solaris_sysconf(int id)
        }
 }
 
+asmlinkage int solaris_setreuid(s32 ruid, s32 euid)
+{
+       int (*sys_setreuid)(uid_t, uid_t) = (int (*)(uid_t, uid_t))SYS(setreuid);
+       return sys_setreuid(ruid, euid);
+}
+
+asmlinkage int solaris_setregid(s32 rgid, s32 egid)
+{
+       int (*sys_setregid)(gid_t, gid_t) = (int (*)(gid_t, gid_t))SYS(setregid);
+       return sys_setregid(rgid, egid);
+}
+
 asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
 {
        int ret;
@@ -378,6 +463,257 @@ asmlinkage int solaris_gettimeofday(u32 tim)
        return sys_gettimeofday((struct timeval *)(u64)tim, NULL);
 }
 
+#define RLIM_SOL_INFINITY32    0x7fffffff
+#define RLIM_SOL_SAVED_MAX32   0x7ffffffe
+#define RLIM_SOL_SAVED_CUR32   0x7ffffffd
+#define RLIM_SOL_INFINITY      ((u64)-3)
+#define RLIM_SOL_SAVED_MAX     ((u64)-2)
+#define RLIM_SOL_SAVED_CUR     ((u64)-1)
+#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
+#define RLIMIT_SOL_NOFILE      5
+#define RLIMIT_SOL_VMEM                6
+
+struct rlimit32 {
+       s32     rlim_cur;
+       s32     rlim_max;
+};
+
+asmlinkage int solaris_getrlimit(unsigned int resource, struct rlimit32 *rlim)
+{
+       struct rlimit r;
+       int ret;
+       mm_segment_t old_fs = get_fs ();
+       int (*sys_getrlimit)(unsigned int, struct rlimit *) =
+               (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
+
+       if (resource > RLIMIT_SOL_VMEM)
+               return -EINVAL; 
+       switch (resource) {
+       case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
+       case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
+       default: break;
+       }
+       set_fs (KERNEL_DS);
+       ret = sys_getrlimit(resource, &r);
+       set_fs (old_fs);
+       if (!ret) {
+               if (r.rlim_cur == RLIM_INFINITY)
+                       r.rlim_cur = RLIM_SOL_INFINITY32;
+               else if ((u64)r.rlim_cur > RLIM_SOL_INFINITY32)
+                       r.rlim_cur = RLIM_SOL_SAVED_CUR32;
+               if (r.rlim_max == RLIM_INFINITY)
+                       r.rlim_max = RLIM_SOL_INFINITY32;
+               else if ((u64)r.rlim_max > RLIM_SOL_INFINITY32)
+                       r.rlim_max = RLIM_SOL_SAVED_MAX32;
+               ret = put_user (r.rlim_cur, &rlim->rlim_cur);
+               ret |= __put_user (r.rlim_max, &rlim->rlim_max);
+       }
+       return ret;
+}
+
+asmlinkage int solaris_setrlimit(unsigned int resource, struct rlimit32 *rlim)
+{
+       struct rlimit r, rold;
+       int ret;
+       mm_segment_t old_fs = get_fs ();
+       int (*sys_getrlimit)(unsigned int, struct rlimit *) =
+               (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
+       int (*sys_setrlimit)(unsigned int, struct rlimit *) =
+               (int (*)(unsigned int, struct rlimit *))SYS(setrlimit);
+
+       if (resource > RLIMIT_SOL_VMEM)
+               return -EINVAL; 
+       switch (resource) {
+       case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
+       case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
+       default: break;
+       }
+       if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
+           __get_user (r.rlim_max, &rlim->rlim_max))
+               return -EFAULT;
+       set_fs (KERNEL_DS);
+       ret = sys_getrlimit(resource, &rold);
+       if (!ret) {
+               if (r.rlim_cur == RLIM_SOL_INFINITY32)
+                       r.rlim_cur = RLIM_INFINITY;
+               else if (r.rlim_cur == RLIM_SOL_SAVED_CUR32)
+                       r.rlim_cur = rold.rlim_cur;
+               else if (r.rlim_cur == RLIM_SOL_SAVED_MAX32)
+                       r.rlim_cur = rold.rlim_max;
+               if (r.rlim_max == RLIM_SOL_INFINITY32)
+                       r.rlim_max = RLIM_INFINITY;
+               else if (r.rlim_max == RLIM_SOL_SAVED_CUR32)
+                       r.rlim_max = rold.rlim_cur;
+               else if (r.rlim_max == RLIM_SOL_SAVED_MAX32)
+                       r.rlim_max = rold.rlim_max;
+               ret = sys_setrlimit(resource, &r);
+       }
+       set_fs (old_fs);
+       return ret;
+}
+
+asmlinkage int solaris_getrlimit64(unsigned int resource, struct rlimit *rlim)
+{
+       struct rlimit r;
+       int ret;
+       mm_segment_t old_fs = get_fs ();
+       int (*sys_getrlimit)(unsigned int, struct rlimit *) =
+               (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
+
+       if (resource > RLIMIT_SOL_VMEM)
+               return -EINVAL; 
+       switch (resource) {
+       case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
+       case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
+       default: break;
+       }
+       set_fs (KERNEL_DS);
+       ret = sys_getrlimit(resource, &r);
+       set_fs (old_fs);
+       if (!ret) {
+               if (r.rlim_cur == RLIM_INFINITY)
+                       r.rlim_cur = RLIM_SOL_INFINITY;
+               if (r.rlim_max == RLIM_INFINITY)
+                       r.rlim_max = RLIM_SOL_INFINITY;
+               ret = put_user (r.rlim_cur, &rlim->rlim_cur);
+               ret |= __put_user (r.rlim_max, &rlim->rlim_max);
+       }
+       return ret;
+}
+
+asmlinkage int solaris_setrlimit64(unsigned int resource, struct rlimit *rlim)
+{
+       struct rlimit r, rold;
+       int ret;
+       mm_segment_t old_fs = get_fs ();
+       int (*sys_getrlimit)(unsigned int, struct rlimit *) =
+               (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
+       int (*sys_setrlimit)(unsigned int, struct rlimit *) =
+               (int (*)(unsigned int, struct rlimit *))SYS(setrlimit);
+
+       if (resource > RLIMIT_SOL_VMEM)
+               return -EINVAL; 
+       switch (resource) {
+       case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
+       case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
+       default: break;
+       }
+       if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
+           __get_user (r.rlim_max, &rlim->rlim_max))
+               return -EFAULT;
+       set_fs (KERNEL_DS);
+       ret = sys_getrlimit(resource, &rold);
+       if (!ret) {
+               if (r.rlim_cur == RLIM_SOL_INFINITY)
+                       r.rlim_cur = RLIM_INFINITY;
+               else if (r.rlim_cur == RLIM_SOL_SAVED_CUR)
+                       r.rlim_cur = rold.rlim_cur;
+               else if (r.rlim_cur == RLIM_SOL_SAVED_MAX)
+                       r.rlim_cur = rold.rlim_max;
+               if (r.rlim_max == RLIM_SOL_INFINITY)
+                       r.rlim_max = RLIM_INFINITY;
+               else if (r.rlim_max == RLIM_SOL_SAVED_CUR)
+                       r.rlim_max = rold.rlim_cur;
+               else if (r.rlim_max == RLIM_SOL_SAVED_MAX)
+                       r.rlim_max = rold.rlim_max;
+               ret = sys_setrlimit(resource, &r);
+       }
+       set_fs (old_fs);
+       return ret;
+}
+
+struct timeval32 {
+       int tv_sec, tv_usec;
+};
+
+struct sol_ntptimeval {
+       struct timeval32 time;
+       s32 maxerror;
+       s32 esterror;
+};
+
+struct sol_timex {
+       u32 modes;
+       s32 offset;
+       s32 freq;
+       s32 maxerror;
+       s32 esterror;
+       s32 status;
+       s32 constant;
+       s32 precision;
+       s32 tolerance;
+       s32 ppsfreq;
+       s32 jitter;
+       s32 shift;
+       s32 stabil;
+       s32 jitcnt;
+       s32 calcnt;
+       s32 errcnt;
+       s32 stbcnt;
+};
+
+asmlinkage int solaris_ntp_gettime(struct sol_ntptimeval *ntp)
+{
+       int (*sys_adjtimex)(struct timex *) =
+               (int (*)(struct timex *))SYS(adjtimex);
+       struct timex t;
+       int ret;
+       mm_segment_t old_fs = get_fs();
+       
+       set_fs(KERNEL_DS);
+       t.modes = 0;
+       ret = sys_adjtimex(&t);
+       set_fs(old_fs);
+       if (ret < 0)
+               return ret;
+       ret = put_user (t.time.tv_sec, &ntp->time.tv_sec);
+       ret |= __put_user (t.time.tv_usec, &ntp->time.tv_usec);
+       ret |= __put_user (t.maxerror, &ntp->maxerror);
+       ret |= __put_user (t.esterror, &ntp->esterror);
+       return ret;                             
+}
+
+asmlinkage int solaris_ntp_adjtime(struct sol_timex *txp)
+{
+       int (*sys_adjtimex)(struct timex *) =
+               (int (*)(struct timex *))SYS(adjtimex);
+       struct timex t;
+       int ret, err;
+       mm_segment_t old_fs = get_fs();
+
+       ret = get_user (t.modes, &txp->modes);
+       ret |= __get_user (t.offset, &txp->offset);
+       ret |= __get_user (t.freq, &txp->freq);
+       ret |= __get_user (t.maxerror, &txp->maxerror);
+       ret |= __get_user (t.esterror, &txp->esterror);
+       ret |= __get_user (t.status, &txp->status);
+       ret |= __get_user (t.constant, &txp->constant);
+       set_fs(KERNEL_DS);
+       ret = sys_adjtimex(&t);
+       set_fs(old_fs);
+       if (ret < 0)
+               return ret;
+       err = put_user (t.offset, &txp->offset);
+       err |= __put_user (t.freq, &txp->freq);
+       err |= __put_user (t.maxerror, &txp->maxerror);
+       err |= __put_user (t.esterror, &txp->esterror);
+       err |= __put_user (t.status, &txp->status);
+       err |= __put_user (t.constant, &txp->constant);
+       err |= __put_user (t.precision, &txp->precision);
+       err |= __put_user (t.tolerance, &txp->tolerance);
+       err |= __put_user (t.ppsfreq, &txp->ppsfreq);
+       err |= __put_user (t.jitter, &txp->jitter);
+       err |= __put_user (t.shift, &txp->shift);
+       err |= __put_user (t.stabil, &txp->stabil);
+       err |= __put_user (t.jitcnt, &txp->jitcnt);
+       err |= __put_user (t.calcnt, &txp->calcnt);
+       err |= __put_user (t.errcnt, &txp->errcnt);
+       err |= __put_user (t.stbcnt, &txp->stbcnt);
+       if (err)
+               return -EFAULT;
+       return ret;
+}
+
 asmlinkage int do_sol_unimplemented(struct pt_regs *regs)
 {
        printk ("Unimplemented Solaris syscall %d %08x %08x %08x %08x\n", 
diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c
new file mode 100644 (file)
index 0000000..4b3f18f
--- /dev/null
@@ -0,0 +1,463 @@
+/* $Id: socket.c,v 1.1 1998/10/28 08:12:11 jj Exp $
+ * socket.c: Socket syscall emulation for Solaris 2.6+
+ *
+ * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
+ */
+
+#include <linux/types.h>
+#include <linux/smp_lock.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/socket.h>
+#include <linux/file.h>
+
+#include <asm/uaccess.h>
+#include <asm/string.h>
+#include <asm/oplib.h>
+#include <asm/idprom.h>
+#include <asm/machines.h>
+
+#include "conv.h"
+
+#define SOCK_SOL_STREAM                2
+#define SOCK_SOL_DGRAM         1
+#define SOCK_SOL_RAW           4
+#define SOCK_SOL_RDM           5
+#define SOCK_SOL_SEQPACKET     6
+
+static int socket_check(int family, int type)
+{
+       if (family != PF_UNIX && family != PF_INET)
+               return -ESOCKTNOSUPPORT;
+       switch (type) {
+       case SOCK_SOL_STREAM: type = SOCK_STREAM; break;
+       case SOCK_SOL_DGRAM: type = SOCK_DGRAM; break;
+       case SOCK_SOL_RAW: type = SOCK_RAW; break;
+       case SOCK_SOL_RDM: type = SOCK_RDM; break;
+       case SOCK_SOL_SEQPACKET: type = SOCK_SEQPACKET; break;
+       default: return -EINVAL;
+       }
+       return type;
+}
+
+asmlinkage int solaris_socket(int family, int type, int protocol)
+{
+       int (*sys_socket)(int, int, int) =
+               (int (*)(int, int, int))SYS(socket);
+
+       type = socket_check (family, type);
+       if (type < 0) return type;
+       return sys_socket(family, type, protocol);
+}
+
+asmlinkage int solaris_socketpair(int family, int type, int protocol, int *usockvec)
+{
+       int (*sys_socketpair)(int, int, int, int *) =
+               (int (*)(int, int, int, int *))SYS(socketpair);
+
+       type = socket_check (family, type);
+       if (type < 0) return type;
+       return sys_socketpair(family, type, protocol, usockvec);
+}
+
+asmlinkage int solaris_bind(int fd, struct sockaddr *addr, int addrlen)
+{
+       int (*sys_bind)(int, struct sockaddr *, int) =
+               (int (*)(int, struct sockaddr *, int))SUNOS(104);
+
+       return sys_bind(fd, addr, addrlen);
+}
+
+asmlinkage int solaris_setsockopt(int fd, int level, int optname, u32 optval, int optlen)
+{
+       int (*sunos_setsockopt)(int, int, int, u32, int) =
+               (int (*)(int, int, int, u32, int))SUNOS(105);
+
+       return sunos_setsockopt(fd, level, optname, optval, optlen);
+}
+
+asmlinkage int solaris_getsockopt(int fd, int level, int optname, u32 optval, u32 optlen)
+{
+       int (*sunos_getsockopt)(int, int, int, u32, u32) =
+               (int (*)(int, int, int, u32, u32))SUNOS(118);
+
+       return sunos_getsockopt(fd, level, optname, optval, optlen);
+}
+
+asmlinkage int solaris_connect(int fd, struct sockaddr *addr, int addrlen)
+{
+       int (*sys_connect)(int, struct sockaddr *, int) =
+               (int (*)(int, struct sockaddr *, int))SYS(connect);
+
+       return sys_connect(fd, addr, addrlen);
+}
+
+asmlinkage int solaris_accept(int fd, struct sockaddr *addr, int *addrlen)
+{
+       int (*sys_accept)(int, struct sockaddr *, int *) =
+               (int (*)(int, struct sockaddr *, int *))SYS(accept);
+
+       return sys_accept(fd, addr, addrlen);
+}
+
+asmlinkage int solaris_listen(int fd, int backlog)
+{
+       int (*sys_listen)(int, int) =
+               (int (*)(int, int))SUNOS(106);
+
+       return sys_listen(fd, backlog);
+}
+
+asmlinkage int solaris_shutdown(int fd, int how)
+{
+       int (*sys_shutdown)(int, int) =
+               (int (*)(int, int))SYS(shutdown);
+
+       return sys_shutdown(fd, how);
+}
+
+#define MSG_SOL_OOB            0x1
+#define MSG_SOL_PEEK           0x2
+#define MSG_SOL_DONTROUTE      0x4
+#define MSG_SOL_EOR            0x8
+#define MSG_SOL_CTRUNC         0x10
+#define MSG_SOL_TRUNC          0x20
+#define MSG_SOL_WAITALL                0x40
+#define MSG_SOL_DONTWAIT       0x80
+
+static int solaris_to_linux_msgflags(int flags)
+{
+       int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE);
+       
+       if (flags & MSG_SOL_EOR) fl |= MSG_EOR;
+       if (flags & MSG_SOL_CTRUNC) fl |= MSG_CTRUNC;
+       if (flags & MSG_SOL_TRUNC) fl |= MSG_TRUNC;
+       if (flags & MSG_SOL_WAITALL) fl |= MSG_WAITALL;
+       if (flags & MSG_SOL_DONTWAIT) fl |= MSG_DONTWAIT;
+       return fl;
+}
+
+static int linux_to_solaris_msgflags(int flags)
+{
+       int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE);
+       
+       if (flags & MSG_EOR) fl |= MSG_SOL_EOR;
+       if (flags & MSG_CTRUNC) fl |= MSG_SOL_CTRUNC;
+       if (flags & MSG_TRUNC) fl |= MSG_SOL_TRUNC;
+       if (flags & MSG_WAITALL) fl |= MSG_SOL_WAITALL;
+       if (flags & MSG_DONTWAIT) fl |= MSG_SOL_DONTWAIT;
+       return fl;
+}
+
+asmlinkage int solaris_recvfrom(int s, char *buf, int len, int flags, u32 from, u32 fromlen)
+{
+       int (*sys_recvfrom)(int, void *, size_t, unsigned, struct sockaddr *, int *) =
+               (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int *))SYS(recvfrom);
+       
+       return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), (struct sockaddr *)A(from), (int *)A(fromlen));
+}
+
+asmlinkage int solaris_recv(int s, char *buf, int len, int flags)
+{
+       int (*sys_recvfrom)(int, void *, size_t, unsigned, struct sockaddr *, int *) =
+               (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int *))SYS(recvfrom);
+       
+       return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), NULL, NULL);
+}
+
+asmlinkage int solaris_sendto(int s, char *buf, int len, int flags, u32 to, u32 tolen)
+{
+       int (*sys_sendto)(int, void *, size_t, unsigned, struct sockaddr *, int *) =
+               (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int *))SYS(sendto);
+       
+       return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), (struct sockaddr *)A(to), (int *)A(tolen));
+}
+
+asmlinkage int solaris_send(int s, char *buf, int len, int flags)
+{
+       int (*sys_sendto)(int, void *, size_t, unsigned, struct sockaddr *, int *) =
+               (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int *))SYS(sendto);
+       
+       return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), NULL, NULL);
+}
+
+asmlinkage int solaris_getpeername(int fd, struct sockaddr *addr, int *addrlen)
+{
+       int (*sys_getpeername)(int, struct sockaddr *, int *) =
+               (int (*)(int, struct sockaddr *, int *))SYS(getpeername);
+
+       return sys_getpeername(fd, addr, addrlen);
+}
+
+asmlinkage int solaris_getsockname(int fd, struct sockaddr *addr, int *addrlen)
+{
+       int (*sys_getsockname)(int, struct sockaddr *, int *) =
+               (int (*)(int, struct sockaddr *, int *))SYS(getsockname);
+
+       return sys_getsockname(fd, addr, addrlen);
+}
+
+/* XXX This really belongs in some header file... -DaveM */
+#define MAX_SOCK_ADDR  128             /* 108 for Unix domain - 
+                                          16 for IP, 16 for IPX,
+                                          24 for IPv6,
+                                          about 80 for AX.25 */
+
+/* XXX These as well... */
+extern __inline__ struct socket *socki_lookup(struct inode *inode)
+{
+       return &inode->u.socket_i;
+}
+
+extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
+{
+       struct file *file;
+       struct inode *inode;
+
+       if (!(file = fget(fd))) {
+               *err = -EBADF;
+               return NULL;
+       }
+
+       inode = file->f_dentry->d_inode;
+       if (!inode || !inode->i_sock || !socki_lookup(inode)) {
+               *err = -ENOTSOCK;
+               fput(file);
+               return NULL;
+       }
+
+       return socki_lookup(inode);
+}
+
+extern __inline__ void sockfd_put(struct socket *sock)
+{
+       fput(sock->file);
+}
+
+struct sol_nmsghdr {
+       u32             msg_name;
+       int             msg_namelen;
+       u32             msg_iov;
+       u32             msg_iovlen;
+       u32             msg_control;
+       u32             msg_controllen;
+       u32             msg_flags;
+};
+
+struct sol_cmsghdr {
+       u32             cmsg_len;
+       int             cmsg_level;
+       int             cmsg_type;
+       unsigned char   cmsg_data[0];
+};
+
+struct iovec32 {
+       u32             iov_base;
+       u32 iov_len;
+};
+
+static inline int iov_from_user32_to_kern(struct iovec *kiov,
+                                         struct iovec32 *uiov32,
+                                         int niov)
+{
+       int tot_len = 0;
+
+       while(niov > 0) {
+               u32 len, buf;
+
+               if(get_user(len, &uiov32->iov_len) ||
+                  get_user(buf, &uiov32->iov_base)) {
+                       tot_len = -EFAULT;
+                       break;
+               }
+               tot_len += len;
+               kiov->iov_base = (void *)A(buf);
+               kiov->iov_len = (__kernel_size_t) len;
+               uiov32++;
+               kiov++;
+               niov--;
+       }
+       return tot_len;
+}
+
+static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
+                                            struct sol_nmsghdr *umsg)
+{
+       u32 tmp1, tmp2, tmp3;
+       int err;
+
+       err = get_user(tmp1, &umsg->msg_name);
+       err |= __get_user(tmp2, &umsg->msg_iov);
+       err |= __get_user(tmp3, &umsg->msg_control);
+       if (err)
+               return -EFAULT;
+
+       kmsg->msg_name = (void *)A(tmp1);
+       kmsg->msg_iov = (struct iovec *)A(tmp2);
+       kmsg->msg_control = (void *)A(tmp3);
+
+       err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
+       err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
+       err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
+       
+       kmsg->msg_flags = solaris_to_linux_msgflags(kmsg->msg_flags);
+       
+       return err;
+}
+
+/* I've named the args so it is easy to tell whose space the pointers are in. */
+static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
+                         char *kern_address, int mode)
+{
+       int tot_len;
+
+       if(kern_msg->msg_namelen) {
+               if(mode==VERIFY_READ) {
+                       int err = move_addr_to_kernel(kern_msg->msg_name,
+                                                     kern_msg->msg_namelen,
+                                                     kern_address);
+                       if(err < 0)
+                               return err;
+               }
+               kern_msg->msg_name = kern_address;
+       } else
+               kern_msg->msg_name = NULL;
+
+       if(kern_msg->msg_iovlen > UIO_FASTIOV) {
+               kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
+                                  GFP_KERNEL);
+               if(!kern_iov)
+                       return -ENOMEM;
+       }
+
+       tot_len = iov_from_user32_to_kern(kern_iov,
+                                         (struct iovec32 *)kern_msg->msg_iov,
+                                         kern_msg->msg_iovlen);
+       if(tot_len >= 0)
+               kern_msg->msg_iov = kern_iov;
+       else if(kern_msg->msg_iovlen > UIO_FASTIOV)
+               kfree(kern_iov);
+
+       return tot_len;
+}
+
+asmlinkage int solaris_sendmsg(int fd, struct sol_nmsghdr *user_msg, unsigned user_flags)
+{
+       struct socket *sock;
+       char address[MAX_SOCK_ADDR];
+       struct iovec iov[UIO_FASTIOV];
+       unsigned char ctl[sizeof(struct cmsghdr) + 20];
+       unsigned char *ctl_buf = ctl;
+       struct msghdr kern_msg;
+       int err, total_len;
+
+       if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
+               return -EFAULT;
+       if(kern_msg.msg_iovlen > UIO_MAXIOV)
+               return -EINVAL;
+       err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
+       if (err < 0)
+               goto out;
+       total_len = err;
+
+       if(kern_msg.msg_controllen) {
+               struct sol_cmsghdr *ucmsg = (struct sol_cmsghdr *)kern_msg.msg_control;
+               unsigned long *kcmsg;
+               __kernel_size_t32 cmlen;
+
+               if(kern_msg.msg_controllen > sizeof(ctl) &&
+                  kern_msg.msg_controllen <= 256) {
+                       err = -ENOBUFS;
+                       ctl_buf = kmalloc(kern_msg.msg_controllen, GFP_KERNEL);
+                       if(!ctl_buf)
+                               goto out_freeiov;
+               }
+               __get_user(cmlen, &ucmsg->cmsg_len);
+               kcmsg = (unsigned long *) ctl_buf;
+               *kcmsg++ = (unsigned long)cmlen;
+               err = -EFAULT;
+               if(copy_from_user(kcmsg, &ucmsg->cmsg_level,
+                                 kern_msg.msg_controllen - sizeof(__kernel_size_t32)))
+                       goto out_freectl;
+               kern_msg.msg_control = ctl_buf;
+       }
+       kern_msg.msg_flags = solaris_to_linux_msgflags(user_flags);
+
+       lock_kernel();
+       sock = sockfd_lookup(fd, &err);
+       if (sock != NULL) {
+               if (sock->file->f_flags & O_NONBLOCK)
+                       kern_msg.msg_flags |= MSG_DONTWAIT;
+               err = sock_sendmsg(sock, &kern_msg, total_len);
+               sockfd_put(sock);
+       }
+       unlock_kernel();
+
+out_freectl:
+       /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
+       if(ctl_buf != ctl)
+               kfree(ctl_buf);
+out_freeiov:
+       if(kern_msg.msg_iov != iov)
+               kfree(kern_msg.msg_iov);
+out:
+       return err;
+}
+
+asmlinkage int solaris_recvmsg(int fd, struct sol_nmsghdr *user_msg, unsigned int user_flags)
+{
+       struct iovec iovstack[UIO_FASTIOV];
+       struct msghdr kern_msg;
+       char addr[MAX_SOCK_ADDR];
+       struct socket *sock;
+       struct iovec *iov = iovstack;
+       struct sockaddr *uaddr;
+       int *uaddr_len;
+       unsigned long cmsg_ptr;
+       int err, total_len, len = 0;
+
+       if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
+               return -EFAULT;
+       if(kern_msg.msg_iovlen > UIO_MAXIOV)
+               return -EINVAL;
+
+       uaddr = kern_msg.msg_name;
+       uaddr_len = &user_msg->msg_namelen;
+       err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
+       if (err < 0)
+               goto out;
+       total_len = err;
+
+       cmsg_ptr = (unsigned long) kern_msg.msg_control;
+       kern_msg.msg_flags = 0;
+
+       lock_kernel();
+       sock = sockfd_lookup(fd, &err);
+       if (sock != NULL) {
+               if (sock->file->f_flags & O_NONBLOCK)
+                       user_flags |= MSG_DONTWAIT;
+               err = sock_recvmsg(sock, &kern_msg, total_len, user_flags);
+               if(err >= 0)
+                       len = err;
+               sockfd_put(sock);
+       }
+       unlock_kernel();
+
+       if(uaddr != NULL && err >= 0)
+               err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
+       if(err >= 0) {
+               err = __put_user(linux_to_solaris_msgflags(kern_msg.msg_flags), &user_msg->msg_flags);
+               if(!err) {
+                       /* XXX Convert cmsg back into userspace 32-bit format... */
+                       err = __put_user((unsigned long)kern_msg.msg_control - cmsg_ptr,
+                                        &user_msg->msg_controllen);
+               }
+       }
+
+       if(kern_msg.msg_iov != iov)
+               kfree(kern_msg.msg_iov);
+out:
+       if(err < 0)
+               return err;
+       return len;
+}
index bb18807f16dd04ec6ee0bb11bf162593816320ed..f47470e4cd7f650b95a47aa8c12c3fdf96bada38 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: systbl.S,v 1.6 1998/03/26 08:46:08 jj Exp $
+/* $Id: systbl.S,v 1.7 1998/10/28 08:11:49 jj Exp $
  * systbl.S: System call entry point table for Solaris compatibility.
  *
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
  */
 
@@ -156,8 +156,8 @@ solaris_sys_table:
        .word solaris_fxstat            /* fxstat       ddx     125     */
        .word solaris_xmknod            /* xmknod       dsox    126     */
        .word solaris_unimplemented     /* syslocal     d       127     */
-       .word solaris_unimplemented     /* setrlimit            128     */
-       .word solaris_unimplemented     /* getrlimit            129     */
+       .word solaris_setrlimit         /* setrlimit    dp      128     */
+       .word solaris_getrlimit         /* getrlimit    dp      129     */
        .word CHAIN(chown)              /* lchown       sdd     130     */
        .word solaris_unimplemented     /* memcntl              131     */
        .word solaris_getpmsg           /* getpmsg      dxxxx   132     */
@@ -230,8 +230,8 @@ solaris_sys_table:
        .word CHAIN(nanosleep)          /* nanosleep    dd      199     */
        .word solaris_facl              /* facl         dddp    200     */
        .word solaris_unimplemented     /*                      201     */
-       .word solaris_unimplemented     /*                      202     */
-       .word solaris_unimplemented     /*                      203     */
+       .word solaris_setreuid          /* setreuid     dd      202     */
+       .word solaris_setregid          /* setregid     dd      203     */
        .word solaris_unimplemented     /*                      204     */
        .word solaris_unimplemented     /*                      205     */
        .word solaris_unimplemented     /*                      206     */
@@ -241,43 +241,43 @@ solaris_sys_table:
        .word solaris_unimplemented     /*                      210     */
        .word solaris_unimplemented     /*                      211     */
        .word solaris_unimplemented     /*                      212     */
-       .word solaris_unimplemented     /*                      213     */
-       .word solaris_unimplemented     /*                      214     */
-       .word solaris_unimplemented     /*                      215     */
-       .word solaris_unimplemented     /*                      216     */
-       .word solaris_unimplemented     /*                      217     */
-       .word solaris_unimplemented     /*                      218     */
-       .word solaris_unimplemented     /*                      219     */
-       .word solaris_unimplemented     /*                      220     */
-       .word solaris_unimplemented     /*                      221     */
-       .word solaris_unimplemented     /*                      222     */
-       .word solaris_unimplemented     /*                      223     */
-       .word solaris_unimplemented     /*                      224     */
-       .word solaris_unimplemented     /*                      225     */
+       .word solaris_getdents64        /* getdents64   dpd     213     */
+       .word REGS(solaris_mmap64)      /* mmap64       xxxxdX  214     */
+       .word solaris_stat64            /* stat64       sP      215     */
+       .word solaris_lstat64           /* lstat64      sP      216     */
+       .word solaris_fstat64           /* fstat64      dP      217     */
+       .word solaris_statvfs64         /* statvfs64    sP      218     */
+       .word solaris_fstatvfs64        /* fstatvfs64   dP      219     */
+       .word solaris_setrlimit64       /* setrlimit64  dP      220     */
+       .word solaris_getrlimit64       /* getrlimit64  dP      221     */
+       .word CHAIN(pread)              /* pread64      dpdD    222     */
+       .word CHAIN(pwrite)             /* pwrite64     dpdD    223     */
+       .word CHAIN(creat)              /* creat64      so      224     */
+       .word solaris_open              /* open64       soo     225     */
        .word solaris_unimplemented     /*                      226     */
        .word solaris_unimplemented     /*                      227     */
        .word solaris_unimplemented     /*                      228     */
        .word solaris_unimplemented     /*                      229     */
-       .word solaris_unimplemented     /*                      230     */
-       .word solaris_unimplemented     /*                      231     */
-       .word solaris_unimplemented     /*                      232     */
-       .word solaris_unimplemented     /*                      233     */
-       .word solaris_unimplemented     /*                      234     */
-       .word solaris_unimplemented     /*                      235     */
-       .word solaris_unimplemented     /*                      236     */
-       .word solaris_unimplemented     /*                      237     */
-       .word solaris_unimplemented     /*                      238     */
-       .word solaris_unimplemented     /*                      239     */
-       .word solaris_unimplemented     /*                      240     */
-       .word solaris_unimplemented     /*                      241     */
-       .word solaris_unimplemented     /*                      242     */
-       .word solaris_unimplemented     /*                      243     */
-       .word solaris_unimplemented     /*                      244     */
-       .word solaris_unimplemented     /*                      245     */
-       .word solaris_unimplemented     /*                      246     */
+       .word solaris_socket            /* socket       ddd     230     */
+       .word solaris_socketpair        /* socketpair   dddp    231     */
+       .word solaris_bind              /* bind         dpd     232     */
+       .word solaris_listen            /* listen       dd      233     */
+       .word solaris_accept            /* accept       dpp     234     */
+       .word solaris_connect           /* connect      dpd     235     */
+       .word solaris_shutdown          /* shutdown     dd      236     */
+       .word solaris_recv              /* recv         dpdd    237     */
+       .word solaris_recvfrom          /* recvfrom     dpddpp  238     */
+       .word solaris_recvmsg           /* recvmsg      dpd     239     */
+       .word solaris_send              /* send         dpdd    240     */
+       .word solaris_sendmsg           /* sendmsg      dpd     241     */
+       .word solaris_sendto            /* sendto       dpddpd  242     */
+       .word solaris_getpeername       /* getpeername  dpp     243     */
+       .word solaris_getsockname       /* getsockname  dpp     244     */
+       .word solaris_getsockopt        /* getsockopt   dddpp   245     */
+       .word solaris_setsockopt        /* setsockopt   dddpp   246     */
        .word solaris_unimplemented     /*                      247     */
-       .word solaris_unimplemented     /*                      248     */
-       .word solaris_unimplemented     /*                      249     */
+       .word solaris_ntp_gettime       /* ntp_gettime  p       248     */
+       .word solaris_ntp_adjtime       /* ntp_adjtime  p       249     */
        .word solaris_unimplemented     /*                      250     */
        .word solaris_unimplemented     /*                      251     */
        .word solaris_unimplemented     /*                      252     */
index 73a48f6a377d86098d5d5c525aee362ca858eee4..a4920df2ab9eaf15f0cfcb239e13d83f326b0afe 100644 (file)
@@ -48,7 +48,7 @@ else
         fi
       fi
       if [ "$CONFIG_PPC" = "y" ]; then
-          bool '   WInbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
+          bool '   Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
       fi
     fi
     if [ "$CONFIG_PMAC" = "y" ]; then
index 714eddcd4890733ecf4bd5a98034b44f24b6a6e2..7fb8430ee77a15b1ffaa1131930c56ec7f946b79 100644 (file)
@@ -61,6 +61,10 @@ extern int blk_dev_init(void);
 extern int scsi_dev_init(void);
 extern int net_dev_init(void);
 
+#ifdef CONFIG_PPC
+extern void note_bootable_part(kdev_t dev, int part);
+#endif
+
 /*
  * disk_name() is used by genhd.c and md.c.
  * It formats the devicename of the indicated disk
@@ -862,7 +866,7 @@ static int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec)
        int blk, blocks_in_map;
        int dev_bsize, dev_pos, pos;
        unsigned secsize;
-#ifdef CONFIG_PMAC
+#ifdef CONFIG_PPC
        int first_bootable = 1;
 #endif
        struct mac_partition *part;
@@ -916,18 +920,18 @@ static int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec)
                        fsec + be32_to_cpu(part->start_block) * (secsize/512),
                        be32_to_cpu(part->block_count) * (secsize/512));
 
-#ifdef CONFIG_PMAC
+#ifdef CONFIG_PPC
                /*
                 * If this is the first bootable partition, tell the
                 * setup code, in case it wants to make this the root.
                 */
-               if (first_bootable
+               if ( (_machine == _MACH_Pmac) && first_bootable
                    && (be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
                    && strcasecmp(part->processor, "powerpc") == 0) {
                        note_bootable_part(dev, blk);
                        first_bootable = 0;
                }
-#endif /* CONFIG_PMAC */
+#endif /* CONFIG_PPC */
 
                ++current_minor;
        }
index 62319220be50f750e1364f1ca0f815024ea951f8..dbce521375f7628f312cf76e2a60dde9085c5934 100644 (file)
@@ -31,7 +31,7 @@ static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 };
 static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
 {
        ide_hwif_t *hwif = HWIF(drive);
-       unsigned int bit, new, *old = (unsigned int *) hwif->select_data;
+       unsigned int bit, other, new, *old = (unsigned int *) hwif->select_data;
        struct pci_dev *dev = hwif->pci_dev;
        unsigned long flags;
 
@@ -39,24 +39,20 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
        __cli();                /* local CPU only */
        new = *old;
 
-       /* adjust IRQ enable bit */
+       /* Adjust IRQ enable bit */
        bit = 1 << (8 + hwif->channel);
        new = drive->present ? (new & ~bit) : (new | bit);
 
-       /* select PIO or DMA */
-       bit = 1 << (20 + drive->select.b.unit + (hwif->channel << 1));
-       new = use_dma ? (new | bit) : (new & ~bit);
+       /* Select PIO or DMA, DMA may only be selected for one drive/channel. */
+       bit   = 1 << (20 + drive->select.b.unit       + (hwif->channel << 1));
+       other = 1 << (20 + (1 - drive->select.b.unit) + (hwif->channel << 1));
+       new = use_dma ? ((new & ~other) | bit) : (new & ~bit);
 
        if (new != *old) {
-               if (use_dma) {
-                       bit = (1 << (5 + drive->select.b.unit));
-                       outb((inb(hwif->dma_base+2) & 0x60) | bit,
-                            hwif->dma_base+2);
-               }
-
                *old = new;
                (void) pci_write_config_dword(dev, 0x40, new);
        }
+
        __restore_flags(flags); /* local CPU only */
 }
 
@@ -94,6 +90,10 @@ __initfunc(void ide_init_ns87415 (ide_hwif_t *hwif))
        struct pci_dev *dev = hwif->pci_dev;
        unsigned int ctrl, using_inta;
        byte progif;
+#ifdef __sparc_v9__
+       int timeout;
+       byte stat;
+#endif
 
        /*
         * We cannot probe for IRQ: both ports share common IRQ on INTA.
@@ -126,22 +126,6 @@ __initfunc(void ide_init_ns87415 (ide_hwif_t *hwif))
                pci_write_config_byte(dev, 0x55, 0xee);
 
 #ifdef __sparc_v9__
-{
-               int     timeout;
-               byte    stat;
-               /*
-                * Put reasonable values in the timing registers
-                * for DMA2 mode performance.
-                */
-               pci_write_config_byte(dev, 0x44, 0xfe);
-               pci_write_config_byte(dev, 0x45, 0xfe);
-               pci_write_config_byte(dev, 0x48, 0xfe);
-               pci_write_config_byte(dev, 0x49, 0xfe);
-               pci_write_config_byte(dev, 0x4c, 0xfe);
-               pci_write_config_byte(dev, 0x4d, 0xfe);
-               pci_write_config_byte(dev, 0x50, 0xfe);
-               pci_write_config_byte(dev, 0x51, 0xfe);
-
                /*
                 * XXX: Reset the device, if we don't it will not respond
                 *      to SELECT_DRIVE() properly during first probe_hwif().
@@ -156,9 +140,11 @@ __initfunc(void ide_init_ns87415 (ide_hwif_t *hwif))
                        if (stat == 0xff)
                                break;
                } while ((stat & BUSY_STAT) && --timeout);
-}
 #endif
        }
+
+       outb(0x60, hwif->dma_base + 2);
+
        if (!using_inta)
                hwif->irq = hwif->channel ? 15 : 14;    /* legacy mode */
        else if (!hwif->irq && hwif->mate && hwif->mate->irq)
index 0f080db773628928b7f6e9e2562c30b48014dd60..5f84aed5286a07d8f55722e412bf3ff37d1395cc 100644 (file)
@@ -224,11 +224,11 @@ else
   endif
 endif
 
-ifeq ($(CONFIG_MACMOUSE),y)
-L_OBJS += macmouse.o
+ifeq ($(CONFIG_ADBMOUSE),y)
+L_OBJS += adbmouse.o
 else
-  ifeq ($(CONFIG_MACMOUSE),m)
-    M_OBJS += macmouse.o
+  ifeq ($(CONFIG_ADBMOUSE),m)
+    M_OBJS += adbmouse.o
   endif
 endif
 
index f74f369a41ac931d97d20301fab59432141941fa..62e31d9c96d8e5be4d49cd37e7b6daecfd579f94 100644 (file)
@@ -1,7 +1,7 @@
 #define BLOCKMOVE
 #define        Z_WAKE
 static char rcsid[] =
-"$Revision: 2.2.1.7 $$Date: 1998/09/03 12:07:28 $";
+"$Revision: 2.2.1.8 $$Date: 1998/11/13 12:46:20 $";
 
 /*
  *  linux/drivers/char/cyclades.c
@@ -31,6 +31,10 @@ static char rcsid[] =
  *   void cleanup_module(void);
  *
  * $Log: cyclades.c,v $
+ * Revision 2.2.1.8  1998/11/13 12:46:20 ivan
+ * cy_close function now resets (correctly) the tty->closing flag;
+ * JIFFIES_DIFF macro fixed.
+ *
  * Revision 2.2.1.7  1998/09/03 12:07:28 ivan
  * Fixed bug in cy_close function, which was not informing HW of
  * which port should have the reception disabled before doing so;
@@ -612,7 +616,7 @@ static unsigned long cy_get_user(unsigned long *addr)
 
 #define STD_COM_FLAGS (0)
 
-#define        JIFFIES_DIFF(n, j)      ((n) - (j))
+#define        JIFFIES_DIFF(n, j)      ((j) - (n))
 
 static DECLARE_TASK_QUEUE(tq_cyclades);
 
@@ -2730,6 +2734,7 @@ cy_close(struct tty_struct * tty, struct file * filp)
         tty->driver.flush_buffer(tty);
     if (tty->ldisc.flush_buffer)
         tty->ldisc.flush_buffer(tty);
+    tty->closing = 0;
     info->event = 0;
     info->tty = 0;
     if (info->blocked_open) {
index 71577f39b92653d61610a67040e25cd78199fc7d..83bbad196cf45ffd422699a273ffab90f558db28 100644 (file)
@@ -53,6 +53,9 @@ extern void prom_con_init(void);
 #ifdef CONFIG_MDA_CONSOLE
 extern void mda_console_init(void);
 #endif
+#if defined(CONFIG_PPC) || defined(CONFIG_MAC)
+extern void adbdev_init(void);
+#endif
 
 static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
                            const char * buf, size_t count, loff_t *ppos)
@@ -509,9 +512,11 @@ static int memory_open(struct inode * inode, struct file * filp)
                case 3:
                        filp->f_op = &null_fops;
                        break;
+#ifndef CONFIG_PPC
                case 4:
                        filp->f_op = &port_fops;
                        break;
+#endif
                case 5:
                        filp->f_op = &zero_fops;
                        break;
@@ -596,6 +601,9 @@ __initfunc(int chr_dev_init(void))
 #ifdef CONFIG_VIDEO_BT848
        i2c_init();
 #endif
+#if defined(CONFIG_PPC) || defined(CONFIG_MAC)
+       adbdev_init();
+#endif
 #ifdef CONFIG_VIDEO_DEV
        videodev_init();
 #endif
index c651ee88baecae6e7aebd4871cdeb1103b1d43b4..b8b80d377241a82eead6bb361068cc7a75dd817e 100644 (file)
@@ -64,14 +64,12 @@ static struct miscdevice misc_list = { 0, "head", NULL, &misc_list, &misc_list }
 #define DYNAMIC_MINORS 64 /* like dynamic majors */
 static unsigned char misc_minors[DYNAMIC_MINORS / 8];
 
-extern int adbdev_init(void);
 extern int bus_mouse_init(void);
 extern int qpmouse_init(void);
 extern int ms_bus_mouse_init(void);
 extern int atixl_busmouse_init(void);
 extern int amiga_mouse_init(void);
 extern int atari_mouse_init(void);
-extern int mac_mouse_init(void);
 extern int sun_mouse_init(void);
 extern int adb_mouse_init(void);
 extern void watchdog_init(void);
@@ -196,9 +194,6 @@ int __init misc_init(void)
        if (proc_misc)
                proc_misc->read_proc = misc_read_proc;
 #endif /* PROC_FS */
-#ifdef CONFIG_MAC
-       adbdev_init();
-#endif
 #ifdef CONFIG_BUSMOUSE
        bus_mouse_init();
 #endif
@@ -217,13 +212,10 @@ int __init misc_init(void)
 #ifdef CONFIG_ATARIMOUSE
        atari_mouse_init();
 #endif
-#ifdef CONFIG_MACMOUSE
-       mac_mouse_init();
-#endif
 #ifdef CONFIG_SUN_MOUSE
        sun_mouse_init();
 #endif
-#ifdef CONFIG_MACMOUSE
+#ifdef CONFIG_ADBMOUSE
        adb_mouse_init();
 #endif
 #ifdef CONFIG_PC110_PAD
index 1360dc17f553a22d5139da19cfe52b9e2209b7df..70cf4961ff6428097b392a284e9c3524af46b289 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: parport_ax.c,v 1.12 1998/07/26 03:03:31 davem Exp $
+/* $Id: parport_ax.c,v 1.13 1998/10/26 20:01:59 davem Exp $
  * Parallel-port routines for Sun Ultra/AX architecture
  * 
  * Author: Eddie C. Dost <ecd@skynet.be>
index 360f62166d5765a396488a3ba3299317a9060316..5e381d9856e22700492ccbd3c5abb04df3af6b1d 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/if_arp.h>
 #include <linux/if_ltalk.h>
 #include <linux/rtnetlink.h>
+#include <net/neighbour.h>
 
 /* The network devices currently exist only in the socket namespace, so these
    entries are unused.  The only ones that make sense are
@@ -219,6 +220,21 @@ struct device *init_hippi_dev(struct device *dev, int sizeof_priv)
        hippi_setup(tmp_dev);
        return tmp_dev;
 }
+
+static int hippi_neigh_setup_dev(struct device *dev, struct neigh_parms *p)
+{
+       /* Never send broadcast/multicast ARP messages */
+       p->mcast_probes = 0;
+       /* In IPv6 unicast probes are valid even on NBMA,
+       * because they are encapsulated in normal IPv6 protocol.
+       * Should be a generic flag. 
+       */
+       if (p->tbl->family != AF_INET6)
+               p->ucast_probes = 0;
+       return 0;
+}
+
 #endif
 
 void ether_setup(struct device *dev)
@@ -304,6 +320,7 @@ void hippi_setup(struct device *dev)
        dev->hard_header_parse          = NULL;
        dev->hard_header_cache          = NULL;
        dev->header_cache_update        = NULL;
+       dev->neigh_setup                = hippi_neigh_setup_dev; 
 
        /*
         * We don't support HIPPI `ARP' for the time being, and probably
@@ -317,12 +334,13 @@ void hippi_setup(struct device *dev)
        dev->tx_queue_len       = 25 /* 5 */;
        memset(dev->broadcast, 0xFF, HIPPI_ALEN);
 
-       /* New-style flags. */
-       dev->flags      = IFF_NODYNARP; /*
-                                        * HIPPI doesn't support
-                                        * broadcast+multicast and we only
-                                        * use static ARP tables.
-                                        */
+
+       /*
+        * HIPPI doesn't support broadcast+multicast and we only use
+        * static ARP tables. ARP is disabled by hippi_neigh_setup_dev. 
+        */
+       dev->flags = 0; 
+
        dev_init_buffers(dev);
 }
 #endif
index 3a738a93db07207fe0d3e83e5fab789a1b7ec5b2..434c082bb0353ae98ab5762ea3e9419eeaa41cca 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: sgiseeq.c,v 1.5 1998/05/01 01:35:40 ralf Exp $
+ * $Id: sgiseeq.c,v 1.6 1998/10/14 17:29:44 ralf Exp $
  */
 
 #include <linux/kernel.h>
@@ -88,7 +88,7 @@ struct sgiseeq_init_block { /* Note the name ;-) */
        /* Ptrs to the descriptors in KSEG1 uncached space. */
        struct sgiseeq_rx_desc *rx_desc;
        struct sgiseeq_tx_desc *tx_desc;
-       unsigned long _padding[14]; /* Pad out to largest cache line size. */
+       unsigned long _padding[30]; /* Pad out to largest cache line size. */
 
        struct sgiseeq_rx_desc rxvector[SEEQ_RX_BUFFERS];
        struct sgiseeq_tx_desc txvector[SEEQ_TX_BUFFERS];
index 23a54356d28cebace7582db8c8f9037d846a5c3f..0b2eb82fc7a5fd4117f9970de47dea1674622ff5 100644 (file)
@@ -38,6 +38,9 @@ static char *version =
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/irq.h>
+#ifndef __sparc_v9__
+#include <asm/io-unit.h>
+#endif
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -1061,14 +1064,23 @@ static void happy_meal_init_rings(struct happy_meal *hp, int from_irq)
                                         (RXFLAG_OWN |
                                          ((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
                                         (u32)virt_to_bus((volatile void *)skb->data));
-               } else {
+               } else
+#endif
+#ifndef __sparc_v9__
+               if (sparc_cpu_model == sun4d) {
+                       __u32 va = (__u32)hp->sun4d_buffers + i * PAGE_SIZE;
+
+                       hb->happy_meal_rxd[i].rx_addr =
+                               iounit_map_dma_page(va, skb->data, hp->happy_sbus_dev->my_bus);
+                       hb->happy_meal_rxd[i].rx_flags =
+                               (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16));
+               } else
 #endif
+               {
                        hb->happy_meal_rxd[i].rx_addr = (u32)((unsigned long) skb->data);
                        hb->happy_meal_rxd[i].rx_flags =
                                (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16));
-#ifdef CONFIG_PCI
                }
-#endif
                skb_reserve(skb, RX_OFFSET);
        }
 
@@ -1078,6 +1090,7 @@ static void happy_meal_init_rings(struct happy_meal *hp, int from_irq)
        HMD(("done\n"));
 }
 
+#ifndef __sparc_v9__
 static void sun4c_happy_meal_init_rings(struct happy_meal *hp)
 {
        struct hmeal_init_block *hb = hp->happy_block;
@@ -1099,6 +1112,7 @@ static void sun4c_happy_meal_init_rings(struct happy_meal *hp)
                hb->happy_meal_txd[i].tx_flags = 0;
        HMD(("done\n"));
 }
+#endif
 
 static void happy_meal_begin_auto_negotiation(struct happy_meal *hp,
                                              struct hmeal_tcvregs *tregs)
@@ -1234,9 +1248,11 @@ static int happy_meal_init(struct happy_meal *hp, int from_irq)
 
        /* Alloc and reset the tx/rx descriptor chains. */
        HMD(("happy_meal_init: to happy_meal_init_rings\n"));
+#ifndef __sparc_v9__   
        if(sparc_cpu_model == sun4c)
                sun4c_happy_meal_init_rings(hp);
        else
+#endif 
                happy_meal_init_rings(hp, from_irq);
 
        /* Shut up the MIF. */
@@ -1681,7 +1697,6 @@ static inline void pci_happy_meal_tx(struct happy_meal *hp)
                                     : "=r" (flags)
                                     : "r" (&this->tx_flags), "i" (ASI_PL));
 #else
-               flush_cache_all();
                flags = flip_dword(this->tx_flags);
 #endif
                if(flags & TXFLAG_OWN)
@@ -1700,6 +1715,7 @@ static inline void pci_happy_meal_tx(struct happy_meal *hp)
 }
 #endif
 
+#ifndef __sparc_v9__
 static inline void sun4c_happy_meal_tx(struct happy_meal *hp)
 {
        struct happy_meal_txd *txbase = &hp->happy_block->happy_meal_txd[0];
@@ -1721,6 +1737,7 @@ static inline void sun4c_happy_meal_tx(struct happy_meal *hp)
        hp->tx_old = elem;
        TXD((">"));
 }
+#endif
 
 #ifdef RXDEBUG
 #define RXD(x) printk x
@@ -1855,7 +1872,6 @@ static inline void pci_happy_meal_rx(struct happy_meal *hp, struct device *dev,
                             : "=r" (flags)
                             : "r" (&this->rx_flags), "i" (ASI_PL));
 #else
-       flush_cache_all();
        flags = flip_dword(this->rx_flags); /* FIXME */
 #endif
        while(!(flags & RXFLAG_OWN)) {
@@ -1949,7 +1965,6 @@ static inline void pci_happy_meal_rx(struct happy_meal *hp, struct device *dev,
                                     : "=r" (flags)
                                     : "r" (&this->rx_flags), "i" (ASI_PL));
 #else
-               flush_cache_all();
                flags = flip_dword(this->rx_flags); /* FIXME */
 #endif
        }
@@ -1960,6 +1975,7 @@ static inline void pci_happy_meal_rx(struct happy_meal *hp, struct device *dev,
 }
 #endif
 
+#ifndef __sparc_v9__
 static inline void sun4c_happy_meal_rx(struct happy_meal *hp, struct device *dev,
                                       struct hmeal_gregs *gregs)
 {
@@ -2023,6 +2039,115 @@ static inline void sun4c_happy_meal_rx(struct happy_meal *hp, struct device *dev
        RXD((">"));
 }
 
+static inline void sun4d_happy_meal_rx(struct happy_meal *hp, struct device *dev,
+                                      struct hmeal_gregs *gregs)
+{
+       struct happy_meal_rxd *rxbase = &hp->happy_block->happy_meal_rxd[0];
+       struct happy_meal_rxd *this;
+       int elem = hp->rx_new, drops = 0;
+       __u32 va;
+
+       RXD(("RX<"));
+       this = &rxbase[elem];
+       while(!(this->rx_flags & RXFLAG_OWN)) {
+               struct sk_buff *skb;
+               unsigned int flags = this->rx_flags;
+               int len = flags >> 16;
+               u16 csum = flags & RXFLAG_CSUM;
+
+               RXD(("[%d ", elem));
+
+               /* Check for errors. */
+               if((len < ETH_ZLEN) || (flags & RXFLAG_OVERFLOW)) {
+                       RXD(("ERR(%08x)]", flags));
+                       hp->net_stats.rx_errors++;
+                       if(len < ETH_ZLEN)
+                               hp->net_stats.rx_length_errors++;
+                       if(len & (RXFLAG_OVERFLOW >> 16)) {
+                               hp->net_stats.rx_over_errors++;
+                               hp->net_stats.rx_fifo_errors++;
+                       }
+
+                       /* Return it to the Happy meal. */
+       drop_it:
+                       hp->net_stats.rx_dropped++;
+                       va = (__u32)hp->sun4d_buffers + elem * PAGE_SIZE;
+                       this->rx_addr = iounit_map_dma_page(va, hp->rx_skbs[elem]->data,
+                                                           hp->happy_sbus_dev->my_bus);
+                       this->rx_flags =
+                               (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16));
+                       goto next;
+               }
+               skb = hp->rx_skbs[elem];
+               if(len > RX_COPY_THRESHOLD) {
+                       struct sk_buff *new_skb;
+
+                       /* Now refill the entry, if we can. */
+                       new_skb = happy_meal_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
+                       if(!new_skb) {
+                               drops++;
+                               goto drop_it;
+                       }
+
+                       hp->rx_skbs[elem] = new_skb;
+                       new_skb->dev = dev;
+                       skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET));
+                       va = (__u32)hp->sun4d_buffers + elem * PAGE_SIZE;
+                       rxbase[elem].rx_addr = iounit_map_dma_page(va, new_skb->data,
+                                                               hp->happy_sbus_dev->my_bus);
+
+                       skb_reserve(new_skb, RX_OFFSET);
+                       rxbase[elem].rx_flags =
+                               (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16));
+
+                       /* Trim the original skb for the netif. */
+                       skb_trim(skb, len);
+               } else {
+                       struct sk_buff *copy_skb = dev_alloc_skb(len+2);
+
+                       if(!copy_skb) {
+                               drops++;
+                               goto drop_it;
+                       }
+
+                       copy_skb->dev = dev;
+                       skb_reserve(copy_skb, 2);
+                       skb_put(copy_skb, len);
+                       memcpy(copy_skb->data, skb->data, len);
+
+                       /* Reuse original ring buffer. */
+                       va = (__u32)hp->sun4d_buffers + elem * PAGE_SIZE;
+                       rxbase[elem].rx_addr = iounit_map_dma_page(va, skb->data,
+                                                               hp->happy_sbus_dev->my_bus);
+                       rxbase[elem].rx_flags =
+                               (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16));
+
+                       skb = copy_skb;
+               }
+
+               /* This card is _fucking_ hot... */
+               if(!(csum ^ 0xffff))
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+               else
+                       skb->ip_summed = CHECKSUM_NONE;
+
+               RXD(("len=%d csum=%4x]", len, csum));
+               skb->protocol = eth_type_trans(skb, dev);
+               netif_rx(skb);
+
+               hp->net_stats.rx_packets++;
+               hp->net_stats.rx_bytes+=len;
+       next:
+               elem = NEXT_RX(elem);
+               this = &rxbase[elem];
+       }
+       hp->rx_new = elem;
+       if(drops)
+               printk("%s: Memory squeeze, deferring packet.\n", hp->dev->name);
+       RXD((">"));
+}
+#endif
+
 static void happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct device *dev            = (struct device *) dev_id;
@@ -2157,6 +2282,50 @@ static void sun4c_happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *re
        dev->interrupt = 0;
        HMD(("done\n"));
 }
+
+static void sun4d_happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct device *dev            = (struct device *) dev_id;
+       struct happy_meal *hp         = (struct happy_meal *) dev->priv;
+       struct hmeal_gregs *gregs     = hp->gregs;
+       struct hmeal_tcvregs *tregs   = hp->tcvregs;
+       unsigned int happy_status    = hme_read32(hp, &gregs->stat);
+
+       HMD(("happy_meal_interrupt: status=%08x ", happy_status));
+
+       dev->interrupt = 1;
+
+       if(happy_status & GREG_STAT_ERRORS) {
+               HMD(("ERRORS "));
+               if(happy_meal_is_not_so_happy(hp, gregs, /* un- */ happy_status)) {
+                       dev->interrupt = 0;
+                       return;
+               }
+       }
+
+       if(happy_status & GREG_STAT_MIFIRQ) {
+               HMD(("MIFIRQ "));
+               happy_meal_mif_interrupt(hp, gregs, tregs);
+       }
+
+       if(happy_status & GREG_STAT_TXALL) {
+               HMD(("TXALL "));
+               happy_meal_tx(hp);
+       }
+
+       if(happy_status & GREG_STAT_RXTOHOST) {
+               HMD(("RXTOHOST "));
+               sun4d_happy_meal_rx(hp, dev, gregs);
+       }
+
+       if(dev->tbusy && (TX_BUFFS_AVAIL(hp) >= 0)) {
+               hp->dev->tbusy = 0;
+               mark_bh(NET_BH);
+       }
+
+       dev->interrupt = 0;
+       HMD(("done\n"));
+}
 #endif
 
 static int happy_meal_open(struct device *dev)
@@ -2173,6 +2342,14 @@ static int happy_meal_open(struct device *dev)
                        printk("happy meal: Can't order irq %d to go.\n", dev->irq);
                        return -EAGAIN;
                }
+       } else if (sparc_cpu_model == sun4d) {
+               if(request_irq(dev->irq, &sun4d_happy_meal_interrupt,
+                              SA_SHIRQ, "HAPPY MEAL", (void *) dev)) {
+                       HMD(("EAGAIN\n"));
+                       printk("happy_meal(SBUS): Can't order irq %s to go.\n",
+                              __irq_itoa(dev->irq));
+                       return -EAGAIN;
+               }
        } else
 #endif
 #ifdef CONFIG_PCI
@@ -2327,6 +2504,7 @@ static int pci_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev)
 }
 #endif
 
+#ifndef __sparc_v9__
 static int sun4c_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev)
 {
        struct happy_meal *hp = (struct happy_meal *) dev->priv;
@@ -2383,6 +2561,59 @@ static int sun4c_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev)
        return 0;
 }
 
+static int sun4d_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev)
+{
+       struct happy_meal *hp = (struct happy_meal *) dev->priv;
+       int len, entry;
+       __u32 va;
+
+       if(test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
+               int tickssofar = jiffies - dev->trans_start;
+           
+               if (tickssofar >= 40) {
+                       printk ("%s: transmit timed out, resetting\n", dev->name);
+                       hp->net_stats.tx_errors++;
+                       tx_dump_log();
+                       printk ("%s: Happy Status %08x TX[%08x:%08x]\n", dev->name,
+                               hme_read32(hp, &hp->gregs->stat),
+                               hme_read32(hp, &hp->etxregs->cfg),
+                               hme_read32(hp, &hp->bigmacregs->tx_cfg));
+                       happy_meal_init(hp, 0);
+                       dev->tbusy = 0;
+                       dev->trans_start = jiffies;
+               } else
+                       tx_add_log(hp, TXLOG_ACTION_TXMIT|TXLOG_ACTION_TBUSY, 0);
+               return 1;
+       }
+
+       if(!TX_BUFFS_AVAIL(hp)) {
+               tx_add_log(hp, TXLOG_ACTION_TXMIT|TXLOG_ACTION_NBUFS, 0);
+               return 1;
+       }
+       len = skb->len;
+       entry = hp->tx_new;
+
+       SXD(("SX<l[%d]e[%d]>", len, entry));
+       hp->tx_skbs[entry] = skb;
+       va = (__u32)hp->sun4d_buffers + (RX_RING_SIZE + entry) * PAGE_SIZE;
+       hp->happy_block->happy_meal_txd[entry].tx_addr = 
+               iounit_map_dma_page(va, skb->data, hp->happy_sbus_dev->my_bus);
+       hp->happy_block->happy_meal_txd[entry].tx_flags =
+               (TXFLAG_OWN | TXFLAG_SOP | TXFLAG_EOP | (len & TXFLAG_SIZE));
+       hp->tx_new = NEXT_TX(entry);
+
+       /* Get it going. */
+       dev->trans_start = jiffies;
+       hme_write32(hp, &hp->etxregs->tx_pnding, ETX_TP_DMAWAKEUP);
+
+       if(TX_BUFFS_AVAIL(hp))
+               dev->tbusy = 0;
+
+       tx_add_log(hp, TXLOG_ACTION_TXMIT, 0);
+       return 0;
+}
+#endif
+
 static struct net_device_stats *happy_meal_get_stats(struct device *dev)
 {
        struct happy_meal *hp = (struct happy_meal *) dev->priv;
@@ -2561,11 +2792,17 @@ static inline int happy_meal_ether_init(struct device *dev, struct linux_sbus_de
                sparc_dvma_malloc(PAGE_SIZE, "Happy Meal Init Block",
                                  &hp->hblock_dvma);
 
+#ifndef __sparc_v9__
        if(sparc_cpu_model == sun4c)
                hp->sun4c_buffers = (struct hmeal_buffers *)
                    sparc_dvma_malloc(sizeof(struct hmeal_buffers), "Happy Meal Bufs",
                                      &hp->s4c_buf_dvma);
+       else if (sparc_cpu_model == sun4d)
+               hp->sun4d_buffers = (struct hmeal_buffers *)
+                   iounit_map_dma_init(hp->happy_sbus_dev->my_bus,
+                                       (RX_RING_SIZE + TX_RING_SIZE) * PAGE_SIZE);
        else
+#endif
                hp->sun4c_buffers = 0;
 
        /* Force check of the link first time we are brought up. */
@@ -2583,9 +2820,13 @@ static inline int happy_meal_ether_init(struct device *dev, struct linux_sbus_de
        hp->dev = dev;
        dev->open = &happy_meal_open;
        dev->stop = &happy_meal_close;
+#ifndef __sparc_v9__   
        if(sparc_cpu_model == sun4c)
                dev->hard_start_xmit = &sun4c_happy_meal_start_xmit;
+       else if (sparc_cpu_model == sun4d)
+               dev->hard_start_xmit = &sun4d_happy_meal_start_xmit;
        else
+#endif
                dev->hard_start_xmit = &happy_meal_start_xmit;
        dev->get_stats = &happy_meal_get_stats;
        dev->set_multicast_list = &happy_meal_set_multicast;
@@ -2684,6 +2925,11 @@ __initfunc(int happy_meal_pci_init(struct device *dev, struct pci_dev *pdev))
        }
 
        hp->hblock_dvma = (u32) virt_to_bus(hp->happy_block);
+#ifndef __sparc_v9__
+       /* This case we currently need to use 'sparc_alloc_io' */
+       hp->happy_block = sparc_alloc_io (hp->hblock_dvma, NULL, 
+                                         PAGE_SIZE, "sunhme", 0, 0);
+#endif
        hp->sun4c_buffers = 0;
 
        hp->linkcheck = 0;
@@ -2796,6 +3042,11 @@ cleanup_module(void)
                sparc_free_io(hp->erxregs, sizeof(struct hmeal_erxregs));
                sparc_free_io(hp->bigmacregs, sizeof(struct hmeal_bigmacregs));
                sparc_free_io(hp->tcvregs, sizeof(struct hmeal_tcvregs));
+#ifndef __sparc_v9__
+               if (sparc_cpu_model == sun4d)
+                       iounit_map_dma_finish(hp->happy_sbus_dev->my_bus,
+                                             (__u32)hp->sun4d_buffers, (RX_RING_SIZE + TX_RING_SIZE) * PAGE_SIZE);
+#endif         
                unregister_netdev(hp->dev);
                kfree(hp->dev);
                root_happy_dev = sunshine;
index e938e21bc90829d8439894bf78e3aa39804d5f53..c7d2bc81307146c5a1310fb506c41d7f126acbe5 100644 (file)
@@ -525,6 +525,7 @@ struct happy_meal {
 
        /* We may use this for Ultra as well, will have to see, maybe not. */
        struct hmeal_buffers     *sun4c_buffers;  /* CPU visible address.              */
+#define        sun4d_buffers             sun4c_buffers   /* No need to make this a separate.  */
        __u32                     s4c_buf_dvma;   /* DVMA visible address.             */
 
        unsigned int              happy_flags;    /* Driver state flags                */
@@ -664,7 +665,6 @@ extern inline void pcihme_write_rxd(struct happy_meal_rxd *rp,
 {
        rp->rx_addr = flip_dword(addr);
        rp->rx_flags = flip_dword(flags);
-        flush_cache_all();
 }
        
 extern inline void pcihme_write_txd(struct happy_meal_txd *tp,
@@ -673,7 +673,6 @@ extern inline void pcihme_write_txd(struct happy_meal_txd *tp,
 {
        tp->tx_addr = flip_dword(addr);
        tp->tx_flags = flip_dword(flags);
-        flush_cache_all();
 }
        
 #endif  /* def __sparc_v9__ */
index ed15e083ae2fcb07a206f8796b0df242e9fe4cff..1ec8b647051f318e3d110075578145b79970b309 100644 (file)
@@ -45,11 +45,11 @@ endif
 
 ifeq ($(CONFIG_SPARCAUDIO_DBRI),y)
 SBUS_AUDIO=y
-O_OBJS += dbri.o
+OX_OBJS += dbri.o
 else
   ifeq ($(CONFIG_SPARCAUDIO_DBRI),m)
   SBUS_AUDIO_MODULE=y
-  M_OBJS += dbri.o
+  MX_OBJS += dbri.o
   endif
 endif
 
index 07893896be1553d3cc25e20587551af2a29805e7..f10039aca8a035ee74580bffddcb16b837d3a7dc 100644 (file)
  *
  * Thanks to the AMD engineer who was able to get us the AMD79C30
  * databook which has all the programming information and gain tables.
+ *
+ * Advanced Micro Devices' Am79C30A is an ISDN/audio chip used in the
+ * SparcStation 1+.  The chip provides microphone and speaker interfaces
+ * which provide mono-channel audio at 8K samples per second via either
+ * 8-bit A-law or 8-bit mu-law encoding.  Also, the chip features an
+ * ISDN BRI Line Interface Unit (LIU), I.430 S/T physical interface,
+ * which performs basic D channel LAPD processing and provides raw
+ * B channel data.  The digital audio channel, the two ISDN B channels,
+ * and two 64 Kbps channels to the microprocessor are all interconnected
+ * via a multiplexer.
+ *
+ * This driver interfaces to the Linux HiSax ISDN driver, which performs
+ * all high-level Q.921 and Q.931 ISDN functions.  The file is not
+ * itself a hardware driver; rather it uses functions exported by
+ * the AMD7930 driver in the sparcaudio subsystem (drivers/sbus/audio),
+ * allowing the chip to be simultaneously used for both audio and ISDN data.
+ * The hardware driver does _no_ buffering, but provides several callbacks
+ * which are called during interrupt service and should therefore run quickly.
+ *
+ * D channel transmission is performed by passing the hardware driver the
+ * address and size of an skb's data area, then waiting for a callback
+ * to signal successful transmission of the packet.  A task is then
+ * queued to notify the HiSax driver that another packet may be transmitted.
+ *
+ * D channel reception is quite simple, mainly because of:
+ *   1) the slow speed of the D channel - 16 kbps, and
+ *   2) the presence of an 8- or 32-byte (depending on chip version) FIFO
+ *      to buffer the D channel data on the chip
+ * Worst case scenario of back-to-back packets with the 8 byte buffer
+ * at 16 kbps yields an service time of 4 ms - long enough to preclude
+ * the need for fancy buffering.  We queue a background task that copies
+ * data out of the receive buffer into an skb, and the hardware driver
+ * simply does nothing until we're done with the receive buffer and
+ * reset it for a new packet.
+ *
+ * B channel processing is more complex, because of:
+ *   1) the faster speed - 64 kbps,
+ *   2) the lack of any on-chip buffering (it interrupts for every byte), and
+ *   3) the lack of any chip support for HDLC encapsulation
+ *
+ * The HiSax driver can put each B channel into one of three modes -
+ * L1_MODE_NULL (channel disabled), L1_MODE_TRANS (transparent data relay),
+ * and L1_MODE_HDLC (HDLC encapsulation by low-level driver).
+ * L1_MODE_HDLC is the most common, used for almost all "pure" digital
+ * data sessions.  L1_MODE_TRANS is used for ISDN audio.
+ *
+ * HDLC B channel transmission is performed via a large buffer into
+ * which the skb is copied while performing HDLC bit-stuffing.  A CRC
+ * is computed and attached to the end of the buffer, which is then
+ * passed to the low-level routines for raw transmission.  Once
+ * transmission is complete, the hardware driver is set to enter HDLC
+ * idle by successive transmission of mark (all 1) bytes, waiting for
+ * the ISDN driver to prepare another packet for transmission and
+ * deliver it.
+ *
+ * HDLC B channel reception is performed via an X-byte ring buffer
+ * divided into N sections of X/N bytes each.  Defaults: X=256 bytes, N=4.
+ * As the hardware driver notifies us that each section is full, we
+ * hand it the next section and schedule a background task to peruse
+ * the received section, bit-by-bit, with an HDLC decoder.  As
+ * packets are detected, they are copied into a large buffer while
+ * decoding HDLC bit-stuffing.  The ending CRC is verified, and if
+ * it is correct, we alloc a new skb of the correct length (which we
+ * now know), copy the packet into it, and hand it to the upper layers.
+ * Optimization: for large packets, we hand the buffer (which also
+ * happens to be an skb) directly to the upper layer after an skb_trim,
+ * and alloc a new large buffer for future packets, thus avoiding a copy.
+ * Then we return to HDLC processing; state is saved between calls.
  */
 
 #include <linux/module.h>
 #include <asm/audioio.h>
 #include "amd7930.h"
 
+#include "../../isdn/hisax/hisax.h"
+#include "../../isdn/hisax/isdnl1.h"
+#include "../../isdn/hisax/foreign.h"
+
 #define MAX_DRIVERS 1
 
 static struct sparcaudio_driver drivers[MAX_DRIVERS];
@@ -296,9 +368,6 @@ static void amd7930_update_map(struct sparcaudio_driver *drv)
  * driver, since D.output_callback_arg is assumed to be a certain struct ptr
  */
 
-#include "../../isdn/hisax/hisax.h"
-#include "../../isdn/hisax/isdnl1.h"
-
 #ifdef L2FRAME_DEBUG
 
 inline void debug_info(struct amd7930_info *info, char c) {
@@ -910,7 +979,7 @@ static int amd7930_get_monitor_volume(struct sparcaudio_driver *drv)
  */
 
 
-int amd7930_get_irqnum(int dev)
+static int amd7930_get_irqnum(int dev)
 {
        struct amd7930_info *info;
 
@@ -923,7 +992,7 @@ int amd7930_get_irqnum(int dev)
        return info->irq;
 }
 
-int amd7930_get_liu_state(int dev)
+static int amd7930_get_liu_state(int dev)
 {
        struct amd7930_info *info;
 
@@ -936,7 +1005,7 @@ int amd7930_get_liu_state(int dev)
        return info->liu_state;
 }
 
-void amd7930_liu_init(int dev, void (*callback)(), void *callback_arg)
+static void amd7930_liu_init(int dev, void (*callback)(), void *callback_arg)
 {
        struct amd7930_info *info;
        register unsigned long flags;
@@ -971,7 +1040,7 @@ void amd7930_liu_init(int dev, void (*callback)(), void *callback_arg)
        restore_flags(flags);
 }
 
-void amd7930_liu_activate(int dev, int priority)
+static void amd7930_liu_activate(int dev, int priority)
 {
        struct amd7930_info *info;
        register unsigned long flags;
@@ -1003,7 +1072,7 @@ void amd7930_liu_activate(int dev, int priority)
        restore_flags(flags);
 }
 
-void amd7930_liu_deactivate(int dev)
+static void amd7930_liu_deactivate(int dev)
 {
        struct amd7930_info *info;
        register unsigned long flags;
@@ -1024,8 +1093,8 @@ void amd7930_liu_deactivate(int dev)
        restore_flags(flags);
 }
 
-void amd7930_dxmit(int dev, __u8 *buffer, unsigned int count,
-                  void (*callback)(void *, int), void *callback_arg)
+static void amd7930_dxmit(int dev, __u8 *buffer, unsigned int count,
+                          void (*callback)(void *, int), void *callback_arg)
 {
        struct amd7930_info *info;
        register unsigned long flags;
@@ -1069,9 +1138,9 @@ void amd7930_dxmit(int dev, __u8 *buffer, unsigned int count,
        restore_flags(flags);
 }
 
-void amd7930_drecv(int dev, __u8 *buffer, unsigned int size,
-                  void (*callback)(void *, int, unsigned int),
-                  void *callback_arg)
+static void amd7930_drecv(int dev, __u8 *buffer, unsigned int size,
+                          void (*callback)(void *, int, unsigned int),
+                          void *callback_arg)
 {
        struct amd7930_info *info;
        register unsigned long flags;
@@ -1115,7 +1184,8 @@ void amd7930_drecv(int dev, __u8 *buffer, unsigned int size,
        restore_flags(flags);
 }
 
-int amd7930_bopen(int dev, int chan, u_char xmit_idle_char)
+static int amd7930_bopen(int dev, unsigned int chan,
+                         int mode, u_char xmit_idle_char)
 {
        struct amd7930_info *info;
        register unsigned long flags;
@@ -1124,6 +1194,10 @@ int amd7930_bopen(int dev, int chan, u_char xmit_idle_char)
                return -1;
        }
 
+        if (mode == L1_MODE_HDLC) {
+                return -1;
+        }
+
        info = (struct amd7930_info *) drivers[dev].private;
 
        save_and_cli(flags);
@@ -1167,7 +1241,7 @@ int amd7930_bopen(int dev, int chan, u_char xmit_idle_char)
        return 0;
 }
 
-void amd7930_bclose(int dev, int chan)
+static void amd7930_bclose(int dev, unsigned int chan)
 {
        struct amd7930_info *info;
        register unsigned long flags;
@@ -1202,8 +1276,9 @@ void amd7930_bclose(int dev, int chan)
        restore_flags(flags);
 }
 
-void amd7930_bxmit(int dev, int chan, __u8 * buffer, unsigned long count,
-                  void (*callback)(void *), void *callback_arg)
+static void amd7930_bxmit(int dev, unsigned int chan,
+                          __u8 * buffer, unsigned long count,
+                          void (*callback)(void *, int), void *callback_arg)
 {
        struct amd7930_info *info;
        struct amd7930_channel *Bchan;
@@ -1228,8 +1303,10 @@ void amd7930_bxmit(int dev, int chan, __u8 * buffer, unsigned long count,
        }
 }
 
-void amd7930_brecv(int dev, int chan, __u8 * buffer, unsigned long size,
-                  void (*callback)(void *), void *callback_arg)
+static void amd7930_brecv(int dev, unsigned int chan,
+                          __u8 * buffer, unsigned long size,
+                          void (*callback)(void *, int, unsigned int),
+                          void *callback_arg)
 {
        struct amd7930_info *info;
        struct amd7930_channel *Bchan;
@@ -1254,17 +1331,20 @@ void amd7930_brecv(int dev, int chan, __u8 * buffer, unsigned long size,
        }
 }
 
-EXPORT_SYMBOL(amd7930_get_irqnum);
-EXPORT_SYMBOL(amd7930_get_liu_state);
-EXPORT_SYMBOL(amd7930_liu_init);
-EXPORT_SYMBOL(amd7930_liu_activate);
-EXPORT_SYMBOL(amd7930_liu_deactivate);
-EXPORT_SYMBOL(amd7930_dxmit);
-EXPORT_SYMBOL(amd7930_drecv);
-EXPORT_SYMBOL(amd7930_bopen);
-EXPORT_SYMBOL(amd7930_bclose);
-EXPORT_SYMBOL(amd7930_bxmit);
-EXPORT_SYMBOL(amd7930_brecv);
+struct foreign_interface amd7930_foreign_interface = {
+        amd7930_get_irqnum,
+        amd7930_get_liu_state,
+        amd7930_liu_init,
+        amd7930_liu_activate,
+        amd7930_liu_deactivate,
+        amd7930_dxmit,
+        amd7930_drecv,
+        amd7930_bopen,
+        amd7930_bclose,
+        amd7930_bxmit,
+        amd7930_brecv
+};
+EXPORT_SYMBOL(amd7930_foreign_interface);
 
 
 /*
index 8df1970619b8f45b1058149a4909bd455edeff50..adc058ee5d80cf7fdeaefed752e6572756993aad 100644 (file)
 
 #include <linux/types.h>
 
-/* Exported ISDN functions */
-
-int amd7930_get_irqnum(int dev);
-int amd7930_get_liu_state(int dev);
-void amd7930_liu_init(int dev, void (*callback)(), void *callback_arg);
-void amd7930_liu_activate(int dev, int priority);
-void amd7930_liu_deactivate(int dev);
-void amd7930_dxmit(int dev, __u8 *buffer, unsigned int count,
-                  void (*callback)(void *, int), void *callback_arg);
-void amd7930_drecv(int dev, __u8 *buffer, unsigned int size,
-                  void (*callback)(void *, int, unsigned int),
-                  void *callback_arg);
-int amd7930_bopen(int dev, int chan, u_char xmit_idle_char);
-void amd7930_bclose(int dev, int chan);
-void amd7930_bxmit(int dev, int chan, __u8 * buffer, unsigned long count,
-                  void (*callback)(void *), void *callback_arg);
-void amd7930_brecv(int dev, int chan, __u8 * buffer, unsigned long size,
-                  void (*callback)(void *), void *callback_arg);
-
-
 /* Register interface presented to the CPU by the amd7930. */
 struct amd7930
 {
index f708fb77f3c913aa5c0518801dcbc72422d9656c..8dc3fddd55c71eac46b0f632a0138d049b57d2f0 100644 (file)
@@ -1009,6 +1009,7 @@ static struct file_operations sparcaudio_fops = {
        sparcaudio_ioctl,
        NULL,                   /* sparcaudio_mmap */
        sparcaudio_open,
+        NULL,                   /* sparcaudio_flush */
        sparcaudio_release
 };
 
index 24a46097340599f6484327dfc26f3c64265ef1ee..717e9a3355d01f11e953b7efcceae7fcf1034a4c 100644 (file)
@@ -1008,7 +1008,7 @@ static void cs4231_playintr(struct sparcaudio_driver *drv)
     cs4231_chip->playlen = cs4231_chip->output_size;
 
   if (cs4231_chip->output_dma_handle) {
-      mmu_release_scsi_one((char *)cs4231_chip->output_dma_handle, 
+      mmu_release_scsi_one((u32)((unsigned long)cs4231_chip->output_dma_handle),
                            4096, drv->dev->my_bus);
       cs4231_chip->output_dma_handle = 0;
   }
@@ -1018,10 +1018,11 @@ static void cs4231_playintr(struct sparcaudio_driver *drv)
   }
 
   if (cs4231_chip->output_ptr && cs4231_chip->output_size > 0) {
-      cs4231_chip->output_next_dma_handle = 
-          mmu_get_scsi_one((char *) cs4231_chip->output_ptr, 4096, 
-                           drv->dev->my_bus);
-      cs4231_chip->regs->dmapnva = cs4231_chip->output_next_dma_handle;
+      cs4231_chip->output_next_dma_handle = (u32 *)(unsigned long)
+          mmu_get_scsi_one((char *) cs4231_chip->output_ptr,
+                           4096, drv->dev->my_bus);
+      cs4231_chip->regs->dmapnva = (u32) (unsigned long)
+              cs4231_chip->output_next_dma_handle;
       cs4231_chip->regs->dmapnc = cs4231_chip->output_size;
       cs4231_chip->output_size = 0;
       cs4231_chip->output_ptr = NULL;
@@ -1064,7 +1065,7 @@ static int cs4231_recintr(struct sparcaudio_driver *drv)
     cs4231_disable_rec(drv);    
   }
   if (cs4231_chip->input_ptr) {
-    cs4231_chip->regs->dmacnva = (__u32) cs4231_chip->input_ptr;
+    cs4231_chip->regs->dmacnva = (__u32) ((unsigned long)cs4231_chip->input_ptr);
     cs4231_chip->regs->dmacnc = cs4231_chip->input_size;
     cs4231_chip->input_ptr = NULL;
     cs4231_chip->input_size = 0;
@@ -1108,12 +1109,12 @@ static void cs4231_stop_output(struct sparcaudio_driver *drv)
   cs4231_chip->output_ptr = NULL;
   cs4231_chip->output_size = 0;
   if (cs4231_chip->output_dma_handle) {
-      mmu_release_scsi_one((char *)cs4231_chip->output_dma_handle,
+      mmu_release_scsi_one((u32)((unsigned long)cs4231_chip->output_dma_handle),
                            4096, drv->dev->my_bus);
       cs4231_chip->output_dma_handle = 0;
   }
   if (cs4231_chip->output_next_dma_handle) {
-      mmu_release_scsi_one((char *)cs4231_chip->output_next_dma_handle,
+      mmu_release_scsi_one((u32)((unsigned long)cs4231_chip->output_next_dma_handle),
                            4096, drv->dev->my_bus);
       cs4231_chip->output_next_dma_handle = 0;
   }
index 5699500621398bb0726480f5d8ba687344e80beb..198386cebe9e8023400ef7c976b71f4331af525b 100644 (file)
@@ -48,7 +48,7 @@ struct cs4231_chip {
   /* Current buffer that the driver is playing. */
   volatile __u8 * output_ptr;
   volatile unsigned long output_size;
-  volatile __u32 * output_dma_handle, output_next_dma_handle;
+  volatile __u32 * output_dma_handle, output_next_dma_handle;
 
   /* Current record buffer. */
   volatile __u8 * input_ptr;
index d65a2e964294707ba38ba86c6b4cd05e51e9c981..382ee4bc77901125cb16abd2e5ce045c63753604 100644 (file)
 #include <asm/audioio.h>
 #include "dbri.h"
 
+#include "../../isdn/hisax/hisax.h"
+#include "../../isdn/hisax/isdnl1.h"
+#include "../../isdn/hisax/foreign.h"
 
 
-#define DBRI_DEBUG
+/* #define DBRI_DEBUG */
 
 #ifdef DBRI_DEBUG
 
@@ -103,35 +106,59 @@ static char *cmds[] = {
 
 static struct sparcaudio_driver drivers[MAX_DRIVERS];
 static char drv_name[] = "DBRI/audio";
-static int num_drivers;
-static int dbri_cmdlocked = 0;
+static int num_drivers = 0;
 
 static void * output_callback_arg;
 
 /*
- * Make sure, that we can send a command to the dbri
+ * Commands are sent to the DBRI by building a list of them in memory,
+ * then writing the address of the first list item to DBRI register 8.
+ * The list is terminated with a WAIT command, which can generate a
+ * CPU interrupt if required.
+ *
+ * Since the DBRI can run asynchronously to the CPU, several means of
+ * synchronization present themselves.  The original scheme (Rudolf's)
+ * was to set a flag when we "cmdlock"ed the DBRI, clear the flag when
+ * an interrupt signaled completion, and wait on a wait_queue if a routine
+ * attempted to cmdlock while the flag was set.  The problems arose when
+ * we tried to cmdlock from inside an interrupt handler, which might
+ * cause scheduling in an interrupt (if we waited), etc, etc
+ *
+ * A more sophisticated scheme might involve a circular command buffer
+ * or an array of command buffers.  A routine could fill one with
+ * commands and link it onto a list.  When a interrupt signaled
+ * completion of the current command buffer, look on the list for
+ * the next one.
+ *
+ * I've decided to implement something much simpler - after each command,
+ * the CPU waits for the DBRI to finish the command by polling the P bit
+ * in DBRI register 0.  I've tried to implement this in such a way
+ * that might make implementing a more sophisticated scheme easier.
+ *
+ * Every time a routine wants to write commands to the DBRI, it
+ * must first call dbri_cmdlock() and get an initial index into dbri->cmd
+ * (currently always 0) in return.  After the commands have been
+ * write (index incremented after each one), dbri_cmdsend() is called
+ * with the final index value.
  */
+
 static int dbri_cmdlock(struct dbri *dbri)
 {
-       unsigned long flags;
-       int was_sleeping = 0;
+       return 0;
+}
 
-       save_flags(flags);
-       cli();
+static void dbri_cmdsend(struct dbri *dbri, int n)
+{
+       int maxloops = 1000000;
 
-       if(dbri_cmdlocked) {
-               interruptible_sleep_on(&dbri->wait);
-               was_sleeping = 1;
-       }
-       if(dbri_cmdlocked)
-               return -EINTR;
-       dbri_cmdlocked = 1;
+       dbri->cmd[n++] = DBRI_CMD(D_WAIT, 0, WAIT_INTR1);
+       dbri->regs->reg8 = (int)dbri->cmd;
 
-       restore_flags(flags);
+       while (maxloops > 0 && (dbri->regs->reg0 & D_P));
 
-       if(was_sleeping)
-               dprintk(D_INT, ("DBRI: Just woke up\n"));
-       return 0;
+       if (maxloops == 0) {
+               printk("DBRI: Maxloops exceeded in dbri_cmdsend\n");
+       }
 }
 
 static void dbri_reset(struct sparcaudio_driver *drv)
@@ -191,13 +218,12 @@ static void dbri_initialize(struct sparcaudio_driver *drv)
        /*
         * Set up the interrupt queue
         */
-       (void)dbri_cmdlock(dbri);
+       n = dbri_cmdlock(dbri);
 
-       n = 0;
        dbri->cmd[n++] = DBRI_CMD(D_IIQ, 0, 0);
        dbri->cmd[n++] = (int)(dbri->intr);
-       dbri->cmd[n++] = DBRI_CMD(D_WAIT, 1, WAIT_INTR1);
-       dbri->regs->reg8 = (int)dbri->cmd;
+
+       dbri_cmdsend(dbri, n);
 }
 
 
@@ -250,9 +276,9 @@ static void mmcodec_default(struct cs4215 *mm)
 
 static void mmcodec_init_data(struct dbri *dbri)
 {
-       int val, n = 0;
+       int val, n;
 
-       dbri_cmdlock(dbri);
+       n = dbri_cmdlock(dbri);
 
        /*
         * Data mode:
@@ -340,9 +366,7 @@ static void mmcodec_init_data(struct dbri *dbri)
         /* CHI: Slave mode; enable interrupts */
        dbri->cmd[n++] = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(0) | D_CHI_IR | D_CHI_EN);
 
-       dbri->cmd[n++] = DBRI_CMD(D_WAIT, 0, WAIT_INTR1);
-
-       dbri->regs->reg8 = (int)dbri->cmd;
+       dbri_cmdsend(dbri, n);
 }
 
 
@@ -351,7 +375,7 @@ static void mmcodec_init_data(struct dbri *dbri)
  */
 static void mmcodec_setctrl(struct dbri *dbri)
 {
-       int n = 0, val;
+       int n, val;
 
        /*
         * Enable Control mode: Set DBRI's PIO3 (4215's D/~C) to 0, then wait
@@ -380,7 +404,7 @@ static void mmcodec_setctrl(struct dbri *dbri)
          * by eight clock cycles.  Anybody know why?
          */
 
-       dbri_cmdlock(dbri);
+       n = dbri_cmdlock(dbri);
 
        /*
         * Control mode:
@@ -462,32 +486,24 @@ static void mmcodec_setctrl(struct dbri *dbri)
        dbri->cmd[n++] = DBRI_CMD(D_CDM, 0, D_CDM_XCE|D_CDM_XEN|D_CDM_REN);
        dbri->cmd[n++] = DBRI_CMD(D_PAUSE, 0, 0);
 
-       dbri->cmd[n++] = DBRI_CMD(D_WAIT, 1, WAIT_INTR1);
-       dbri->regs->reg8 = (int)dbri->cmd;
-
-
-       /* Wait for the data from the CS4215 */
-        interruptible_sleep_on(&dbri->int_wait);
+       /* Wait for the command to complete */
+       dbri_cmdsend(dbri, n);
 
         /* Switch CS4215 to data mode - data sheet says
          * "Set CLB=1 and send two more frames of valid control info"
          */
-       dbri_cmdlock(dbri);
+       n = dbri_cmdlock(dbri);
 
-        n = 0;
        dbri->mm.ctrl[0] |= CS4215_CLB;
        dbri->cmd[n++] = DBRI_CMD(D_SSP, 0, D_PIPE(D_P_17));
        dbri->cmd[n++] = reverse_bytes(*(int *)dbri->mm.ctrl, 4);
 
-       dbri->cmd[n++] = DBRI_CMD(D_WAIT, 1, WAIT_INTR1);
-       dbri->regs->reg8 = (int)dbri->cmd;
-
-        dbri_cmdlock(dbri);
+        dbri_cmdsend(dbri, n);
 
         /* Two frames of control info @ 8kHz frame rate = 250 us delay */
         udelay(250);
 
-       n = 0;
+       n = dbri_cmdlock(dbri);
 
        /* Now switch back to data mode */
        /* Reset CHI Anchor: Stop Send/Receive */
@@ -504,15 +520,8 @@ static void mmcodec_setctrl(struct dbri *dbri)
        dbri->cmd[n++] = DBRI_CMD(D_PAUSE, 0, 0x16);
 
 
-       dbri->cmd[n++] = DBRI_CMD(D_WAIT, 1, WAIT_INTR1);
-       dbri->regs->reg8 = (int)dbri->cmd;
-
         /* Wait for command to complete */
-        dbri_cmdlock(dbri);
-        n = 0;
-       dbri->cmd[n++] = DBRI_CMD(D_WAIT, 1, WAIT_INTR1);
-       dbri->regs->reg8 = (int)dbri->cmd;
-
+        dbri_cmdsend(dbri, n);
 
         /* Switch CS4215 to data mode - set PIO3 to 1 */
        dbri->regs->reg2 = D_ENPIO | D_PIO1 | D_PIO3 |
@@ -563,6 +572,95 @@ static int mmcodec_init(struct sparcaudio_driver *drv)
        return 0;
 }
 
+void dbri_isdn_init(struct dbri *dbri)
+{
+        int n, val;
+
+        /* Pipe  0: Receive D channel
+         * Pipe  8: Receive B1 channel
+         * Pipe  9: Receive B2 channel
+         * Pipe  1: Transmit D channel
+         * Pipe 10: Transmit B1 channel
+         * Pipe 11: Transmit B2 channel
+         */
+
+        n = dbri_cmdlock(dbri);
+
+       /* Pipe 0: SDP */
+       val = D_SDP_HDLC|D_SDP_FROM_SER|D_SDP_C|D_SDP_P|D_SDP_LSB|D_PIPE(D_P_0);
+       dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
+       dbri->cmd[n++] = 0;
+
+       /* Pipe 8: SDP */
+       val = D_SDP_HDLC|D_SDP_FROM_SER|D_SDP_C|D_SDP_P|D_SDP_LSB|D_PIPE(D_P_8);
+       dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
+       dbri->cmd[n++] = 0;
+
+       /* Pipe 9: SDP */
+       val = D_SDP_HDLC|D_SDP_FROM_SER|D_SDP_C|D_SDP_P|D_SDP_LSB|D_PIPE(D_P_9);
+       dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
+       dbri->cmd[n++] = 0;
+
+       /* Pipe 1: SDP */
+       val = D_SDP_HDLC_D|D_SDP_TO_SER|D_SDP_C|D_SDP_P|D_SDP_LSB|D_PIPE(D_P_1);
+       dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
+       dbri->cmd[n++] = 0;
+
+       /* Pipe 10: SDP */
+       val = D_SDP_HDLC|D_SDP_TO_SER|D_SDP_C|D_SDP_P|D_SDP_LSB|D_PIPE(D_P_10);
+       dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
+       dbri->cmd[n++] = 0;
+
+       /* Pipe 11: SDP */
+       val = D_SDP_HDLC|D_SDP_TO_SER|D_SDP_C|D_SDP_P|D_SDP_LSB|D_PIPE(D_P_11);
+       dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
+       dbri->cmd[n++] = 0;
+
+
+       dbri->cmd[n++] = DBRI_CMD(D_PAUSE, 0, 0);
+
+        /* Pipe 0: DTS */
+       val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(D_P_0) | D_PIPE(D_P_0);
+       dbri->cmd[n++] = DBRI_CMD(D_DTS, 0, val);
+       dbri->cmd[n++] = D_TS_LEN(2) | D_TS_CYCLE(17)| D_TS_NEXT(D_P_0);
+       dbri->cmd[n++] = 0;
+
+        /* Pipe 8: DTS */
+       val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(D_P_0) | D_PIPE(D_P_8);
+       dbri->cmd[n++] = DBRI_CMD(D_DTS, 0, val);
+       dbri->cmd[n++] = D_TS_LEN(8) | D_TS_CYCLE(0)| D_TS_NEXT(D_P_0);
+       dbri->cmd[n++] = 0;
+
+        /* Pipe 9: DTS */
+       val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(D_P_8) | D_PIPE(D_P_9);
+       dbri->cmd[n++] = DBRI_CMD(D_DTS, 0, val);
+       dbri->cmd[n++] = D_TS_LEN(8) | D_TS_CYCLE(8)| D_TS_NEXT(D_P_0);
+       dbri->cmd[n++] = 0;
+
+        /* Pipe 1: DTS */
+       val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(D_P_1) | D_PIPE(D_P_1);
+       dbri->cmd[n++] = DBRI_CMD(D_DTS, 0, val);
+       dbri->cmd[n++] = 0;
+       dbri->cmd[n++] = D_TS_LEN(2) | D_TS_CYCLE(17)| D_TS_NEXT(D_P_1);
+
+        /* Pipe 10: DTS */
+       val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(D_P_1) | D_PIPE(D_P_10);
+       dbri->cmd[n++] = DBRI_CMD(D_DTS, 0, val);
+       dbri->cmd[n++] = 0;
+       dbri->cmd[n++] = D_TS_LEN(8) | D_TS_CYCLE(0)| D_TS_NEXT(D_P_1);
+
+        /* Pipe 11: DTS */
+       val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(D_P_10) | D_PIPE(D_P_11);
+       dbri->cmd[n++] = DBRI_CMD(D_DTS, 0, val);
+       dbri->cmd[n++] = 0;
+       dbri->cmd[n++] = D_TS_LEN(8) | D_TS_CYCLE(8)| D_TS_NEXT(D_P_1);
+
+
+        /* Wait for command to complete */
+       dbri_cmdsend(dbri, n);
+}
+
+
 void dbri_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct sparcaudio_driver *drv = (struct sparcaudio_driver *)dev_id;
@@ -610,8 +708,16 @@ void dbri_intr(int irq, void *dev_id, struct pt_regs *regs)
 
                val = D_INTR_GETVAL(x);
 
+                if (D_INTR_GETCODE(x) == D_INTR_SBRI) {
+                        int liu_states[] = {1, 0, 8, 3, 4, 5, 6, 7};
+                        dbri->liu_state = liu_states[val & 0x7];
+                        if (dbri->liu_callback)
+                                dbri->liu_callback(dbri->liu_callback_arg);
+                }
+
                switch(D_INTR_GETCHAN(x)) {
                        case D_INTR_CMD:
+#if 0
                                if(D_INTR_GETCMD(x) == D_WAIT)
                                        if(val == WAIT_INTR1) {
                                                dbri_cmdlocked = 0;
@@ -619,25 +725,86 @@ void dbri_intr(int irq, void *dev_id, struct pt_regs *regs)
                                        }
                                        if(val == WAIT_INTR2)
                                                wake_up(&dbri->int_wait);
+#endif
                                break;
+
+                        case D_P_0:
+                                /* Pipe 0 - D channel receive */
+                                if (D_INTR_GETCODE(x) == D_INTR_BRDY &&
+                                    dbri->D.input_callback) {
+                                        dbri->D.input_callback(dbri->D.input_callback_arg,
+                                                               DBRI_RD_STATUS(dbri->D.rd.flags),
+                                                               DBRI_RD_CNT(dbri->D.rd.flags)-2);
+                                }
+                                break;
+
+                        case D_P_1:
+                                /* Pipe 1 - D channel transmit */
+                                if (D_INTR_GETCODE(x) == D_INTR_XCMP &&
+                                    dbri->D.output_callback) {
+                                        dbri->D.output_callback(dbri->D.output_callback_arg,
+                                                                DBRI_TD_STATUS(dbri->D.rd.flags)&0xe);
+                                }
+                                break;
+
                        case D_P_4:
+                                /* Pipe 4 - audio transmit */
                                if (D_INTR_GETCODE(x) == D_INTR_XCMP) {
                                        sparcaudio_output_done(output_callback_arg, 1);
                                }
                                break;
 
+                        case D_P_8:
+                                /* Pipe 8 - B1 channel receive */
+                                if (D_INTR_GETCODE(x) == D_INTR_BRDY &&
+                                    dbri->B[0].input_callback) {
+                                        dbri->B[0].input_callback(dbri->B[0].input_callback_arg,
+                                                                  DBRI_RD_STATUS(dbri->B[0].rd.flags),
+                                                                  DBRI_RD_CNT(dbri->B[0].rd.flags)-2);
+                                }
+                                break;
+
+                        case D_P_9:
+                                /* Pipe 9 - B2 channel receive */
+                                if (D_INTR_GETCODE(x) == D_INTR_BRDY &&
+                                    dbri->B[1].input_callback) {
+                                        dbri->B[1].input_callback(dbri->B[1].input_callback_arg,
+                                                                DBRI_RD_STATUS(dbri->B[1].rd.flags),
+                                                                DBRI_RD_CNT(dbri->B[1].rd.flags)-2);
+                                }
+                                break;
+
+                        case D_P_10:
+                                /* Pipe 10 - B1 channel transmit */
+                                if (D_INTR_GETCODE(x) == D_INTR_XCMP &&
+                                    dbri->B[0].output_callback) {
+                                        dbri->B[0].output_callback(dbri->B[0].output_callback_arg,
+                                                                   DBRI_TD_STATUS(dbri->B[0].rd.flags)&0xfe);
+                                }
+                                break;
+
+                        case D_P_11:
+                                /* Pipe 11 - B2 channel transmit */
+                                if (D_INTR_GETCODE(x) == D_INTR_XCMP &&
+                                    dbri->B[1].output_callback) {
+                                        dbri->B[1].output_callback(dbri->B[1].output_callback_arg,
+                                                                   DBRI_TD_STATUS(dbri->B[1].rd.flags)&0xfe);
+                                }
+                                break;
+
                        case D_P_18:
+                                /* Pipe 18 - receive CS4215 status */
                                if(val != 0) {
                                        x = reverse_bytes(val,2)&CS4215_12_MASK;
-printk("Comparing int: %x with hi(%x)\n", x, *(int *)dbri->mm.ctrl);
-                                       if(x == (*(int *)dbri->mm.ctrl >> 16))
-{
-printk("Comp ok\n");
+                                        printk("Comparing int: %x with hi(%x)\n", x, *(int *)dbri->mm.ctrl);
+                                       if(x == (*(int *)dbri->mm.ctrl >> 16)) {
+                                                printk("Comp ok\n");
                                                wake_up(&dbri->int_wait);
-}
+                                        }
                                }
                                break;
                        case D_P_19:
+                                /* Pipe 19 - receive CS4215 version */
                                if(val != 0) {
                                        dbri->mm.version = 
                                                reverse_bytes(val, 1) & 0xf;
@@ -693,17 +860,14 @@ static void dbri_start_output(struct sparcaudio_driver *drv,
                               __u8 * buffer, unsigned long count)
 {
        struct dbri *dbri = (struct dbri *)drv->private;
-        int val, n = 0;
+        int val, n;
 
-        /* XXX - This routine can be called via interrupt.  If DBRI
-         * was cmdlocked, that would cause a sleep, which would be
-         * scheduling in an interrupt, and that's not allowed
-         *
-         * Fortunately, there's nothing else talking to our DBRI (yet),
-         * so this isn't a problem (yet)
-         */
+        if (count > (1 << 14) - 1) {
+                printk("dbri_start_output called with count=%d; truncated", count);
+                count = (1 << 14) - 1;
+        }
 
-        dbri_cmdlock(dbri);
+        n = dbri_cmdlock(dbri);
 
         dbri->mm.td.flags = DBRI_TD_F | DBRI_TD_B | DBRI_TD_D | DBRI_TD_CNT(count);
         dbri->mm.td.ba = (__u32) buffer;
@@ -715,11 +879,9 @@ static void dbri_start_output(struct sparcaudio_driver *drv,
        dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
        dbri->cmd[n++] = (__u32)&dbri->mm.td;
 
-       dbri->cmd[n++] = DBRI_CMD(D_WAIT, 0, WAIT_INTR1);
-
-       dbri->regs->reg8 = (int)dbri->cmd;
-
         output_callback_arg = drv;
+
+       dbri_cmdsend(dbri, n);
 }
 
 static void dbri_stop_output(struct sparcaudio_driver *drv)
@@ -774,6 +936,341 @@ static struct sparcaudio_operations dbri_ops = {
 };
 
 
+/*
+****************************************************************************
+************************** ISDN (Hisax) Interface **************************
+****************************************************************************
+*/
+
+
+int dbri_get_irqnum(int dev)
+{
+       struct dbri *dbri;
+
+       if (dev >= num_drivers) {
+               return(0);
+       }
+
+       dbri = (struct dbri *) drivers[dev].private;
+
+        /* On the sparc, the cpu's irq number is only part of the "irq" */
+       return (dbri->irq & NR_IRQS);
+}
+
+int dbri_get_liu_state(int dev)
+{
+       struct dbri *dbri;
+
+       if (dev >= num_drivers) {
+               return(0);
+       }
+
+       dbri = (struct dbri *) drivers[dev].private;
+
+       return dbri->liu_state;
+}
+
+void dbri_liu_init(int dev, void (*callback)(void *), void *callback_arg)
+{
+       struct dbri *dbri;
+
+       if (dev >= num_drivers) {
+               return;
+       }
+
+       dbri = (struct dbri *) drivers[dev].private;
+
+       /* Set callback for LIU state change */
+        dbri->liu_callback = callback;
+       dbri->liu_callback_arg = callback_arg;
+
+        dbri_isdn_init(dbri);
+}
+
+void dbri_liu_activate(int dev, int priority)
+{
+       struct dbri *dbri;
+        int n, val;
+
+       if (dev >= num_drivers) {
+               return;
+       }
+
+       dbri = (struct dbri *) drivers[dev].private;
+
+        n = dbri_cmdlock(dbri);
+
+        /* Turn on the ISDN TE interface and request activation */
+        val = D_NT_IRM_IMM | D_NT_IRM_EN | D_NT_ACT;
+        dbri->cmd[n++] = DBRI_CMD(D_TE, 0, val);
+
+       dbri_cmdsend(dbri, n);
+
+        /* Activate the interface */
+        dbri->regs->reg0 |= D_T;
+}
+
+void dbri_liu_deactivate(int dev)
+{
+       struct dbri *dbri;
+
+       if (dev >= num_drivers) {
+               return;
+       }
+
+       dbri = (struct dbri *) drivers[dev].private;
+
+        /* Turn off the ISDN TE interface */
+        dbri->regs->reg0 &= ~D_T;
+}
+
+void dbri_dxmit(int dev, __u8 *buffer, unsigned int count,
+                       void (*callback)(void *, int), void *callback_arg)
+{
+       struct dbri *dbri;
+        int n, val;
+
+       if (dev >= num_drivers) {
+               return;
+       }
+
+       dbri = (struct dbri *) drivers[dev].private;
+
+        if (count > (1 << 14) - 1) {
+                printk("dbri_dxmit called with count=%d; truncated", count);
+                count = (1 << 14) - 1;
+        }
+
+        n = dbri_cmdlock(dbri);
+
+        /* XXX - Shouldn't I check to make sure D.td isn't is use? */
+
+        dbri->D.td.flags = DBRI_TD_F | DBRI_TD_B | DBRI_TD_CNT(count) | DBRI_TD_I;
+        dbri->D.td.ba = (__u32) buffer;
+        dbri->D.td.nda = 0;
+        dbri->D.td.status = 0;
+
+        /* Pipe 1 is D channel transmit */
+       val = D_SDP_HDLC_D|D_SDP_TO_SER|D_SDP_C|D_SDP_P|D_SDP_LSB|D_PIPE(D_P_1);
+       dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
+       dbri->cmd[n++] = (__u32)&dbri->D.td;
+
+        dbri->D.output_callback = callback;
+        dbri->D.output_callback_arg = callback_arg;
+
+       dbri_cmdsend(dbri, n);
+}
+
+void dbri_drecv(int dev, __u8 *buffer, unsigned int size,
+                       void (*callback)(void *, int, unsigned int),
+                       void *callback_arg)
+{
+       struct dbri *dbri;
+        int n, val;
+
+       if (dev >= num_drivers) {
+               return;
+       }
+
+       dbri = (struct dbri *) drivers[dev].private;
+
+        if (size > (1 << 14) - 1) {
+                printk("dbri_drecv called with size=%d; truncated", size);
+                size = (1 << 14) - 1;
+        }
+
+        /* Make sure size is a multiple of four */
+        size &= ~3;
+
+        n = dbri_cmdlock(dbri);
+
+        /* XXX - Shouldn't I check to make sure D.rd isn't is use? */
+
+        dbri->D.rd.flags = 0;
+        dbri->D.rd.ba = (__u32) buffer;
+        dbri->D.rd.nda = 0;
+        dbri->D.rd.status = DBRI_RD_B | DBRI_RD_BCNT(size);
+
+        /* Pipe 0 is D channel receive */
+       val = D_SDP_HDLC|D_SDP_FROM_SER|D_SDP_C|D_SDP_P|D_SDP_LSB|D_PIPE(D_P_0);
+       dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
+       dbri->cmd[n++] = (__u32)&dbri->D.rd;
+
+       dbri_cmdsend(dbri, n);
+
+        dbri->D.input_callback = callback;
+        dbri->D.input_callback_arg = callback_arg;
+}
+
+int dbri_bopen(int dev, unsigned int chan,
+               int hdlcmode, u_char xmit_idle_char)
+{
+       struct dbri *dbri;
+        int n, val;
+
+       if (dev >= num_drivers || chan > 1) {
+               return -1;
+       }
+
+       dbri = (struct dbri *) drivers[dev].private;
+
+        if (hdlcmode) {
+
+                return -1;
+
+                /* Pipe 8/9: receive B1/B2 channel */
+                dbri->B[chan].recvSDP = D_SDP_HDLC|D_SDP_FROM_SER|D_SDP_P|D_SDP_LSB|D_PIPE(D_P_8+chan);
+
+                /* Pipe 10/11: transmit B1/B2 channel */
+                dbri->B[chan].xmitSDP = D_SDP_HDLC|D_SDP_TO_SER|D_SDP_P|D_SDP_LSB|D_PIPE(D_P_10+chan);
+
+        } else {        /* !hdlcmode means transparent */
+
+                /* Pipe 8/9: receive B1/B2 channel */
+                dbri->B[chan].recvSDP = D_SDP_MEM|D_SDP_FROM_SER|D_SDP_P|D_SDP_LSB|D_PIPE(D_P_8+chan);
+
+                /* Pipe 10/11: transmit B1/B2 channel */
+                dbri->B[chan].xmitSDP = D_SDP_MEM|D_SDP_TO_SER|D_SDP_P|D_SDP_LSB|D_PIPE(D_P_10+chan);
+
+        }
+
+        n = dbri_cmdlock(dbri);
+
+        /* Pipe 8/9: receive B1/B2 channel */
+        val = dbri->B[chan].recvSDP | D_SDP_C;
+        dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
+        dbri->cmd[n++] = 0;
+
+        /* Pipe 10/11: transmit B1/B2 channel */
+        val = dbri->B[chan].xmitSDP | D_SDP_C;
+        dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
+        dbri->cmd[n++] = 0;
+
+        dbri->B[chan].output_callback = NULL;
+        dbri->B[chan].input_callback = NULL;
+
+       dbri_cmdsend(dbri, n);
+
+        return 0;
+}
+
+void dbri_bclose(int dev, unsigned int chan)
+{
+       struct dbri *dbri;
+
+       if (dev >= num_drivers || chan > 1) {
+               return;
+       }
+
+       dbri = (struct dbri *) drivers[dev].private;
+
+        dbri->B[chan].output_callback = NULL;
+        dbri->B[chan].input_callback = NULL;
+}
+
+void dbri_bxmit(int dev, unsigned int chan,
+                       __u8 *buffer, unsigned long count,
+                       void (*callback)(void *, int),
+                       void *callback_arg)
+{
+       struct dbri *dbri;
+        int n, val;
+
+       if (dev >= num_drivers || chan > 1) {
+               return;
+       }
+
+       dbri = (struct dbri *) drivers[dev].private;
+
+        if (count > (1 << 14) - 1) {
+                printk("dbri_bxmit called with count=%ld; truncated", count);
+                count = (1 << 14) - 1;
+        }
+
+        n = dbri_cmdlock(dbri);
+
+        /* XXX - Shouldn't I check to make sure td isn't is use? */
+
+        dbri->B[chan].td.flags = DBRI_TD_F | DBRI_TD_B | DBRI_TD_CNT(count);
+        dbri->B[chan].td.ba = (__u32) buffer;
+        dbri->B[chan].td.nda = 0;
+        dbri->B[chan].td.status = 0;
+
+        /* Pipe 10/11 is B1/B2 channel transmit */
+       val = dbri->B[chan].xmitSDP;
+       dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
+       dbri->cmd[n++] = (__u32)&dbri->B[chan].td;
+
+        dbri->B[chan].output_callback = callback;
+        dbri->B[chan].output_callback_arg = callback_arg;
+
+       dbri_cmdsend(dbri, n);
+}
+
+void dbri_brecv(int dev, unsigned int chan,
+                       __u8 *buffer, unsigned long size,
+                       void (*callback)(void *, int, unsigned int),
+                       void *callback_arg)
+{
+       struct dbri *dbri;
+        int n, val;
+
+       if (dev >= num_drivers || chan > 1) {
+               return;
+       }
+
+       dbri = (struct dbri *) drivers[dev].private;
+
+        if (size > (1 << 14) - 1) {
+                printk("dbri_brecv called with size=%ld; truncated", size);
+                size = (1 << 14) - 1;
+        }
+
+        /* Make sure size is a multiple of four */
+        size &= ~3;
+
+        n = dbri_cmdlock(dbri);
+
+        /* XXX - Shouldn't I check to make sure RD isn't is use? */
+
+        dbri->B[chan].rd.flags = 0;
+        dbri->B[chan].rd.ba = (__u32) buffer;
+        dbri->B[chan].rd.nda = 0;
+        dbri->B[chan].rd.status = DBRI_RD_B | DBRI_RD_BCNT(size);
+
+        /* Pipe 8/9 is B1/B2 channel receive */
+       val = dbri->B[chan].recvSDP;
+       dbri->cmd[n++] = DBRI_CMD(D_SDP, 0, val);
+       dbri->cmd[n++] = (__u32)&dbri->B[chan].rd;
+
+       dbri_cmdsend(dbri, n);
+
+        dbri->B[chan].input_callback = callback;
+        dbri->B[chan].input_callback_arg = callback_arg;
+}
+
+struct foreign_interface dbri_foreign_interface = {
+        dbri_get_irqnum,
+        dbri_get_liu_state,
+        dbri_liu_init,
+        dbri_liu_activate,
+        dbri_liu_deactivate,
+        dbri_dxmit,
+        dbri_drecv,
+        dbri_bopen,
+        dbri_bclose,
+        dbri_bxmit,
+        dbri_brecv
+};
+EXPORT_SYMBOL(dbri_foreign_interface);
+
+/*
+****************************************************************************
+**************************** Initialization ********************************
+****************************************************************************
+*/
+
+
 static int dbri_attach(struct sparcaudio_driver *drv, 
                         struct linux_sbus_device *sdev)
 {
@@ -901,12 +1398,12 @@ void cleanup_module(void)
  * of the file.
  * ---------------------------------------------------------------------------
  * Local variables:
- * c-indent-level: 4
+ * c-indent-level: 8
  * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
  * c-continued-brace-offset: 0
  * indent-tabs-mode: nil
  * tab-width: 8
index 0bb9d67b0dc858b70cbe02cf65de8e863f6bf68c..2dc9a8d378959026184799badc22bbd723c9ba59 100644 (file)
@@ -33,6 +33,17 @@ struct dbri_mem {
        __u32   status;
 };
 
+struct dbri_channel {
+        struct dbri_mem td;
+        struct dbri_mem rd;
+        unsigned int recvSDP;
+        unsigned int xmitSDP;
+        void (*output_callback)(void *, int);
+        void *output_callback_arg;
+        void (*input_callback)(void *, int, unsigned int);
+        void *input_callback_arg;
+};
+
 #include "cs4215.h"
 
 /* This structure holds the information for both chips (DBRI & CS4215) */
@@ -49,6 +60,15 @@ struct dbri {
  
   struct wait_queue *wait, *int_wait;          /* Where to sleep if busy */
   struct audio_info perchip_info;
+
+  /* Track ISDN LIU and notify changes */
+  int liu_state;
+  void (*liu_callback)(void *);
+  void *liu_callback_arg;
+
+  /* Callback routines and descriptors for ISDN channels */
+  struct dbri_channel D;
+  struct dbri_channel B[2];
 };
 
 
@@ -109,7 +129,7 @@ struct dbri {
 
 
 /* Special bits for some commands */
-#define D_PIPE(v)      (v<<0)  /* Pipe Nr: 0-15 long, 16-21 short */
+#define D_PIPE(v)      ((v)<<0)        /* Pipe Nr: 0-15 long, 16-21 short */
 
 /* Setup Data Pipe */
 /* IRM */
@@ -139,8 +159,8 @@ struct dbri {
 #define D_DTS_VO       (1<<16) /* Valid Output Time-Slot Descriptor */
 #define D_DTS_INS      (1<<15) /* Insert Time Slot */
 #define D_DTS_DEL      (0<<15) /* Delete Time Slot */
-#define D_DTS_PRVIN(v) (v<<10) /* Previous In Pipe */
-#define D_DTS_PRVOUT(v)        (v<<5)  /* Previous Out Pipe */
+#define D_DTS_PRVIN(v) ((v)<<10) /* Previous In Pipe */
+#define D_DTS_PRVOUT(v)        ((v)<<5)  /* Previous Out Pipe */
 
 /* Time Slot defines */
 #define D_TS_LEN(v)    (v<<24) /* Number of bits in this time slot */
@@ -150,8 +170,8 @@ struct dbri {
 #define D_TS_MONITOR   (2<<10) /* Monitor pipe */
 #define D_TS_NONCONTIG (3<<10) /* Non contiguous mode */
 #define D_TS_ANCHOR    (7<<10) /* Starting short pipes */
-#define D_TS_MON(v)    (v<<5)  /* Monitor Pipe */
-#define D_TS_NEXT(v)   (v<<0)  /* Pipe Nr: 0-15 long, 16-21 short */
+#define D_TS_MON(v)    ((v)<<5)        /* Monitor Pipe */
+#define D_TS_NEXT(v)   ((v)<<0)        /* Pipe Nr: 0-15 long, 16-21 short */
 
 /* Concentration Highway Interface Modes */
 #define D_CHI_CHICM(v) (v<<16) /* Clock mode */
@@ -276,17 +296,19 @@ struct dbri {
 #define DBRI_TD_UNR    (1<<3)  /* Underrun: transmitter is out of data */
 #define DBRI_TD_ABT    (1<<2)  /* Abort: frame aborted */
 #define DBRI_TD_TBC    (1<<0)  /* Transmit buffer Complete */
+#define DBRI_TD_STATUS(v)      ((v)&0xff)      /* Transmit status */
 
 /* Receive descriptor defines */
 #define DBRI_RD_F      (1<<31) /* End of Frame */
 #define DBRI_RD_C      (1<<30) /* Completed buffer */
 #define DBRI_RD_B      (1<<15) /* Final interrupt */
 #define DBRI_RD_M      (1<<14) /* Marker interrupt */
-#define DBRI_RD_CNT(v) (v<<16) /* Number of valid bytes in the buffer */
 #define DBRI_RD_BCNT(v)        v       /* Buffer size */
 #define DBRI_RD_CRC    (1<<7)  /* 0: CRC is correct */
 #define DBRI_RD_BBC    (1<<6)  /* 1: Bad Byte recieved */
 #define DBRI_RD_ABT    (1<<5)  /* Abort: frame aborted */
 #define DBRI_RD_OVRN   (1<<3)  /* Overrun: data lost */
+#define DBRI_RD_STATUS(v)      ((v)&0xff)      /* Receive status */
+#define DBRI_RD_CNT(v) ((v>>16)&0x1fff)        /* Number of valid bytes in the buffer */
 
 #endif /* _DBRI_H_ */
index ec75114fed2d9fb8ac8482969aa90251f0d7d579..a64f823c2d9c5c72e2f98ca6b6ec593c8efc3bbe 100644 (file)
@@ -50,7 +50,7 @@ endif
 else # !eq($(ARCH),sparc64)
 
 ifeq ($(CONFIG_PCI),y)
-O_OBJS += su32.o pcikbd.o
+O_OBJS += su.o pcikbd.o
 endif
 
 endif # !eq($(ARCH),sparc64)
index fb5088b4e045c8574e1b7c9e0d385244f4dae371..fbc93415db049ef90b1c6d3317e8fd8da55a87a7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: envctrl.c,v 1.8 1998/08/26 10:29:40 davem Exp $
+/* $Id: envctrl.c,v 1.9 1998/11/06 07:38:20 ecd Exp $
  * envctrl.c: Temperature and Fan monitoring on Machines providing it.
  *
  * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
@@ -115,10 +115,7 @@ i2c_read(unsigned char dev, char *buffer, int len, int user)
        unsigned char dummy;
        unsigned char stat;
        int error = -ENODEV;
-       int count = -1;
-
-       if (len == 0)
-               return 0;
+       int count = 0;
 
        i2c->data = (dev << 1) | I2C_READ;
 
@@ -134,21 +131,26 @@ i2c_read(unsigned char dev, char *buffer, int len, int user)
 
                if (stat & STATUS_LRB)
                        goto stop;
+
                error = 0;
-               if (count == (len - 2))
-                       goto final;
+               if (len == 0) {
+                       count--;
+                       break;
+               }
 
-               if (++count > 0) {
+               if (count == (len - 1))
+                       break;
+
+               if (count++ > 0) {
                        error = PUT_DATA(&i2c->data, buffer++, user);
                        if (error)
-                               goto final;
+                               break;
                } else
                        dummy = i2c->data;
        } while (1);
 
-final:
        i2c->csr = CONTROL_ES0;
-       if (!error && (++count > 0))
+       if (!error && (count++ > 0))
                error = PUT_DATA(&i2c->data, buffer++, user);
        else
                dummy = i2c->data;
@@ -159,14 +161,14 @@ final:
 
 stop:
        i2c->csr = CONTROL_PIN | CONTROL_ES0 | CONTROL_STO | CONTROL_ACK;
-       if (!error && (++count > 0))
+       if (!error && (count++ > 0))
                error = PUT_DATA(&i2c->data, buffer++, user);
        else
                dummy = i2c->data;
 
        if (error)
                return error;
-       return count;
+       return count - 1;
 }
 
 static int
@@ -189,19 +191,19 @@ i2c_write(unsigned char dev, const char *buffer, int len, int user)
                        udelay(1);
 
                if (stat & STATUS_LRB)
-                       goto stop;
+                       break;
+
                error = count;
                if (count == len)
-                       goto stop;
+                       break;
 
                error = GET_DATA(&i2c->data, buffer++, user);
                if (error)
-                       goto stop;
+                       break;
 
                count++;
        } while (1);
 
-stop:
        i2c->csr = CONTROL_PIN | CONTROL_ES0 | CONTROL_STO | CONTROL_ACK;
        return error;
 }
@@ -212,7 +214,7 @@ __initfunc(static int i2c_scan_bus(void))
        int count = 0;
 
        for (dev = 1; dev < 128; dev++) {
-               if (i2c_write(dev, 0, 0, 0) == 0) {
+               if (i2c_read(dev, 0, 0, 0) == 0) {
 #ifdef DEBUG_BUS_SCAN
                        int i;
                        for (i = 0; i < NR_DEVMAP; i++)
@@ -224,7 +226,11 @@ __initfunc(static int i2c_scan_bus(void))
                        count++;
                }
        }
-       return count ? 0 : -ENODEV;
+       if (!count) {
+               printk("%s: no devices found\n", __FUNCTION__);
+               return -ENODEV;
+       }
+       return 0;
 }
 
 static loff_t
@@ -317,6 +323,7 @@ __initfunc(int envctrl_init(void))
 #ifdef CONFIG_PCI
        struct linux_ebus *ebus;
        struct linux_ebus_device *edev = 0;
+       int err;
 
        for_each_ebus(ebus) {
                for_each_ebusdev(edev, ebus) {
@@ -327,8 +334,10 @@ __initfunc(int envctrl_init(void))
                }
        }
 ebus_done:
-       if (!edev)
+       if (!edev) {
+               printk("%s: ebus device not found\n", __FUNCTION__);
                return -ENODEV;
+       }
 
        if (check_region(edev->base_address[0], sizeof(*i2c))) {
                printk("%s: Can't get region %lx, %d\n",
@@ -353,7 +362,10 @@ ebus_done:
                release_region((unsigned long)i2c, sizeof(*i2c));
        }
 
-       return i2c_scan_bus();
+       err = i2c_scan_bus();
+       if (err)
+               release_region((unsigned long)i2c, sizeof(*i2c));
+       return err;
 #else
        return -ENODEV;
 #endif
index d159506716ff6af1779a692212511a66012acb7c..297b8f9aea6f806f0e0fa2ed5af0c53521f317bb 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pcikbd.c,v 1.23 1998/10/07 11:35:24 jj Exp $
+/* $Id: pcikbd.c,v 1.24 1998/11/08 11:15:24 davem Exp $
  * pcikbd.c: Ultra/AX PC keyboard support.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -691,7 +691,7 @@ static int poll_aux_status(void)
                    == AUX_STAT_OBF)
                        pcimouse_inb(pcimouse_iobase + KBD_DATA_REG);
                current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout((5*HZ + 99)/100);
+               schedule_timeout((5*HZ + 99) / 100);
                retries++;
        }
        return (retries < MAX_RETRIES);
index c4417ebe2d064ec6fb85f14fcd2f8ad78e35f423..3f0924525477365750da043a290f49ec4c8820dd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sab82532.c,v 1.26 1998/10/25 06:46:41 ecd Exp $
+/* $Id: sab82532.c,v 1.27 1998/11/08 11:15:25 davem Exp $
  * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -2136,7 +2136,7 @@ sab82532_kgdb_hook(int line))
 
 __initfunc(static inline void show_serial_version(void))
 {
-       char *revision = "$Revision: 1.26 $";
+       char *revision = "$Revision: 1.27 $";
        char *version, *p;
 
        version = strchr(revision, ' ');
index a83d8b8ce3496eac9d73e8fcab6028de99066c08..b05acc3143e7099b19cb1dcb69cbb24da673267d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: su.c,v 1.12 1998/10/25 04:24:52 ecd Exp $
+/* $Id: su.c,v 1.16 1998/11/14 23:02:54 ecd Exp $
  * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -37,7 +37,7 @@ do {                                                                  \
        printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n",          \
               kdevname(tty->device), (info->flags), serial_refcount,   \
               info->count,tty->count,s);                               \
-} while (0);
+} while (0)
 #else
 #define DBG_CNT(s)
 #endif
@@ -146,7 +146,7 @@ struct su_struct {
 };
 
 static char *serial_name = "PCIO serial driver";
-static char *serial_version = "1.1";
+static char serial_version[16];
 
 static DECLARE_TASK_QUEUE(tq_serial);
 
@@ -251,10 +251,10 @@ su_outb(struct su_struct *info, unsigned long offset, int value)
        /*
         * MrCoffee has weird schematics: IRQ4 & P10(?) pins of SuperIO are
         * connected with a gate then go to SlavIO. When IRQ4 goes tristated
-        * gate gives logical one. Since we use level triggered interrupts
+        * gate outputs a logical one. Since we use level triggered interrupts
         * we have lockup and watchdog reset. We cannot mask IRQ because
-        * keyboard shares IRQ with us (Bob Smelik: I would not hire you).
-        * P3: Assure that OUT2 never goes down.
+        * keyboard shares IRQ with us (Word has it as Bob Smelik's design).
+        * This problem is similar to what Alpha people suffer, see serial.c.
         */
        if (offset == UART_MCR) value |= UART_MCR_OUT2;
        *(volatile unsigned char *)(info->port + offset) = value;
@@ -386,14 +386,13 @@ receive_serial_chars(struct su_struct *info, int *status, struct pt_regs *regs)
        icount = &info->icount;
        do {
                ch = serial_inp(info, UART_RX);
-
                if (tty->flip.count >= TTY_FLIPBUF_SIZE)
                        break;
                *tty->flip.char_buf_ptr = ch;
                icount->rx++;
 
 #ifdef SERIAL_DEBUG_INTR
-               printk("DR%02x:%02x...", ch, *status);
+               printk("D%02x:%02x.", ch, *status);
 #endif
                *tty->flip.flag_buf_ptr = 0;
                if (*status & (UART_LSR_BI | UART_LSR_PE |
@@ -417,8 +416,12 @@ receive_serial_chars(struct su_struct *info, int *status, struct pt_regs *regs)
                         * should be ignored.
                         */
                        if (*status & info->ignore_status_mask) {
-                               if (++ignored > 100)
+                               if (++ignored > 100) {
+#ifdef SERIAL_DEBUG_INTR
+                                       printk("ign100..");
+#endif
                                        break;
+                               }
                                goto ignore_char;
                        }
                        *status &= info->read_status_mask;
@@ -454,6 +457,9 @@ receive_serial_chars(struct su_struct *info, int *status, struct pt_regs *regs)
        ignore_char:
                *status = serial_inp(info, UART_LSR);
        } while (*status & UART_LSR_DR);
+#ifdef SERIAL_DEBUG_INTR
+       printk("E%02x.R%d", *status, tty->flip.count);
+#endif
        tty_flip_buffer_push(tty);
 }
 
@@ -490,7 +496,7 @@ transmit_chars(struct su_struct *info, int *intr_done)
                su_sched_event(info, RS_EVENT_WRITE_WAKEUP);
 
 #ifdef SERIAL_DEBUG_INTR
-       printk("THRE...");
+       printk("T%d...", info->xmit_cnt);
 #endif
        if (intr_done)
                *intr_done = 0;
@@ -580,7 +586,7 @@ su_kbd_ms_interrupt(int irq, void *dev_id, struct pt_regs * regs)
        unsigned char status;
 
 #ifdef SERIAL_DEBUG_INTR
-       printk("su_interrupt(%s)...", __irq_itoa(irq));
+       printk("su_kbd_ms_interrupt(%s)...", __irq_itoa(irq));
 #endif
        if (!info)
                return;
@@ -611,12 +617,16 @@ su_serial_interrupt(int irq, void *dev_id, struct pt_regs * regs)
        int pass_counter = 0;
 
 #ifdef SERIAL_DEBUG_INTR
-       printk("su_interrupt(%s)...", __irq_itoa(irq));
+       printk("su_serial_interrupt(%s)...", __irq_itoa(irq));
 #endif
        info = (struct su_struct *)dev_id;
-       if (!info || !info->tty)
+       if (!info || !info->tty) {
+#ifdef SERIAL_DEBUG_INTR
+               printk("strain\n");
+#endif
                return;
-       
+       }
+
        do {
                status = serial_inp(info, UART_LSR);
 #ifdef SERIAL_DEBUG_INTR
@@ -629,8 +639,8 @@ su_serial_interrupt(int irq, void *dev_id, struct pt_regs * regs)
                        transmit_chars(info, 0);
 
                if (pass_counter++ > RS_ISR_PASS_LIMIT) {
-#if 0
-                       printk("rs loop break\n");
+#ifdef SERIAL_DEBUG_INTR
+                       printk("rs loop break");
 #endif
                        break;  /* Prevent infinite loops */
                }
@@ -658,18 +668,16 @@ su_serial_interrupt(int irq, void *dev_id, struct pt_regs * regs)
  * interrupt driver proper are done; the interrupt driver schedules
  * them using su_sched_event(), and they get done here.
  */
-static void
-do_serial_bh(void)
+static void do_serial_bh(void)
 {
        run_task_queue(&tq_serial);
 }
 
-static void
-do_softint(void *private_)
+static void do_softint(void *private_)
 {
        struct su_struct        *info = (struct su_struct *) private_;
        struct tty_struct       *tty;
-       
+
        tty = info->tty;
        if (!tty)
                return;
@@ -724,7 +732,8 @@ startup(struct su_struct *info)
        cli();
 
 #ifdef SERIAL_DEBUG_OPEN
-       printk("starting up ttys%d (irq %d)...", info->line, state->irq);
+       printk("starting up ttys%d (irq %s)...", info->line,
+              __irq_itoa(info->irq));
 #endif
 
        if (uart_config[info->type].flags & UART_STARTECH) {
@@ -1269,12 +1278,13 @@ static void
 su_flush_buffer(struct tty_struct *tty)
 {
        struct su_struct *info = (struct su_struct *)tty->driver_data;
+       unsigned long flags;
 
        if (serial_paranoia_check(info, tty->device, "su_flush_buffer"))
                return;
-       cli();
+       save_flags(flags); cli();
        info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-       sti();
+       restore_flags(flags);
        wake_up_interruptible(&tty->write_wait);
        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
            tty->ldisc.write_wakeup)
@@ -1313,41 +1323,43 @@ static void
 su_throttle(struct tty_struct * tty)
 {
        struct su_struct *info = (struct su_struct *)tty->driver_data;
+       unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
        char    buf[64];
-       
+
        printk("throttle %s: %d....\n", tty_name(tty, buf),
               tty->ldisc.chars_in_buffer(tty));
 #endif
 
        if (serial_paranoia_check(info, tty->device, "su_throttle"))
                return;
-       
+
        if (I_IXOFF(tty))
                su_send_xchar(tty, STOP_CHAR(tty));
 
        if (tty->termios->c_cflag & CRTSCTS)
                info->MCR &= ~UART_MCR_RTS;
 
-       cli();
+       save_flags(flags); cli();
        serial_out(info, UART_MCR, info->MCR);
-       sti();
+       restore_flags(flags);
 }
 
 static void
 su_unthrottle(struct tty_struct * tty)
 {
        struct su_struct *info = (struct su_struct *)tty->driver_data;
+       unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
        char    buf[64];
-       
+
        printk("unthrottle %s: %d....\n", tty_name(tty, buf),
               tty->ldisc.chars_in_buffer(tty));
 #endif
 
        if (serial_paranoia_check(info, tty->device, "su_unthrottle"))
                return;
-       
+
        if (I_IXOFF(tty)) {
                if (info->x_char)
                        info->x_char = 0;
@@ -1356,9 +1368,9 @@ su_unthrottle(struct tty_struct * tty)
        }
        if (tty->termios->c_cflag & CRTSCTS)
                info->MCR |= UART_MCR_RTS;
-       cli();
+       save_flags(flags); cli();
        serial_out(info, UART_MCR, info->MCR);
-       sti();
+       restore_flags(flags);
 }
 
 /*
@@ -1382,10 +1394,11 @@ get_lsr_info(struct su_struct * info, unsigned int *value)
 {
        unsigned char status;
        unsigned int result;
+       unsigned long flags;
 
-       cli();
+       save_flags(flags); cli();
        status = serial_in(info, UART_LSR);
-       sti();
+       restore_flags(flags);
        result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
        return put_user(result,value);
 }
@@ -1396,11 +1409,12 @@ get_modem_info(struct su_struct * info, unsigned int *value)
 {
        unsigned char control, status;
        unsigned int result;
+       unsigned long flags;
 
        control = info->MCR;
-       cli();
+       save_flags(flags); cli();
        status = serial_in(info, UART_MSR);
-       sti();
+       restore_flags(flags);
        result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
                | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
 #ifdef TIOCM_OUT1
@@ -1419,6 +1433,7 @@ set_modem_info(struct su_struct * info, unsigned int cmd, unsigned int *value)
 {
        int error;
        unsigned int arg;
+       unsigned long flags;
 
        error = get_user(arg, value);
        if (error)
@@ -1465,9 +1480,9 @@ set_modem_info(struct su_struct * info, unsigned int cmd, unsigned int *value)
        default:
                return -EINVAL;
        }
-       cli();
+       save_flags(flags); cli();
        serial_out(info, UART_MCR, info->MCR);
-       sti();
+       restore_flags(flags);
        return 0;
 }
 
@@ -1589,13 +1604,14 @@ su_ioctl(struct tty_struct *tty, struct file * file,
                default:
                        return -ENOIOCTLCMD;
                }
-       /* return 0; */ /* Trigger warnings is fall through by a chance. */
+       /* return 0; */ /* Trigger warnings if fall through by a chance. */
 }
 
 static void
 su_set_termios(struct tty_struct *tty, struct termios *old_termios)
 {
        struct su_struct *info = (struct su_struct *)tty->driver_data;
+       unsigned long flags;
 
        if (   (tty->termios->c_cflag == old_termios->c_cflag)
            && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
@@ -1608,11 +1624,11 @@ su_set_termios(struct tty_struct *tty, struct termios *old_termios)
        if ((old_termios->c_cflag & CBAUD) &&
            !(tty->termios->c_cflag & CBAUD)) {
                info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
-               cli();
+               save_flags(flags); cli();
                serial_out(info, UART_MCR, info->MCR);
-               sti();
+               restore_flags(flags);
        }
-       
+
        /* Handle transition away from B0 status */
        if (!(old_termios->c_cflag & CBAUD) &&
            (tty->termios->c_cflag & CBAUD)) {
@@ -1621,9 +1637,9 @@ su_set_termios(struct tty_struct *tty, struct termios *old_termios)
                    !test_bit(TTY_THROTTLED, &tty->flags)) {
                        info->MCR |= UART_MCR_RTS;
                }
-               cli();
+               save_flags(flags); cli();
                serial_out(info, UART_MCR, info->MCR);
-               sti();
+               restore_flags(flags);
        }
        
        /* Handle turning off CRTSCTS */
@@ -1771,6 +1787,9 @@ su_wait_until_sent(struct tty_struct *tty, int timeout)
        if (info->type == PORT_UNKNOWN)
                return;
 
+       if (info->xmit_fifo_size == 0)
+               return; /* Just in case ... */
+
        orig_jiffies = jiffies;
        /*
         * Set the check interval to be 1/5 of the estimated time to
@@ -1838,8 +1857,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
                struct su_struct *info)
 {
        struct wait_queue wait = { current, NULL };
-       int             retval;
-       int             do_clocal = 0;
+       int               retval;
+       int               do_clocal = 0, extra_count = 0;
+       unsigned long     flags;
 
        /*
         * If the device is in the middle of being closed, then block
@@ -1909,19 +1929,21 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
        printk("block_til_ready before block: ttys%d, count = %d\n",
               info->line, info->count);
 #endif
-       cli();
-       if (!tty_hung_up_p(filp)) 
+       save_flags(flags); cli();
+       if (!tty_hung_up_p(filp)) {
+               extra_count = 1;
                info->count--;
-       sti();
+       }
+       restore_flags(flags);
        info->blocked_open++;
        while (1) {
-               cli();
+               save_flags(flags); cli();
                if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
                    (tty->termios->c_cflag & CBAUD))
                        serial_out(info, UART_MCR,
                                   serial_inp(info, UART_MCR) |
                                   (UART_MCR_DTR | UART_MCR_RTS));
-               sti();
+               restore_flags(flags);
                current->state = TASK_INTERRUPTIBLE;
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ASYNC_INITIALIZED)) {
@@ -1952,7 +1974,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
        }
        current->state = TASK_RUNNING;
        remove_wait_queue(&info->open_wait, &wait);
-       if (!tty_hung_up_p(filp))
+       if (extra_count)
                info->count++;
        info->blocked_open--;
 #ifdef SERIAL_DEBUG_OPEN
@@ -1982,16 +2004,19 @@ su_open(struct tty_struct *tty, struct file * filp)
        if ((line < 0) || (line >= NR_PORTS))
                return -ENODEV;
        info = su_table + line;
-       if (serial_paranoia_check(info, tty->device, "su_open"))
-               return -ENODEV;
        info->count++;
+       tty->driver_data = info;
+       info->tty = tty;
+
+       if (serial_paranoia_check(info, tty->device, "su_open")) {
+               info->count--;
+               return -ENODEV;
+       }
 
 #ifdef SERIAL_DEBUG_OPEN
        printk("su_open %s%d, count = %d\n", tty->driver.name, info->line,
               info->count);
 #endif
-       tty->driver_data = info;
-       info->tty = tty;
        info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 
        if (!tmp_buf) {
@@ -2066,8 +2091,9 @@ su_open(struct tty_struct *tty, struct file * filp)
 static __inline__ int
 line_info(char *buf, struct su_struct *info)
 {
-       char    stat_buf[30], control, status;
-       int     ret;
+       char            stat_buf[30], control, status;
+       int             ret;
+       unsigned long   flags;
 
        ret = sprintf(buf, "%d: uart:%s port:%X irq:%s",
                      info->line, uart_config[info->type].name, 
@@ -2081,10 +2107,10 @@ line_info(char *buf, struct su_struct *info)
        /*
         * Figure out the current RS-232 lines
         */
-       cli();
+       save_flags(flags); cli();
        status = serial_in(info, UART_MSR);
        control = info ? info->MCR : serial_in(info, UART_MCR);
-       sti();
+       restore_flags(flags);
 
        stat_buf[0] = 0;
        stat_buf[1] = 0;
@@ -2165,9 +2191,15 @@ done:
  * number, and identifies which options were configured into this
  * driver.
  */
-static __inline__
-void show_su_version(void)
+__initfunc(static __inline__ void show_su_version(void))
 {
+       char *revision = "$Revision: 1.16 $";
+       char *version, *p;
+
+       version = strchr(revision, ' ');
+       strcpy(serial_version, ++version);
+       p = strchr(serial_version, ' ');
+       *p = '\0';
        printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
 }
 
@@ -2249,23 +2281,21 @@ ebus_done:
         * 0x80 is a non-existent port; which should be safe since
         * include/asm/io.h also makes this assumption.
         */
-       scratch = serial_in(info, UART_IER);
-       su_outb(info, UART_IER, 0);
-       scratch2 = serial_in(info, UART_IER);
-       su_outb(info, UART_IER, scratch);
+       scratch = serial_inp(info, UART_IER);
+       serial_outp(info, UART_IER, 0);
+       scratch2 = serial_inp(info, UART_IER);
+       serial_outp(info, UART_IER, scratch);
        if (scratch2) {
                restore_flags(flags);
                return;         /* We failed; there's nothing here */
        }
 
-#if 0 /* P3 You will never beleive but SuperIO fails this test in MrCoffee. */
-       scratch = serial_in(info, UART_MCR);
-       su_outb(info, UART_MCR, UART_MCR_LOOP | scratch);
-       scratch2 = serial_in(info, UART_MSR);
-       su_outb(info, UART_MCR, UART_MCR_LOOP | 0x0A);
-       status1 = serial_in(info, UART_MSR) & 0xF0;
-       su_outb(info, UART_MCR, scratch);
-       su_outb(info, UART_MSR, scratch2);
+#if 0 /* P3: This does not work on MrCoffee. OUT2 is 0x80 - should work... */
+       scratch = serial_inp(info, UART_MCR);
+       serial_outp(info, UART_MCR, UART_MCR_LOOP | scratch);
+       serial_outp(info, UART_MCR, UART_MCR_LOOP | 0x0A);
+       status1 = serial_inp(info, UART_MSR) & 0xF0;
+       serial_outp(info, UART_MCR, scratch);
        if (status1 != 0x90) {
                restore_flags(flags);
                return;
@@ -2273,10 +2303,10 @@ ebus_done:
 #endif
 
        scratch2 = serial_in(info, UART_LCR);
-       su_outb(info, UART_LCR, 0xBF);  /* set up for StarTech test */
-       su_outb(info, UART_EFR, 0);     /* EFR is the same as FCR */
-       su_outb(info, UART_LCR, 0);
-       su_outb(info, UART_FCR, UART_FCR_ENABLE_FIFO);
+       serial_outp(info, UART_LCR, 0xBF);      /* set up for StarTech test */
+       serial_outp(info, UART_EFR, 0);         /* EFR is the same as FCR */
+       serial_outp(info, UART_LCR, 0);
+       serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
        scratch = serial_in(info, UART_IIR) >> 6;
        switch (scratch) {
                case 0:
@@ -2294,38 +2324,38 @@ ebus_done:
        }
        if (info->type == PORT_16550A) {
                /* Check for Startech UART's */
-               su_outb(info, UART_LCR, scratch2 | UART_LCR_DLAB);
-               if (su_inb(info, UART_EFR) == 0) {
+               serial_outp(info, UART_LCR, scratch2 | UART_LCR_DLAB);
+               if (serial_in(info, UART_EFR) == 0) {
                        info->type = PORT_16650;
                } else {
-                       su_outb(info, UART_LCR, 0xBF);
-                       if (su_inb(info, UART_EFR) == 0)
+                       serial_outp(info, UART_LCR, 0xBF);
+                       if (serial_in(info, UART_EFR) == 0)
                                info->type = PORT_16650V2;
                }
        }
        if (info->type == PORT_16550A) {
                /* Check for TI 16750 */
-               su_outb(info, UART_LCR, scratch2 | UART_LCR_DLAB);
-               su_outb(info, UART_FCR,
+               serial_outp(info, UART_LCR, scratch2 | UART_LCR_DLAB);
+               serial_outp(info, UART_FCR,
                            UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-               scratch = su_inb(info, UART_IIR) >> 5;
+               scratch = serial_in(info, UART_IIR) >> 5;
                if (scratch == 7) {
-                       su_outb(info, UART_LCR, 0);
-                       su_outb(info, UART_FCR, UART_FCR_ENABLE_FIFO);
-                       scratch = su_inb(info, UART_IIR) >> 5;
+                       serial_outp(info, UART_LCR, 0);
+                       serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
+                       scratch = serial_in(info, UART_IIR) >> 5;
                        if (scratch == 6)
                                info->type = PORT_16750;
                }
-               su_outb(info, UART_FCR, UART_FCR_ENABLE_FIFO);
+               serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
        }
-       su_outb(info, UART_LCR, scratch2);
+       serial_outp(info, UART_LCR, scratch2);
        if (info->type == PORT_16450) {
-               scratch = su_inb(info, UART_SCR);
-               su_outb(info, UART_SCR, 0xa5);
-               status1 = su_inb(info, UART_SCR);
-               su_outb(info, UART_SCR, 0x5a);
-               status2 = su_inb(info, UART_SCR);
-               su_outb(info, UART_SCR, scratch);
+               scratch = serial_in(info, UART_SCR);
+               serial_outp(info, UART_SCR, 0xa5);
+               status1 = serial_in(info, UART_SCR);
+               serial_outp(info, UART_SCR, 0x5a);
+               status2 = serial_in(info, UART_SCR);
+               serial_outp(info, UART_SCR, scratch);
 
                if ((status1 != 0xa5) || (status2 != 0x5a))
                        info->type = PORT_8250;
@@ -2349,9 +2379,10 @@ ebus_done:
        /*
         * Reset the UART.
         */
-       su_outb(info, UART_MCR, 0x00);
-       su_outb(info, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));
-       su_inb(info, UART_RX);
+       serial_outp(info, UART_MCR, 0x00);
+       serial_outp(info, UART_FCR, (UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT));
+       (void)serial_in(info, UART_RX);
+       serial_outp(info, UART_IER, 0x00);
 
        restore_flags(flags);
 }
index 750d89574122dcc8f165f9ba4fbf778b5cd44e9c..67aa3c574109243aca2fdcdeac514898f45d7993 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: zs.c,v 1.31 1998/10/07 11:35:29 jj Exp $
+/* $Id: zs.c,v 1.32 1998/11/08 11:15:29 davem Exp $
  * zs.c: Zilog serial port driver for the Sparc.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1806,7 +1806,7 @@ int zs_open(struct tty_struct *tty, struct file * filp)
 
 static void show_serial_version(void)
 {
-       char *revision = "$Revision: 1.31 $";
+       char *revision = "$Revision: 1.32 $";
        char *version, *p;
 
        version = strchr(revision, ' ');
index ee73bd3681df1a75d01631f4c488a01d2a2bf915..b3b96709b3e921064c364ca465ec24c680396f93 100644 (file)
@@ -1432,7 +1432,6 @@ do_sync_known:
                           (SDptr->type != TYPE_ROM ||
                            strncmp(SDptr->vendor, "TOSHIBA", 7))) {
                                build_wide_nego_msg(esp, 16);
-                               esp->config3[SCptr->target] |= ESP_CONFIG3_EWIDE;
                                SDptr->wide = 1;
                                esp->wnip = 1;
                                goto after_nego_msg_built;
index 126a689c48ba8b76606152d2fc1dc64c115574fd..c4fb47dcef5fcccc9cd829084711be20c158b803 100644 (file)
@@ -41,19 +41,7 @@ obj-         :=
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_SOUND)            += soundcore.o
-
-ifeq ($(ARCH),m68k)
-
-obj-$(CONFIG_DMASOUND)         += dmasound.o
-
-else
-
-ifeq ($(CONFIG_PMAC),y)
-
 obj-$(CONFIG_DMASOUND)         += dmasound.o
-
-else
-
 obj-$(CONFIG_SOUND_OSS)                += sound.o
 obj-$(CONFIG_SOUND_ADLIB)      += adlib_card.o opl3.o
 obj-$(CONFIG_SOUND_CS4232)     += cs4232.o ad1848.o 
@@ -90,9 +78,6 @@ obj-$(CONFIG_SOUND_ES1370)    += es1370.o
 obj-$(CONFIG_SOUND_ES1371)     += es1371.o
 obj-$(CONFIG_SOUND_SONICVIBES) += sonicvibes.o
 
-endif
-endif
-
 # Declare multi-part drivers.
 
 list-multi     := sound.o gus.o pas2.o sb.o softoss2.o vidc_mod.o \
index a60a04b193ceb4c70c10efeeefc1a1943592b6e4..a88af3709716cb428d3f5ba3e8382e725b14a637 100644 (file)
@@ -48,7 +48,7 @@ if [ "$CONFIG_INET" = "y" ]; then
     bool 'SMB Win95 bug work-around' CONFIG_SMB_WIN95
   fi
 fi
-if [ "$CONFIG_IPX" != "n" ]; then
+if [ "$CONFIG_IPX" != "n" -o "$CONFIG_INET" != "n" ]; then
   tristate 'NCP filesystem support (to mount NetWare volumes)' CONFIG_NCP_FS
   if [ "$CONFIG_NCP_FS" != "n" ]; then
     source fs/ncpfs/Config.in
index 3d91302bdbcfb8c21b47ca63aa273b537041cf3a..821cf44e0e770de9256506e34c506e464ab17beb 100644 (file)
@@ -66,9 +66,9 @@ struct autofs_dirhash {
 };
 
 struct autofs_wait_queue {
-       unsigned long wait_queue_token;
        struct wait_queue *queue;
        struct autofs_wait_queue *next;
+       autofs_wqt_t wait_queue_token;
        /* We use the following to see what we are waiting for */
        int hash;
        int len;
@@ -79,8 +79,8 @@ struct autofs_wait_queue {
 };
 
 struct autofs_symlink {
-       int len;
        char *data;
+       int len;
        time_t mtime;
 };
 
@@ -146,7 +146,7 @@ struct super_block *autofs_read_super(struct super_block *, void *,int);
 /* Queue management functions */
 
 int autofs_wait(struct autofs_sb_info *,struct qstr *);
-int autofs_wait_release(struct autofs_sb_info *,unsigned long,int);
+int autofs_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
 void autofs_catatonic_mode(struct autofs_sb_info *);
 
 #ifdef DEBUG
index acf05f536431ba907a8079c31a17768be631515b..a3d41fb33db175aafce0f043a57f77ec173afb25 100644 (file)
@@ -503,9 +503,9 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp,
        
        switch(cmd) {
        case AUTOFS_IOC_READY:  /* Wait queue: go ahead and retry */
-               return autofs_wait_release(sbi,arg,0);
+               return autofs_wait_release(sbi,(autofs_wqt_t)arg,0);
        case AUTOFS_IOC_FAIL:   /* Wait queue: fail with ENOENT */
-               return autofs_wait_release(sbi,arg,-ENOENT);
+               return autofs_wait_release(sbi,(autofs_wqt_t)arg,-ENOENT);
        case AUTOFS_IOC_CATATONIC: /* Enter catatonic mode (daemon shutdown) */
                autofs_catatonic_mode(sbi);
                return 0;
index 7ac28e2f1ec9a57a8ba56b7d347d3117b47e7710..0a36930d9e7e70bb0e140040a4d6519f123bfb39 100644 (file)
@@ -18,7 +18,7 @@
 
 /* We make this a static variable rather than a part of the superblock; it
    is better if we don't reassign numbers easily even across filesystems */
-static int autofs_next_wait_queue = 1;
+static autofs_wqt_t autofs_next_wait_queue = 1;
 
 /* These are the signals we allow interrupting a pending mount */
 #define SHUTDOWN_SIGS  (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT))
@@ -168,7 +168,7 @@ int autofs_wait(struct autofs_sb_info *sbi, struct qstr * name)
 }
 
 
-int autofs_wait_release(struct autofs_sb_info *sbi, unsigned long wait_queue_token, int status)
+int autofs_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_token, int status)
 {
        struct autofs_wait_queue *wq, **wql;
 
index 748b9e9336e2e09446e335b20246a21aa772811f..e123a9f1648d0a88eceeeb7455d7cef71dc87f64 100644 (file)
@@ -624,7 +624,8 @@ void fat_read_inode(struct inode *inode, struct inode_operations *fs_dir_inode_o
        if (!(bh = fat_bread(sb, inode->i_ino >> MSDOS_DPB_BITS))) {
                printk("dev = %s, ino = %ld\n",
                       kdevname(inode->i_dev), inode->i_ino);
-               panic("fat_read_inode: unable to read i-node block");
+               fat_fs_panic(sb, "fat_read_inode: unable to read i-node block");
+               return;
        }
        raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
            [inode->i_ino & (MSDOS_DPB-1)];
@@ -713,7 +714,8 @@ void fat_write_inode(struct inode *inode)
        if (!(bh = fat_bread(sb, inode->i_ino >> MSDOS_DPB_BITS))) {
                printk("dev = %s, ino = %ld\n",
                       kdevname(inode->i_dev), inode->i_ino);
-               panic("msdos_write_inode: unable to read i-node block");
+               fat_fs_panic(sb, "msdos_write_inode: unable to read i-node block");
+               return;
        }
        raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
            [inode->i_ino & (MSDOS_DPB-1)];
index 642adacdaa75db24664c3093cf64853e2150a41e..b6843aaf69143385096da2878f44b4fb79bf27ca 100644 (file)
@@ -338,6 +338,7 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned
                do {
                        name++;
                } while (*name == '/');
+               __prefix_lookup_dentry(name, lookup_flags);
                base = dget(current->fs->root);
        } else if (!base) {
                base = dget(current->fs->pwd);
index 22e14bdce09092c2b7b3b706ee8c42ebf1e2c789..644ec09902caee1e80f7ae16ef3867161ecf0847 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: namei.h,v 1.1 1996/12/13 14:48:23 jj Exp $
+/* $Id: namei.h,v 1.1 1996/12/13 14:48:21 jj Exp $
  * linux/include/asm-alpha/namei.h
  *
  * Included from linux/fs/namei.c
@@ -12,7 +12,7 @@
  * Look at asm-sparc/namei.h for details.
  */
 
-#define __prefix_namei(retrieve_mode, name, base, buf, res_dir, res_inode, \
-                      last_name, last_entry, last_error) 1
+#define __prefix_lookup_dentry(name, lookup_flags) \
+        do {} while (0)
 
 #endif /* __ALPHA_NAMEI_H */
index 8fcd2f5cde3dec6cc6366c9ee37fa583a3235f34..858f400b6bde40895750eb7ddd8a26190a7ea033 100644 (file)
@@ -1,5 +1,5 @@
-/*
- * linux/include/asm-i386/namei.h
+/* 
+ * linux/include/asm-arm/namei.h
  *
  * Included from linux/fs/namei.c
  */
@@ -12,7 +12,7 @@
  * Look at asm-sparc/namei.h for details.
  */
 
-#define __prefix_namei(retrieve_mode, name, base, buf, res_dir, res_inode, \
-                      last_name, last_entry, last_error) 1
+#define __prefix_lookup_dentry(name, lookup_flags) \
+        do {} while (0)
 
 #endif /* __ASMARM_NAMEI_H */
index 981627be70c9fc7383cea51885a207909a1cecc6..5708ffd8dd17453a6aa609265111c352de7e43f7 100644 (file)
@@ -12,7 +12,7 @@
  * Look at asm-sparc/namei.h for details.
  */
 
-#define __prefix_namei(retrieve_mode, name, base, buf, res_dir, res_inode, \
-                      last_name, last_entry, last_error) 1
+#define __prefix_lookup_dentry(name, lookup_flags) \
+        do {} while (0)
 
 #endif /* __I386_NAMEI_H */
index 0f0115dc59091219e2f49f6abe891fe065a269f7..a0b8372e9967653ec719d16fb86be67b957e09e7 100644 (file)
 #define __NR_sendfile          187
 #define __NR_getpmsg           188     /* some people actually want streams */
 #define __NR_putpmsg           189     /* some people actually want streams */
+#define __NR_mrecow            190
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
 
index d01ddf852eb66fa46b8964e66b1dca960350e006..7b4f026809985322592dffef3c7adc1d3103d9e9 100644 (file)
@@ -12,7 +12,7 @@
  * Look at asm-sparc/namei.h for details.
  */
 
-#define __prefix_lookup_dentry(name, follow_link) \
+#define __prefix_lookup_dentry(name, lookup_flags) \
         do {} while (0)
 
 #endif
index 8db275671e76739150d31b1d5e13aee5f75e054a..b1a6ca1bc80ac4b61fec9a41ab83c661328f6ec9 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Included from linux/fs/namei.c
  *
- * $Id: namei.h,v 1.9 1998/05/01 01:35:59 ralf Exp $
+ * $Id: namei.h,v 1.10 1998/10/28 08:13:24 jj Exp $
  */
 #ifndef __ASM_MIPS_NAMEI_H
 #define __ASM_MIPS_NAMEI_H
@@ -14,7 +14,7 @@
 #define IRIX32_EMUL "usr/gnemul/irix/"
 
 static inline struct dentry *
-__mips_lookup_dentry(const char *name, int follow_link)
+__mips_lookup_dentry(const char *name, int lookup_flags)
 {
        struct dentry *base;
 
@@ -22,11 +22,12 @@ __mips_lookup_dentry(const char *name, int follow_link)
                return ERR_PTR(-ENOENT);
 
        base = lookup_dentry (IRIX32_EMUL,
-                       dget (current->fs->root), 1);
+                       dget (current->fs->root), 
+                       (LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_SLASHOK));
                        
        if (IS_ERR (base)) return base;
        
-       base = lookup_dentry (name, base, follow_link);
+       base = lookup_dentry (name, base, lookup_flags);
 
        if (IS_ERR (base)) return base;
 
@@ -40,13 +41,13 @@ __mips_lookup_dentry(const char *name, int follow_link)
 
 #ifdef CONFIG_BINFMT_IRIX
 
-#define __prefix_lookup_dentry(name, follow_link)                              \
-       dentry = __mips_lookup_dentry (name, follow_link);                      \
+#define __prefix_lookup_dentry(name, lookup_flags)                             \
+       dentry = __mips_lookup_dentry (name, lookup_flags);                     \
        if (!IS_ERR (dentry)) return dentry;
 
 #else /* !defined(CONFIG_BINFMT_IRIX) */
 
-#define __prefix_lookup_dentry(name, follow_link) \
+#define __prefix_lookup_dentry(name, lookup_flags) \
         do {} while (0)
 
 #endif /* !defined(CONFIG_BINFMT_IRIX) */
index 2775b899db2ab35f5de00c102f94a9685ea7b6c1..655987dd5092efface5b231da7f056e73a7ad954 100644 (file)
 #define ASIZ_task_tarray_ptr   0x00000004
 #define AOFF_task_wait_chldexit        0x0000008c
 #define ASIZ_task_wait_chldexit        0x00000004
-#define AOFF_task_timeout      0x00000090
-#define ASIZ_task_timeout      0x00000004
-#define AOFF_task_policy       0x00000094
+#define AOFF_task_policy       0x00000090
 #define ASIZ_task_policy       0x00000004
-#define AOFF_task_rt_priority  0x00000098
+#define AOFF_task_rt_priority  0x00000094
 #define ASIZ_task_rt_priority  0x00000004
-#define AOFF_task_it_real_value        0x0000009c
+#define AOFF_task_it_real_value        0x00000098
 #define ASIZ_task_it_real_value        0x00000004
-#define AOFF_task_it_prof_value        0x000000a0
+#define AOFF_task_it_prof_value        0x0000009c
 #define ASIZ_task_it_prof_value        0x00000004
-#define AOFF_task_it_virt_value        0x000000a4
+#define AOFF_task_it_virt_value        0x000000a0
 #define ASIZ_task_it_virt_value        0x00000004
-#define AOFF_task_it_real_incr 0x000000a8
+#define AOFF_task_it_real_incr 0x000000a4
 #define ASIZ_task_it_real_incr 0x00000004
-#define AOFF_task_it_prof_incr 0x000000ac
+#define AOFF_task_it_prof_incr 0x000000a8
 #define ASIZ_task_it_prof_incr 0x00000004
-#define AOFF_task_it_virt_incr 0x000000b0
+#define AOFF_task_it_virt_incr 0x000000ac
 #define ASIZ_task_it_virt_incr 0x00000004
-#define AOFF_task_real_timer   0x000000b4
+#define AOFF_task_real_timer   0x000000b0
 #define ASIZ_task_real_timer   0x00000014
-#define AOFF_task_times        0x000000c8
+#define AOFF_task_times        0x000000c4
 #define ASIZ_task_times        0x00000010
-#define AOFF_task_start_time   0x000000d8
+#define AOFF_task_start_time   0x000000d4
 #define ASIZ_task_start_time   0x00000004
-#define AOFF_task_per_cpu_utime        0x000000dc
+#define AOFF_task_per_cpu_utime        0x000000d8
 #define ASIZ_task_per_cpu_utime        0x00000004
-#define AOFF_task_min_flt      0x000000e4
+#define AOFF_task_min_flt      0x000000e0
 #define ASIZ_task_min_flt      0x00000004
-#define AOFF_task_maj_flt      0x000000e8
+#define AOFF_task_maj_flt      0x000000e4
 #define ASIZ_task_maj_flt      0x00000004
-#define AOFF_task_nswap        0x000000ec
+#define AOFF_task_nswap        0x000000e8
 #define ASIZ_task_nswap        0x00000004
-#define AOFF_task_cmin_flt     0x000000f0
+#define AOFF_task_cmin_flt     0x000000ec
 #define ASIZ_task_cmin_flt     0x00000004
-#define AOFF_task_cmaj_flt     0x000000f4
+#define AOFF_task_cmaj_flt     0x000000f0
 #define ASIZ_task_cmaj_flt     0x00000004
-#define AOFF_task_cnswap       0x000000f8
+#define AOFF_task_cnswap       0x000000f4
 #define ASIZ_task_cnswap       0x00000004
-#define AOFF_task_swap_address 0x00000100
+#define AOFF_task_swap_address 0x000000fc
 #define ASIZ_task_swap_address 0x00000004
-#define AOFF_task_old_maj_flt  0x00000104
+#define AOFF_task_old_maj_flt  0x00000100
 #define ASIZ_task_old_maj_flt  0x00000004
-#define AOFF_task_dec_flt      0x00000108
+#define AOFF_task_dec_flt      0x00000104
 #define ASIZ_task_dec_flt      0x00000004
-#define AOFF_task_swap_cnt     0x0000010c
+#define AOFF_task_swap_cnt     0x00000108
 #define ASIZ_task_swap_cnt     0x00000004
-#define AOFF_task_uid  0x00000110
+#define AOFF_task_uid  0x0000010c
 #define ASIZ_task_uid  0x00000002
-#define AOFF_task_euid 0x00000112
+#define AOFF_task_euid 0x0000010e
 #define ASIZ_task_euid 0x00000002
-#define AOFF_task_suid 0x00000114
+#define AOFF_task_suid 0x00000110
 #define ASIZ_task_suid 0x00000002
-#define AOFF_task_fsuid        0x00000116
+#define AOFF_task_fsuid        0x00000112
 #define ASIZ_task_fsuid        0x00000002
-#define AOFF_task_gid  0x00000118
+#define AOFF_task_gid  0x00000114
 #define ASIZ_task_gid  0x00000002
-#define AOFF_task_egid 0x0000011a
+#define AOFF_task_egid 0x00000116
 #define ASIZ_task_egid 0x00000002
-#define AOFF_task_sgid 0x0000011c
+#define AOFF_task_sgid 0x00000118
 #define ASIZ_task_sgid 0x00000002
-#define AOFF_task_fsgid        0x0000011e
+#define AOFF_task_fsgid        0x0000011a
 #define ASIZ_task_fsgid        0x00000002
-#define AOFF_task_ngroups      0x00000120
+#define AOFF_task_ngroups      0x0000011c
 #define ASIZ_task_ngroups      0x00000004
-#define AOFF_task_groups       0x00000124
+#define AOFF_task_groups       0x00000120
 #define ASIZ_task_groups       0x00000040
-#define AOFF_task_cap_effective        0x00000164
+#define AOFF_task_cap_effective        0x00000160
 #define ASIZ_task_cap_effective        0x00000004
-#define AOFF_task_cap_inheritable      0x00000168
+#define AOFF_task_cap_inheritable      0x00000164
 #define ASIZ_task_cap_inheritable      0x00000004
-#define AOFF_task_cap_permitted        0x0000016c
+#define AOFF_task_cap_permitted        0x00000168
 #define ASIZ_task_cap_permitted        0x00000004
-#define AOFF_task_user 0x00000170
+#define AOFF_task_user 0x0000016c
 #define ASIZ_task_user 0x00000004
-#define AOFF_task_rlim 0x00000174
+#define AOFF_task_rlim 0x00000170
 #define ASIZ_task_rlim 0x00000050
-#define AOFF_task_used_math    0x000001c4
+#define AOFF_task_used_math    0x000001c0
 #define ASIZ_task_used_math    0x00000002
-#define AOFF_task_comm 0x000001c6
+#define AOFF_task_comm 0x000001c2
 #define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count   0x000001d8
+#define AOFF_task_link_count   0x000001d4
 #define ASIZ_task_link_count   0x00000004
-#define AOFF_task_tty  0x000001dc
+#define AOFF_task_tty  0x000001d8
 #define ASIZ_task_tty  0x00000004
-#define AOFF_task_semundo      0x000001e0
+#define AOFF_task_semundo      0x000001dc
 #define ASIZ_task_semundo      0x00000004
-#define AOFF_task_semsleeping  0x000001e4
+#define AOFF_task_semsleeping  0x000001e0
 #define ASIZ_task_semsleeping  0x00000004
 #define AOFF_task_tss  0x000001e8
 #define ASIZ_task_tss  0x00000388
 #define ASIZ_task_tarray_ptr   0x00000004
 #define AOFF_task_wait_chldexit        0x0000008c
 #define ASIZ_task_wait_chldexit        0x00000004
-#define AOFF_task_timeout      0x00000090
-#define ASIZ_task_timeout      0x00000004
-#define AOFF_task_policy       0x00000094
+#define AOFF_task_policy       0x00000090
 #define ASIZ_task_policy       0x00000004
-#define AOFF_task_rt_priority  0x00000098
+#define AOFF_task_rt_priority  0x00000094
 #define ASIZ_task_rt_priority  0x00000004
-#define AOFF_task_it_real_value        0x0000009c
+#define AOFF_task_it_real_value        0x00000098
 #define ASIZ_task_it_real_value        0x00000004
-#define AOFF_task_it_prof_value        0x000000a0
+#define AOFF_task_it_prof_value        0x0000009c
 #define ASIZ_task_it_prof_value        0x00000004
-#define AOFF_task_it_virt_value        0x000000a4
+#define AOFF_task_it_virt_value        0x000000a0
 #define ASIZ_task_it_virt_value        0x00000004
-#define AOFF_task_it_real_incr 0x000000a8
+#define AOFF_task_it_real_incr 0x000000a4
 #define ASIZ_task_it_real_incr 0x00000004
-#define AOFF_task_it_prof_incr 0x000000ac
+#define AOFF_task_it_prof_incr 0x000000a8
 #define ASIZ_task_it_prof_incr 0x00000004
-#define AOFF_task_it_virt_incr 0x000000b0
+#define AOFF_task_it_virt_incr 0x000000ac
 #define ASIZ_task_it_virt_incr 0x00000004
-#define AOFF_task_real_timer   0x000000b4
+#define AOFF_task_real_timer   0x000000b0
 #define ASIZ_task_real_timer   0x00000014
-#define AOFF_task_times        0x000000c8
+#define AOFF_task_times        0x000000c4
 #define ASIZ_task_times        0x00000010
-#define AOFF_task_start_time   0x000000d8
+#define AOFF_task_start_time   0x000000d4
 #define ASIZ_task_start_time   0x00000004
-#define AOFF_task_per_cpu_utime        0x000000dc
+#define AOFF_task_per_cpu_utime        0x000000d8
 #define ASIZ_task_per_cpu_utime        0x00000080
-#define AOFF_task_min_flt      0x000001dc
+#define AOFF_task_min_flt      0x000001d8
 #define ASIZ_task_min_flt      0x00000004
-#define AOFF_task_maj_flt      0x000001e0
+#define AOFF_task_maj_flt      0x000001dc
 #define ASIZ_task_maj_flt      0x00000004
-#define AOFF_task_nswap        0x000001e4
+#define AOFF_task_nswap        0x000001e0
 #define ASIZ_task_nswap        0x00000004
-#define AOFF_task_cmin_flt     0x000001e8
+#define AOFF_task_cmin_flt     0x000001e4
 #define ASIZ_task_cmin_flt     0x00000004
-#define AOFF_task_cmaj_flt     0x000001ec
+#define AOFF_task_cmaj_flt     0x000001e8
 #define ASIZ_task_cmaj_flt     0x00000004
-#define AOFF_task_cnswap       0x000001f0
+#define AOFF_task_cnswap       0x000001ec
 #define ASIZ_task_cnswap       0x00000004
-#define AOFF_task_swap_address 0x000001f8
+#define AOFF_task_swap_address 0x000001f4
 #define ASIZ_task_swap_address 0x00000004
-#define AOFF_task_old_maj_flt  0x000001fc
+#define AOFF_task_old_maj_flt  0x000001f8
 #define ASIZ_task_old_maj_flt  0x00000004
-#define AOFF_task_dec_flt      0x00000200
+#define AOFF_task_dec_flt      0x000001fc
 #define ASIZ_task_dec_flt      0x00000004
-#define AOFF_task_swap_cnt     0x00000204
+#define AOFF_task_swap_cnt     0x00000200
 #define ASIZ_task_swap_cnt     0x00000004
-#define AOFF_task_uid  0x00000208
+#define AOFF_task_uid  0x00000204
 #define ASIZ_task_uid  0x00000002
-#define AOFF_task_euid 0x0000020a
+#define AOFF_task_euid 0x00000206
 #define ASIZ_task_euid 0x00000002
-#define AOFF_task_suid 0x0000020c
+#define AOFF_task_suid 0x00000208
 #define ASIZ_task_suid 0x00000002
-#define AOFF_task_fsuid        0x0000020e
+#define AOFF_task_fsuid        0x0000020a
 #define ASIZ_task_fsuid        0x00000002
-#define AOFF_task_gid  0x00000210
+#define AOFF_task_gid  0x0000020c
 #define ASIZ_task_gid  0x00000002
-#define AOFF_task_egid 0x00000212
+#define AOFF_task_egid 0x0000020e
 #define ASIZ_task_egid 0x00000002
-#define AOFF_task_sgid 0x00000214
+#define AOFF_task_sgid 0x00000210
 #define ASIZ_task_sgid 0x00000002
-#define AOFF_task_fsgid        0x00000216
+#define AOFF_task_fsgid        0x00000212
 #define ASIZ_task_fsgid        0x00000002
-#define AOFF_task_ngroups      0x00000218
+#define AOFF_task_ngroups      0x00000214
 #define ASIZ_task_ngroups      0x00000004
-#define AOFF_task_groups       0x0000021c
+#define AOFF_task_groups       0x00000218
 #define ASIZ_task_groups       0x00000040
-#define AOFF_task_cap_effective        0x0000025c
+#define AOFF_task_cap_effective        0x00000258
 #define ASIZ_task_cap_effective        0x00000004
-#define AOFF_task_cap_inheritable      0x00000260
+#define AOFF_task_cap_inheritable      0x0000025c
 #define ASIZ_task_cap_inheritable      0x00000004
-#define AOFF_task_cap_permitted        0x00000264
+#define AOFF_task_cap_permitted        0x00000260
 #define ASIZ_task_cap_permitted        0x00000004
-#define AOFF_task_user 0x00000268
+#define AOFF_task_user 0x00000264
 #define ASIZ_task_user 0x00000004
-#define AOFF_task_rlim 0x0000026c
+#define AOFF_task_rlim 0x00000268
 #define ASIZ_task_rlim 0x00000050
-#define AOFF_task_used_math    0x000002bc
+#define AOFF_task_used_math    0x000002b8
 #define ASIZ_task_used_math    0x00000002
-#define AOFF_task_comm 0x000002be
+#define AOFF_task_comm 0x000002ba
 #define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count   0x000002d0
+#define AOFF_task_link_count   0x000002cc
 #define ASIZ_task_link_count   0x00000004
-#define AOFF_task_tty  0x000002d4
+#define AOFF_task_tty  0x000002d0
 #define ASIZ_task_tty  0x00000004
-#define AOFF_task_semundo      0x000002d8
+#define AOFF_task_semundo      0x000002d4
 #define ASIZ_task_semundo      0x00000004
-#define AOFF_task_semsleeping  0x000002dc
+#define AOFF_task_semsleeping  0x000002d8
 #define ASIZ_task_semsleeping  0x00000004
 #define AOFF_task_tss  0x000002e0
 #define ASIZ_task_tss  0x00000388
index d76219df47be05c979f923e05ebd7fa527492670..aac5f374cfa45f8e2cc1c55ef28a354e97c39043 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <asm/page.h>
 #include <asm/spinlock.h>
+#include <asm/pgtable.h>
 
 /* The io-unit handles all virtual to physical address translations
  * that occur between the SBUS and physical memory.  Access by
@@ -50,4 +51,8 @@ struct iounit_struct {
 #define IOUNIT_BMAPM_START     IOUNIT_BMAP2_END
 #define IOUNIT_BMAPM_END       ((IOUNIT_DMA_SIZE - IOUNIT_DVMA_SIZE) >> PAGE_SHIFT)
 
+extern __u32 iounit_map_dma_init(struct linux_sbus *, int);
+#define iounit_map_dma_finish(sbus, addr, len) mmu_release_scsi_one(addr, len, sbus)
+extern __u32 iounit_map_dma_page(__u32, void *, struct linux_sbus *);
+
 #endif /* !(_SPARC_IO_UNIT_H) */
index 401e8082006c534499a977870df50a37b9a1a21d..29f672eb56baad6c781ecbf47841a1b1f29e19d9 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: namei.h,v 1.11 1998/01/15 12:58:24 jj Exp $
+/* $Id: namei.h,v 1.12 1998/10/28 08:13:42 jj Exp $
  * linux/include/asm-sparc/namei.h
  *
  * Routines to handle famous /usr/gnemul/s*.
@@ -12,7 +12,7 @@
 #define SPARC_SOL_EMUL "usr/gnemul/solaris/"
 
 static inline struct dentry *
-__sparc_lookup_dentry(const char *name, int follow_link)
+__sparc_lookup_dentry(const char *name, int lookup_flags)
 {
        struct dentry *base;
        char *emul;
@@ -29,18 +29,20 @@ __sparc_lookup_dentry(const char *name, int follow_link)
                return NULL;
        }
 
-       base = lookup_dentry (emul, dget (current->fs->root), 1);
+       base = lookup_dentry (emul, 
+                             dget (current->fs->root),
+                             (LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_SLASHOK));
                        
        if (IS_ERR (base)) return NULL;
        
-       base = lookup_dentry (name, base, follow_link);
+       base = lookup_dentry (name, base, lookup_flags);
        
        if (IS_ERR (base)) return NULL;
        
        if (!base->d_inode) {
                struct dentry *fromroot;
                
-               fromroot = lookup_dentry (name, dget (current->fs->root), follow_link);
+               fromroot = lookup_dentry (name, dget (current->fs->root), lookup_flags);
                
                if (IS_ERR (fromroot)) return base;
                
@@ -55,9 +57,9 @@ __sparc_lookup_dentry(const char *name, int follow_link)
        return base;
 }
 
-#define __prefix_lookup_dentry(name, follow_link)                              \
+#define __prefix_lookup_dentry(name, lookup_flags)                             \
        if (current->personality) {                                             \
-               dentry = __sparc_lookup_dentry (name, follow_link);             \
+               dentry = __sparc_lookup_dentry (name, lookup_flags);            \
                if (dentry) return dentry;                                      \
        }
 
index 2a4b6a69f2237b533524aef9a4fa58095362f044..91afa084097358bbb3bbea591e7b5e72c045c2ba 100644 (file)
@@ -150,11 +150,12 @@ extern __inline__ int hard_smp_processor_id(void)
 #else
 extern __inline__ int hard_smp_processor_id(void)
 {
-       int cpuid __asm__ ("g2");
+       int cpuid;
        
        __asm__ __volatile__("mov %%o7, %%g1\n\t"
                             "call ___f___smp_processor_id\n\t"
-                            " nop\n\t" : "=r"(cpuid) : : "g1");
+                            " nop\n\t"
+                            "mov %%g2, %0\n\t" : "=r"(cpuid) : : "g1", "g2");
        return cpuid;
 }
 #endif
index 517b0cc2ce2f32ef7288aac0592d0767220138cb..e58ffe605d3987146572f512364c29df3b5d5677 100644 (file)
@@ -34,8 +34,8 @@ typedef unsigned char spinlock_t;
  * irq-safe write-lock, but readers can get non-irqsafe
  * read-locks.
  */
-typedef struct { } rwlock_t;
-#define RW_LOCK_UNLOCKED { }
+typedef struct { volatile unsigned int lock; } rwlock_t;
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 
 #define read_lock(lock)                do { } while(0)
 #define read_unlock(lock)      do { } while(0)
@@ -65,7 +65,7 @@ struct _spinlock_debug {
 };
 typedef struct _spinlock_debug spinlock_t;
 
-#define SPIN_LOCK_UNLOCKED     { 0, 0 }
+#define SPIN_LOCK_UNLOCKED     (spinlock_t) { 0, 0 }
 #define spin_lock_init(lp)     do { (lp)->owner_pc = 0; (lp)->lock = 0; } while(0)
 #define spin_unlock_wait(lp)   do { barrier(); } while(*(volatile unsigned char *)(&(lp)->lock))
 
@@ -90,7 +90,7 @@ struct _rwlock_debug {
 };
 typedef struct _rwlock_debug rwlock_t;
 
-#define RW_LOCK_UNLOCKED { 0, 0, {0} }
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, {0} }
 
 extern void _do_read_lock(rwlock_t *rw, char *str);
 extern void _do_read_unlock(rwlock_t *rw, char *str);
@@ -260,7 +260,7 @@ extern __inline__ void spin_unlock_irqrestore(spinlock_t *lock, unsigned long fl
  */
 typedef struct { volatile unsigned int lock; } rwlock_t;
 
-#define RW_LOCK_UNLOCKED { 0 }
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 
 /* Sort of like atomic_t's on Sparc, but even more clever.
  *
index 20019252853d42f9ee6d577952ee8756896a7667..52f6a9ee083e7574c297772e5d62fea59104ddae 100644 (file)
 #define ASIZ_task_tarray_ptr   0x00000008
 #define AOFF_task_wait_chldexit        0x000000e8
 #define ASIZ_task_wait_chldexit        0x00000008
-#define AOFF_task_timeout      0x000000f0
-#define ASIZ_task_timeout      0x00000008
-#define AOFF_task_policy       0x000000f8
+#define AOFF_task_policy       0x000000f0
 #define ASIZ_task_policy       0x00000008
-#define AOFF_task_rt_priority  0x00000100
+#define AOFF_task_rt_priority  0x000000f8
 #define ASIZ_task_rt_priority  0x00000008
-#define AOFF_task_it_real_value        0x00000108
+#define AOFF_task_it_real_value        0x00000100
 #define ASIZ_task_it_real_value        0x00000008
-#define AOFF_task_it_prof_value        0x00000110
+#define AOFF_task_it_prof_value        0x00000108
 #define ASIZ_task_it_prof_value        0x00000008
-#define AOFF_task_it_virt_value        0x00000118
+#define AOFF_task_it_virt_value        0x00000110
 #define ASIZ_task_it_virt_value        0x00000008
-#define AOFF_task_it_real_incr 0x00000120
+#define AOFF_task_it_real_incr 0x00000118
 #define ASIZ_task_it_real_incr 0x00000008
-#define AOFF_task_it_prof_incr 0x00000128
+#define AOFF_task_it_prof_incr 0x00000120
 #define ASIZ_task_it_prof_incr 0x00000008
-#define AOFF_task_it_virt_incr 0x00000130
+#define AOFF_task_it_virt_incr 0x00000128
 #define ASIZ_task_it_virt_incr 0x00000008
-#define AOFF_task_real_timer   0x00000138
+#define AOFF_task_real_timer   0x00000130
 #define ASIZ_task_real_timer   0x00000028
-#define AOFF_task_times        0x00000160
+#define AOFF_task_times        0x00000158
 #define ASIZ_task_times        0x00000020
-#define AOFF_task_start_time   0x00000180
+#define AOFF_task_start_time   0x00000178
 #define ASIZ_task_start_time   0x00000008
-#define AOFF_task_per_cpu_utime        0x00000188
+#define AOFF_task_per_cpu_utime        0x00000180
 #define ASIZ_task_per_cpu_utime        0x00000008
-#define AOFF_task_min_flt      0x00000198
+#define AOFF_task_min_flt      0x00000190
 #define ASIZ_task_min_flt      0x00000008
-#define AOFF_task_maj_flt      0x000001a0
+#define AOFF_task_maj_flt      0x00000198
 #define ASIZ_task_maj_flt      0x00000008
-#define AOFF_task_nswap        0x000001a8
+#define AOFF_task_nswap        0x000001a0
 #define ASIZ_task_nswap        0x00000008
-#define AOFF_task_cmin_flt     0x000001b0
+#define AOFF_task_cmin_flt     0x000001a8
 #define ASIZ_task_cmin_flt     0x00000008
-#define AOFF_task_cmaj_flt     0x000001b8
+#define AOFF_task_cmaj_flt     0x000001b0
 #define ASIZ_task_cmaj_flt     0x00000008
-#define AOFF_task_cnswap       0x000001c0
+#define AOFF_task_cnswap       0x000001b8
 #define ASIZ_task_cnswap       0x00000008
-#define AOFF_task_swap_address 0x000001d0
+#define AOFF_task_swap_address 0x000001c8
 #define ASIZ_task_swap_address 0x00000008
-#define AOFF_task_old_maj_flt  0x000001d8
+#define AOFF_task_old_maj_flt  0x000001d0
 #define ASIZ_task_old_maj_flt  0x00000008
-#define AOFF_task_dec_flt      0x000001e0
+#define AOFF_task_dec_flt      0x000001d8
 #define ASIZ_task_dec_flt      0x00000008
-#define AOFF_task_swap_cnt     0x000001e8
+#define AOFF_task_swap_cnt     0x000001e0
 #define ASIZ_task_swap_cnt     0x00000008
-#define AOFF_task_uid  0x000001f0
+#define AOFF_task_uid  0x000001e8
 #define ASIZ_task_uid  0x00000004
-#define AOFF_task_euid 0x000001f4
+#define AOFF_task_euid 0x000001ec
 #define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x000001f8
+#define AOFF_task_suid 0x000001f0
 #define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid        0x000001fc
+#define AOFF_task_fsuid        0x000001f4
 #define ASIZ_task_fsuid        0x00000004
-#define AOFF_task_gid  0x00000200
+#define AOFF_task_gid  0x000001f8
 #define ASIZ_task_gid  0x00000004
-#define AOFF_task_egid 0x00000204
+#define AOFF_task_egid 0x000001fc
 #define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x00000208
+#define AOFF_task_sgid 0x00000200
 #define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid        0x0000020c
+#define AOFF_task_fsgid        0x00000204
 #define ASIZ_task_fsgid        0x00000004
-#define AOFF_task_ngroups      0x00000210
+#define AOFF_task_ngroups      0x00000208
 #define ASIZ_task_ngroups      0x00000004
-#define AOFF_task_groups       0x00000214
+#define AOFF_task_groups       0x0000020c
 #define ASIZ_task_groups       0x00000080
-#define AOFF_task_cap_effective        0x00000294
+#define AOFF_task_cap_effective        0x0000028c
 #define ASIZ_task_cap_effective        0x00000004
-#define AOFF_task_cap_inheritable      0x00000298
+#define AOFF_task_cap_inheritable      0x00000290
 #define ASIZ_task_cap_inheritable      0x00000004
-#define AOFF_task_cap_permitted        0x0000029c
+#define AOFF_task_cap_permitted        0x00000294
 #define ASIZ_task_cap_permitted        0x00000004
-#define AOFF_task_user 0x000002a0
+#define AOFF_task_user 0x00000298
 #define ASIZ_task_user 0x00000008
-#define AOFF_task_rlim 0x000002a8
+#define AOFF_task_rlim 0x000002a0
 #define ASIZ_task_rlim 0x000000a0
-#define AOFF_task_used_math    0x00000348
+#define AOFF_task_used_math    0x00000340
 #define ASIZ_task_used_math    0x00000002
-#define AOFF_task_comm 0x0000034a
+#define AOFF_task_comm 0x00000342
 #define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count   0x0000035c
+#define AOFF_task_link_count   0x00000354
 #define ASIZ_task_link_count   0x00000004
-#define AOFF_task_tty  0x00000360
+#define AOFF_task_tty  0x00000358
 #define ASIZ_task_tty  0x00000008
-#define AOFF_task_semundo      0x00000368
+#define AOFF_task_semundo      0x00000360
 #define ASIZ_task_semundo      0x00000008
-#define AOFF_task_semsleeping  0x00000370
+#define AOFF_task_semsleeping  0x00000368
 #define ASIZ_task_semsleeping  0x00000008
-#define AOFF_task_tss  0x00000380
+#define AOFF_task_tss  0x00000370
 #define ASIZ_task_tss  0x00000470
-#define AOFF_task_fs   0x000007f0
+#define AOFF_task_fs   0x000007e0
 #define ASIZ_task_fs   0x00000008
-#define AOFF_task_files        0x000007f8
+#define AOFF_task_files        0x000007e8
 #define ASIZ_task_files        0x00000008
-#define AOFF_task_mm   0x00000800
+#define AOFF_task_mm   0x000007f0
 #define ASIZ_task_mm   0x00000008
-#define AOFF_task_sigmask_lock 0x00000808
+#define AOFF_task_sigmask_lock 0x000007f8
 #define ASIZ_task_sigmask_lock 0x00000001
-#define AOFF_task_sig  0x00000810
+#define AOFF_task_sig  0x00000800
 #define ASIZ_task_sig  0x00000008
-#define AOFF_task_signal       0x00000818
+#define AOFF_task_signal       0x00000808
 #define ASIZ_task_signal       0x00000008
-#define AOFF_task_blocked      0x00000820
+#define AOFF_task_blocked      0x00000810
 #define ASIZ_task_blocked      0x00000008
-#define AOFF_task_sigqueue     0x00000828
+#define AOFF_task_sigqueue     0x00000818
 #define ASIZ_task_sigqueue     0x00000008
-#define AOFF_task_sigqueue_tail        0x00000830
+#define AOFF_task_sigqueue_tail        0x00000820
 #define ASIZ_task_sigqueue_tail        0x00000008
-#define AOFF_task_sas_ss_sp    0x00000838
+#define AOFF_task_sas_ss_sp    0x00000828
 #define ASIZ_task_sas_ss_sp    0x00000008
-#define AOFF_task_sas_ss_size  0x00000840
+#define AOFF_task_sas_ss_size  0x00000830
 #define ASIZ_task_sas_ss_size  0x00000008
-#define ASIZ_task      0x00000850
+#define ASIZ_task      0x00000840
 #define AOFF_mm_mmap   0x00000000
 #define ASIZ_mm_mmap   0x00000008
 #define AOFF_mm_mmap_cache     0x00000008
 #define ASIZ_task_tarray_ptr   0x00000008
 #define AOFF_task_wait_chldexit        0x000000e8
 #define ASIZ_task_wait_chldexit        0x00000008
-#define AOFF_task_timeout      0x000000f0
-#define ASIZ_task_timeout      0x00000008
-#define AOFF_task_policy       0x000000f8
+#define AOFF_task_policy       0x000000f0
 #define ASIZ_task_policy       0x00000008
-#define AOFF_task_rt_priority  0x00000100
+#define AOFF_task_rt_priority  0x000000f8
 #define ASIZ_task_rt_priority  0x00000008
-#define AOFF_task_it_real_value        0x00000108
+#define AOFF_task_it_real_value        0x00000100
 #define ASIZ_task_it_real_value        0x00000008
-#define AOFF_task_it_prof_value        0x00000110
+#define AOFF_task_it_prof_value        0x00000108
 #define ASIZ_task_it_prof_value        0x00000008
-#define AOFF_task_it_virt_value        0x00000118
+#define AOFF_task_it_virt_value        0x00000110
 #define ASIZ_task_it_virt_value        0x00000008
-#define AOFF_task_it_real_incr 0x00000120
+#define AOFF_task_it_real_incr 0x00000118
 #define ASIZ_task_it_real_incr 0x00000008
-#define AOFF_task_it_prof_incr 0x00000128
+#define AOFF_task_it_prof_incr 0x00000120
 #define ASIZ_task_it_prof_incr 0x00000008
-#define AOFF_task_it_virt_incr 0x00000130
+#define AOFF_task_it_virt_incr 0x00000128
 #define ASIZ_task_it_virt_incr 0x00000008
-#define AOFF_task_real_timer   0x00000138
+#define AOFF_task_real_timer   0x00000130
 #define ASIZ_task_real_timer   0x00000028
-#define AOFF_task_times        0x00000160
+#define AOFF_task_times        0x00000158
 #define ASIZ_task_times        0x00000020
-#define AOFF_task_start_time   0x00000180
+#define AOFF_task_start_time   0x00000178
 #define ASIZ_task_start_time   0x00000008
-#define AOFF_task_per_cpu_utime        0x00000188
+#define AOFF_task_per_cpu_utime        0x00000180
 #define ASIZ_task_per_cpu_utime        0x00000100
-#define AOFF_task_min_flt      0x00000388
+#define AOFF_task_min_flt      0x00000380
 #define ASIZ_task_min_flt      0x00000008
-#define AOFF_task_maj_flt      0x00000390
+#define AOFF_task_maj_flt      0x00000388
 #define ASIZ_task_maj_flt      0x00000008
-#define AOFF_task_nswap        0x00000398
+#define AOFF_task_nswap        0x00000390
 #define ASIZ_task_nswap        0x00000008
-#define AOFF_task_cmin_flt     0x000003a0
+#define AOFF_task_cmin_flt     0x00000398
 #define ASIZ_task_cmin_flt     0x00000008
-#define AOFF_task_cmaj_flt     0x000003a8
+#define AOFF_task_cmaj_flt     0x000003a0
 #define ASIZ_task_cmaj_flt     0x00000008
-#define AOFF_task_cnswap       0x000003b0
+#define AOFF_task_cnswap       0x000003a8
 #define ASIZ_task_cnswap       0x00000008
-#define AOFF_task_swap_address 0x000003c0
+#define AOFF_task_swap_address 0x000003b8
 #define ASIZ_task_swap_address 0x00000008
-#define AOFF_task_old_maj_flt  0x000003c8
+#define AOFF_task_old_maj_flt  0x000003c0
 #define ASIZ_task_old_maj_flt  0x00000008
-#define AOFF_task_dec_flt      0x000003d0
+#define AOFF_task_dec_flt      0x000003c8
 #define ASIZ_task_dec_flt      0x00000008
-#define AOFF_task_swap_cnt     0x000003d8
+#define AOFF_task_swap_cnt     0x000003d0
 #define ASIZ_task_swap_cnt     0x00000008
-#define AOFF_task_uid  0x000003e0
+#define AOFF_task_uid  0x000003d8
 #define ASIZ_task_uid  0x00000004
-#define AOFF_task_euid 0x000003e4
+#define AOFF_task_euid 0x000003dc
 #define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x000003e8
+#define AOFF_task_suid 0x000003e0
 #define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid        0x000003ec
+#define AOFF_task_fsuid        0x000003e4
 #define ASIZ_task_fsuid        0x00000004
-#define AOFF_task_gid  0x000003f0
+#define AOFF_task_gid  0x000003e8
 #define ASIZ_task_gid  0x00000004
-#define AOFF_task_egid 0x000003f4
+#define AOFF_task_egid 0x000003ec
 #define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x000003f8
+#define AOFF_task_sgid 0x000003f0
 #define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid        0x000003fc
+#define AOFF_task_fsgid        0x000003f4
 #define ASIZ_task_fsgid        0x00000004
-#define AOFF_task_ngroups      0x00000400
+#define AOFF_task_ngroups      0x000003f8
 #define ASIZ_task_ngroups      0x00000004
-#define AOFF_task_groups       0x00000404
+#define AOFF_task_groups       0x000003fc
 #define ASIZ_task_groups       0x00000080
-#define AOFF_task_cap_effective        0x00000484
+#define AOFF_task_cap_effective        0x0000047c
 #define ASIZ_task_cap_effective        0x00000004
-#define AOFF_task_cap_inheritable      0x00000488
+#define AOFF_task_cap_inheritable      0x00000480
 #define ASIZ_task_cap_inheritable      0x00000004
-#define AOFF_task_cap_permitted        0x0000048c
+#define AOFF_task_cap_permitted        0x00000484
 #define ASIZ_task_cap_permitted        0x00000004
-#define AOFF_task_user 0x00000490
+#define AOFF_task_user 0x00000488
 #define ASIZ_task_user 0x00000008
-#define AOFF_task_rlim 0x00000498
+#define AOFF_task_rlim 0x00000490
 #define ASIZ_task_rlim 0x000000a0
-#define AOFF_task_used_math    0x00000538
+#define AOFF_task_used_math    0x00000530
 #define ASIZ_task_used_math    0x00000002
-#define AOFF_task_comm 0x0000053a
+#define AOFF_task_comm 0x00000532
 #define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count   0x0000054c
+#define AOFF_task_link_count   0x00000544
 #define ASIZ_task_link_count   0x00000004
-#define AOFF_task_tty  0x00000550
+#define AOFF_task_tty  0x00000548
 #define ASIZ_task_tty  0x00000008
-#define AOFF_task_semundo      0x00000558
+#define AOFF_task_semundo      0x00000550
 #define ASIZ_task_semundo      0x00000008
-#define AOFF_task_semsleeping  0x00000560
+#define AOFF_task_semsleeping  0x00000558
 #define ASIZ_task_semsleeping  0x00000008
-#define AOFF_task_tss  0x00000570
+#define AOFF_task_tss  0x00000560
 #define ASIZ_task_tss  0x00000470
-#define AOFF_task_fs   0x000009e0
+#define AOFF_task_fs   0x000009d0
 #define ASIZ_task_fs   0x00000008
-#define AOFF_task_files        0x000009e8
+#define AOFF_task_files        0x000009d8
 #define ASIZ_task_files        0x00000008
-#define AOFF_task_mm   0x000009f0
+#define AOFF_task_mm   0x000009e0
 #define ASIZ_task_mm   0x00000008
-#define AOFF_task_sigmask_lock 0x000009f8
+#define AOFF_task_sigmask_lock 0x000009e8
 #define ASIZ_task_sigmask_lock 0x00000001
-#define AOFF_task_sig  0x00000a00
+#define AOFF_task_sig  0x000009f0
 #define ASIZ_task_sig  0x00000008
-#define AOFF_task_signal       0x00000a08
+#define AOFF_task_signal       0x000009f8
 #define ASIZ_task_signal       0x00000008
-#define AOFF_task_blocked      0x00000a10
+#define AOFF_task_blocked      0x00000a00
 #define ASIZ_task_blocked      0x00000008
-#define AOFF_task_sigqueue     0x00000a18
+#define AOFF_task_sigqueue     0x00000a08
 #define ASIZ_task_sigqueue     0x00000008
-#define AOFF_task_sigqueue_tail        0x00000a20
+#define AOFF_task_sigqueue_tail        0x00000a10
 #define ASIZ_task_sigqueue_tail        0x00000008
-#define AOFF_task_sas_ss_sp    0x00000a28
+#define AOFF_task_sas_ss_sp    0x00000a18
 #define ASIZ_task_sas_ss_sp    0x00000008
-#define AOFF_task_sas_ss_size  0x00000a30
+#define AOFF_task_sas_ss_size  0x00000a20
 #define ASIZ_task_sas_ss_size  0x00000008
-#define ASIZ_task      0x00000a40
+#define ASIZ_task      0x00000a30
 #define AOFF_mm_mmap   0x00000000
 #define ASIZ_mm_mmap   0x00000008
 #define AOFF_mm_mmap_cache     0x00000008
 #define ASIZ_task_tarray_ptr   0x00000008
 #define AOFF_task_wait_chldexit        0x000000e8
 #define ASIZ_task_wait_chldexit        0x00000008
-#define AOFF_task_timeout      0x000000f0
-#define ASIZ_task_timeout      0x00000008
-#define AOFF_task_policy       0x000000f8
+#define AOFF_task_policy       0x000000f0
 #define ASIZ_task_policy       0x00000008
-#define AOFF_task_rt_priority  0x00000100
+#define AOFF_task_rt_priority  0x000000f8
 #define ASIZ_task_rt_priority  0x00000008
-#define AOFF_task_it_real_value        0x00000108
+#define AOFF_task_it_real_value        0x00000100
 #define ASIZ_task_it_real_value        0x00000008
-#define AOFF_task_it_prof_value        0x00000110
+#define AOFF_task_it_prof_value        0x00000108
 #define ASIZ_task_it_prof_value        0x00000008
-#define AOFF_task_it_virt_value        0x00000118
+#define AOFF_task_it_virt_value        0x00000110
 #define ASIZ_task_it_virt_value        0x00000008
-#define AOFF_task_it_real_incr 0x00000120
+#define AOFF_task_it_real_incr 0x00000118
 #define ASIZ_task_it_real_incr 0x00000008
-#define AOFF_task_it_prof_incr 0x00000128
+#define AOFF_task_it_prof_incr 0x00000120
 #define ASIZ_task_it_prof_incr 0x00000008
-#define AOFF_task_it_virt_incr 0x00000130
+#define AOFF_task_it_virt_incr 0x00000128
 #define ASIZ_task_it_virt_incr 0x00000008
-#define AOFF_task_real_timer   0x00000138
+#define AOFF_task_real_timer   0x00000130
 #define ASIZ_task_real_timer   0x00000028
-#define AOFF_task_times        0x00000160
+#define AOFF_task_times        0x00000158
 #define ASIZ_task_times        0x00000020
-#define AOFF_task_start_time   0x00000180
+#define AOFF_task_start_time   0x00000178
 #define ASIZ_task_start_time   0x00000008
-#define AOFF_task_per_cpu_utime        0x00000188
+#define AOFF_task_per_cpu_utime        0x00000180
 #define ASIZ_task_per_cpu_utime        0x00000100
-#define AOFF_task_min_flt      0x00000388
+#define AOFF_task_min_flt      0x00000380
 #define ASIZ_task_min_flt      0x00000008
-#define AOFF_task_maj_flt      0x00000390
+#define AOFF_task_maj_flt      0x00000388
 #define ASIZ_task_maj_flt      0x00000008
-#define AOFF_task_nswap        0x00000398
+#define AOFF_task_nswap        0x00000390
 #define ASIZ_task_nswap        0x00000008
-#define AOFF_task_cmin_flt     0x000003a0
+#define AOFF_task_cmin_flt     0x00000398
 #define ASIZ_task_cmin_flt     0x00000008
-#define AOFF_task_cmaj_flt     0x000003a8
+#define AOFF_task_cmaj_flt     0x000003a0
 #define ASIZ_task_cmaj_flt     0x00000008
-#define AOFF_task_cnswap       0x000003b0
+#define AOFF_task_cnswap       0x000003a8
 #define ASIZ_task_cnswap       0x00000008
-#define AOFF_task_swap_address 0x000003c0
+#define AOFF_task_swap_address 0x000003b8
 #define ASIZ_task_swap_address 0x00000008
-#define AOFF_task_old_maj_flt  0x000003c8
+#define AOFF_task_old_maj_flt  0x000003c0
 #define ASIZ_task_old_maj_flt  0x00000008
-#define AOFF_task_dec_flt      0x000003d0
+#define AOFF_task_dec_flt      0x000003c8
 #define ASIZ_task_dec_flt      0x00000008
-#define AOFF_task_swap_cnt     0x000003d8
+#define AOFF_task_swap_cnt     0x000003d0
 #define ASIZ_task_swap_cnt     0x00000008
-#define AOFF_task_uid  0x000003e0
+#define AOFF_task_uid  0x000003d8
 #define ASIZ_task_uid  0x00000004
-#define AOFF_task_euid 0x000003e4
+#define AOFF_task_euid 0x000003dc
 #define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x000003e8
+#define AOFF_task_suid 0x000003e0
 #define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid        0x000003ec
+#define AOFF_task_fsuid        0x000003e4
 #define ASIZ_task_fsuid        0x00000004
-#define AOFF_task_gid  0x000003f0
+#define AOFF_task_gid  0x000003e8
 #define ASIZ_task_gid  0x00000004
-#define AOFF_task_egid 0x000003f4
+#define AOFF_task_egid 0x000003ec
 #define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x000003f8
+#define AOFF_task_sgid 0x000003f0
 #define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid        0x000003fc
+#define AOFF_task_fsgid        0x000003f4
 #define ASIZ_task_fsgid        0x00000004
-#define AOFF_task_ngroups      0x00000400
+#define AOFF_task_ngroups      0x000003f8
 #define ASIZ_task_ngroups      0x00000004
-#define AOFF_task_groups       0x00000404
+#define AOFF_task_groups       0x000003fc
 #define ASIZ_task_groups       0x00000080
-#define AOFF_task_cap_effective        0x00000484
+#define AOFF_task_cap_effective        0x0000047c
 #define ASIZ_task_cap_effective        0x00000004
-#define AOFF_task_cap_inheritable      0x00000488
+#define AOFF_task_cap_inheritable      0x00000480
 #define ASIZ_task_cap_inheritable      0x00000004
-#define AOFF_task_cap_permitted        0x0000048c
+#define AOFF_task_cap_permitted        0x00000484
 #define ASIZ_task_cap_permitted        0x00000004
-#define AOFF_task_user 0x00000490
+#define AOFF_task_user 0x00000488
 #define ASIZ_task_user 0x00000008
-#define AOFF_task_rlim 0x00000498
+#define AOFF_task_rlim 0x00000490
 #define ASIZ_task_rlim 0x000000a0
-#define AOFF_task_used_math    0x00000538
+#define AOFF_task_used_math    0x00000530
 #define ASIZ_task_used_math    0x00000002
-#define AOFF_task_comm 0x0000053a
+#define AOFF_task_comm 0x00000532
 #define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count   0x0000054c
+#define AOFF_task_link_count   0x00000544
 #define ASIZ_task_link_count   0x00000004
-#define AOFF_task_tty  0x00000550
+#define AOFF_task_tty  0x00000548
 #define ASIZ_task_tty  0x00000008
-#define AOFF_task_semundo      0x00000558
+#define AOFF_task_semundo      0x00000550
 #define ASIZ_task_semundo      0x00000008
-#define AOFF_task_semsleeping  0x00000560
+#define AOFF_task_semsleeping  0x00000558
 #define ASIZ_task_semsleeping  0x00000008
-#define AOFF_task_tss  0x00000570
+#define AOFF_task_tss  0x00000560
 #define ASIZ_task_tss  0x00000470
-#define AOFF_task_fs   0x000009e0
+#define AOFF_task_fs   0x000009d0
 #define ASIZ_task_fs   0x00000008
-#define AOFF_task_files        0x000009e8
+#define AOFF_task_files        0x000009d8
 #define ASIZ_task_files        0x00000008
-#define AOFF_task_mm   0x000009f0
+#define AOFF_task_mm   0x000009e0
 #define ASIZ_task_mm   0x00000008
-#define AOFF_task_sigmask_lock 0x000009f8
+#define AOFF_task_sigmask_lock 0x000009e8
 #define ASIZ_task_sigmask_lock 0x0000000c
-#define AOFF_task_sig  0x00000a08
+#define AOFF_task_sig  0x000009f8
 #define ASIZ_task_sig  0x00000008
-#define AOFF_task_signal       0x00000a10
+#define AOFF_task_signal       0x00000a00
 #define ASIZ_task_signal       0x00000008
-#define AOFF_task_blocked      0x00000a18
+#define AOFF_task_blocked      0x00000a08
 #define ASIZ_task_blocked      0x00000008
-#define AOFF_task_sigqueue     0x00000a20
+#define AOFF_task_sigqueue     0x00000a10
 #define ASIZ_task_sigqueue     0x00000008
-#define AOFF_task_sigqueue_tail        0x00000a28
+#define AOFF_task_sigqueue_tail        0x00000a18
 #define ASIZ_task_sigqueue_tail        0x00000008
-#define AOFF_task_sas_ss_sp    0x00000a30
+#define AOFF_task_sas_ss_sp    0x00000a20
 #define ASIZ_task_sas_ss_sp    0x00000008
-#define AOFF_task_sas_ss_size  0x00000a38
+#define AOFF_task_sas_ss_size  0x00000a28
 #define ASIZ_task_sas_ss_size  0x00000008
-#define ASIZ_task      0x00000a40
+#define ASIZ_task      0x00000a30
 #define AOFF_mm_mmap   0x00000000
 #define ASIZ_mm_mmap   0x00000008
 #define AOFF_mm_mmap_cache     0x00000008
index 6e756de28d6d871e2509516e4b082cd500739d06..e6175ab4f82caeb9f80fd47415d1d22ed89a9125 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: dma.h,v 1.9 1998/10/26 20:03:15 davem Exp $
+/* $Id: dma.h,v 1.10 1998/10/27 23:28:50 davem Exp $
  * include/asm-sparc64/dma.h
  *
  * Copyright 1996 (C) David S. Miller (davem@caip.rutgers.edu)
 
 extern spinlock_t  dma_spin_lock;
 
-static __inline__ unsigned long claim_dma_lock(void)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&dma_spin_lock, flags);
-       return flags;
-}
-
-static __inline__ void release_dma_lock(unsigned long flags)
-{
-       spin_unlock_irqrestore(&dma_spin_lock, flags);
-}
+#define claim_dma_lock() \
+({     unsigned long flags; \
+       spin_lock_irqsave(&dma_spin_lock, flags); \
+       flags; \
+})
+
+#define release_dma_lock(__flags) \
+       spin_unlock_irqrestore(&dma_spin_lock, __flags);
 
 /* These are irrelevant for Sparc DMA, but we leave it in so that
  * things can compile.
index dbd89303bfec230993eb6ae5936173593b1dd976..1e21247974dfc400aedee746a16b3afba1b32082 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: namei.h,v 1.12 1998/03/13 17:38:13 jj Exp $
+/* $Id: namei.h,v 1.13 1998/10/28 08:13:49 jj Exp $
  * linux/include/asm-sparc64/namei.h
  *
  * Routines to handle famous /usr/gnemul/s*.
@@ -29,7 +29,9 @@ __sparc64_lookup_dentry(const char *name, int lookup_flags)
                return NULL;
        }
 
-       base = lookup_dentry (emul, dget (current->fs->root), (LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_SLASHOK));
+       base = lookup_dentry (emul, 
+                             dget (current->fs->root), 
+                             (LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_SLASHOK));
                        
        if (IS_ERR (base)) return NULL;
        
index ba204ce26095ade3163fdf8cdb8c8d98d4709ecf..d1d319bab5ad3eaba25341043462f4c6e82254de 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.95 1998/10/22 03:05:57 davem Exp $
+/* $Id: pgtable.h,v 1.96 1998/10/27 23:28:42 davem Exp $
  * pgtable.h: SpitFire page table operations.
  *
  * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -602,7 +602,12 @@ extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
 { pte_t pte; pte_val(pte) = (type<<PAGE_SHIFT)|(offset<<(PAGE_SHIFT+8)); return pte; }
 
 extern inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space)
-{ pte_t pte; pte_val(pte) = ((page) | pgprot_val(prot) | _PAGE_E) & ~(unsigned long)_PAGE_CACHE; return pte; }
+{
+       pte_t pte;
+       pte_val(pte) = ((page) | pgprot_val(prot) | _PAGE_E) & ~(unsigned long)_PAGE_CACHE;
+       pte_val(pte) |= (((unsigned long)space) << 32);
+       return pte;
+}
 
 #define SWP_TYPE(entry)                (((entry>>PAGE_SHIFT) & 0xff))
 #define SWP_OFFSET(entry)      ((entry) >> (PAGE_SHIFT+8))
index 5c0133d9817b81ef1eced9a8a6e9abc0a3778e2e..5f65fc78f7da4314cf0a5beca458b28cc3bb6db7 100644 (file)
@@ -34,8 +34,8 @@ typedef unsigned char spinlock_t;
  * irq-safe write-lock, but readers can get non-irqsafe
  * read-locks.
  */
-typedef struct { } rwlock_t;
-#define RW_LOCK_UNLOCKED { }
+typedef unsigned long rwlock_t;
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 
 #define read_lock(lock)                do { } while(0)
 #define read_unlock(lock)      do { } while(0)
@@ -186,7 +186,7 @@ typedef struct {
        unsigned char lock;
        unsigned int owner_pc, owner_cpu;
 } spinlock_t;
-#define SPIN_LOCK_UNLOCKED { 0, 0, NO_PROC_ID }
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 0, NO_PROC_ID }
 #define spin_lock_init(__lock) \
 do {   (__lock)->lock = 0; \
        (__lock)->owner_pc = 0; \
@@ -322,7 +322,7 @@ typedef struct {
        unsigned int writer_pc, writer_cpu;
        unsigned int reader_pc[4];
 } rwlock_t;
-#define RW_LOCK_UNLOCKED       { 0, 0, NO_PROC_ID, { 0, 0, 0, 0 } }
+#define RW_LOCK_UNLOCKED       (rwlock_t) { 0, 0, NO_PROC_ID, { 0, 0, 0, 0 } }
 
 extern void _do_read_lock(rwlock_t *rw, char *str);
 extern void _do_read_unlock(rwlock_t *rw, char *str);
index 2b25d2902cb738d8f7124fae658e73a7bc778698..9a0ddd6c4e4416e4fd28adba50786c07a0178e85 100644 (file)
 
 #define AUTOFS_PROTO_VERSION 3
 
+/*
+ * Architectures where both 32- and 64-bit binaries can be executed
+ * on 64-bit kernels need this.  This keeps the structure format
+ * uniform, and makes sure the wait_queue_token isn't too big to be
+ * passed back down to the kernel.
+ *
+ * This assumes that on these architectures:
+ * mode     32 bit    64 bit
+ * -------------------------
+ * int      32 bit    32 bit
+ * long     32 bit    64 bit
+ *
+ * If so, 32-bit user-space code should be backwards compatible.
+ */
+
+#if defined(__sparc__) || defined(__mips__)
+typedef unsigned int autofs_wqt_t;
+#else
+typedef unsigned long autofs_wqt_t;
+#endif
+
 enum autofs_packet_type {
        autofs_ptype_missing,   /* Missing entry (mount request) */
        autofs_ptype_expire,    /* Expire entry (umount request) */
@@ -34,7 +55,7 @@ struct autofs_packet_hdr {
 
 struct autofs_packet_missing {
        struct autofs_packet_hdr hdr;
-        unsigned long wait_queue_token;
+        autofs_wqt_t wait_queue_token;
        int len;
        char name[NAME_MAX+1];
 };     
index 15656ff08ca3df9e909696a49fac352d4c8b98e5..b5b4e73931378795b94d13087de862d1543916d6 100644 (file)
@@ -117,7 +117,7 @@ struct lp_stats {
 
 struct lp_struct {
        struct pardevice *dev;
-       int flags;
+       unsigned long flags;
        unsigned int chars;
        unsigned int time;
        unsigned int wait;
index 658663577ed48e6276b401d5c61d48f3f56c91a1..dd3a4e436d7feffb2f9b2774b0f72a5b34fbdb0c 100644 (file)
@@ -351,6 +351,7 @@ extern int stli_init(void);
 extern int riscom8_init(void);
 extern int specialix_init(void);
 extern int espserial_init(void);
+extern int macserial_init(void);
 
 extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
                              const char *routine);
index 5ec3967a354f4a104a0bf8f8b1176b6374e011c0..c76cf34eabd87d7283c8b50116681befa39ee397 100644 (file)
@@ -838,7 +838,7 @@ static struct kernel_param cooked_params[] __initdata = {
 #ifdef CONFIG_MD_BOOT
        { "md=", md_setup},
 #endif
-#ifdef CONFIG_MACMOUSE
+#ifdef CONFIG_ADBMOUSE
        { "adb_buttons=", adb_mouse_setup },
 #endif
 #ifdef CONFIG_LTPC
@@ -1246,7 +1246,7 @@ static void __init do_basic_setup(void)
 #ifdef CONFIG_SBUS
        sbus_init();
 #endif
-#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+#if defined(CONFIG_PPC)
        powermac_init();
 #endif
 #ifdef CONFIG_MCA
index c64eefbd2ed3c7ae0618646b46f17ed149590559..eb548f6c552d766b030ace700c66342c50df2395 100644 (file)
@@ -9,7 +9,7 @@
 
 O_TARGET := mm.o
 O_OBJS  := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
-           vmalloc.o slab.o \
+           vmalloc.o slab.o mrecow.o \
            swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o
 
 include $(TOPDIR)/Rules.make
index df82a952418d8d2bbe2ddb213d6b49393dd0cd17..54ed51b988ab4f22a8969a834742003c9f6ea3da 100644 (file)
@@ -176,9 +176,6 @@ static inline int shrink_one_page(struct page *page, int gfp_mask)
                                touch_page(page);
                                break;
                        }
-                       age_page(page);
-                       if (page->age)
-                               break;
                        if (pgcache_under_min())
                                break;
                        remove_inode_page(page);
diff --git a/mm/mrecow.c b/mm/mrecow.c
new file mode 100644 (file)
index 0000000..16e239c
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ *     linux/mm/recow.c
+ *
+ * Copyright (C) 1998 Linus Torvalds
+ */
+
+#include <linux/mm.h>
+#include <linux/smp_lock.h>
+
+#include <asm/pgtable.h>
+
+/*
+ * This implements the "re-COW" system call.
+ *
+ * "re-cow" - synchronize two page-aligned areas with each other,
+ * returning the first offset at which they differ. This is useful
+ * for doing large memory compares. One example is simulating a
+ * VGA device under DOSEMU, where you cache the old state of the
+ * screen, and let DOSEMU have a private copy that it can change.
+ *
+ * When you want to synchronize the real screen with the private
+ * simulation, you "re-cow()" the areas and see where the changes
+ * have been. It will not only tell you what pages have been modified,
+ * it will also share pages if they are the same..
+ *
+ * Doing this in user mode is prohibitive, as we need to access
+ * the page tables in order to do this efficiently.
+ */
+
+#define verify_recow(mm, vma, addr, len) do { \
+       vma = find_vma(mm, addr); \
+       if (!vma || (vma->vm_flags & VM_SHARED) || addr < vma->vm_start || vma->vm_end - addr < len) \
+               goto badvma; \
+} while (0)
+
+static int do_compare(struct mm_struct *mm, pte_t * firstpte, unsigned long addr)
+{
+       pgd_t * pgd;
+
+       pgd = pgd_offset(mm, addr);
+       if (!pgd_none(*pgd)) {
+               pmd_t * pmd = pmd_offset(pgd, addr);
+               if (!pmd_none(*pmd)) {
+                       pte_t * pte = pte_offset(pmd, addr);
+                       pte_t entry = *pte;
+                       if (pte_present(entry)) {
+                               unsigned long page1 = pte_page(*firstpte);
+                               unsigned long page2 = pte_page(entry);
+
+                               if (page1 == page2)
+                                       return 1;
+
+                               if (!memcmp((void *) page1, (void *) page2, PAGE_SIZE)) {
+                                       entry = pte_wrprotect(entry);
+                                       *firstpte = entry;
+                                       *pte = entry;
+                                       atomic_inc(&mem_map[MAP_NR(page2)].count);
+                                       free_page(page1);
+                                       return 2;
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+/*
+ * NOTE! We return zero for all "special" cases, 
+ * so that if something is not present for any
+ * reason the user has to compare that by hand.
+ */
+static int same_page(struct mm_struct *mm, unsigned long addr1, unsigned long addr2)
+{
+       pgd_t * pgd;
+
+       pgd = pgd_offset(mm, addr1);
+       if (!pgd_none(*pgd)) {
+               pmd_t * pmd = pmd_offset(pgd, addr1);
+               if (!pmd_none(*pmd)) {
+                       pte_t * pte = pte_offset(pmd, addr1);
+                       if (pte_present(*pte))
+                               return do_compare(mm, pte, addr2);
+               }
+       }
+       return 0;
+}
+
+asmlinkage long sys_mrecow(unsigned long addr1, unsigned long addr2, size_t len)
+{
+       int shared = 0;
+       long retval;
+       struct mm_struct *mm = current->mm;
+       struct vm_area_struct *vma1, *vma2;
+
+       /*
+        * Everything has to be page-aligned..
+        */
+       if ((addr1 | addr2 | len) & ~PAGE_MASK)
+               return -EINVAL;
+
+       /* Make sure we're not aliased (trivially the same for the whole length) */
+       if (addr1 == addr2)
+               return len;
+
+       down(&mm->mmap_sem);
+
+       /*
+        * We require that the comparison areas are fully contained
+        * within the vm_area_structs, and that they are both private
+        * mappings..
+        */
+       retval = -EFAULT;
+       verify_recow(mm, vma1, addr1, len);
+       verify_recow(mm, vma2, addr2, len);
+
+       /*
+        * We need to have the same page protections on both
+        * areas, otherwise we'll mess up when we combine pages.
+        *
+        * Right now we also only allow this on anonymous areas,
+        * I don't know if we'd want to expand it to other things
+        * at some point.
+        */
+       retval = -EINVAL;
+       if (pgprot_val(vma1->vm_page_prot) != pgprot_val(vma2->vm_page_prot))
+               goto badvma;
+       if (vma1->vm_file || vma2->vm_file)
+               goto badvma;
+
+       /*
+        * Ok, start the page walk..
+        */
+       lock_kernel();
+       retval = 0;
+       while (len) {
+               int same = same_page(mm, addr1, addr2);
+               if (!same)
+                       break;
+
+               shared |= same;
+               len -= PAGE_SIZE;
+               retval += PAGE_SIZE;
+               addr1 += PAGE_SIZE;
+               addr2 += PAGE_SIZE;
+       }
+       unlock_kernel();
+       if (shared)
+               flush_tlb_mm(mm);
+
+badvma:
+       up(&mm->mmap_sem);
+       return retval;
+}
+
+
index e9f308479347396ca31c5f895fe2e11dc11dfe2f..1b9f5eb0d12ad927de1f8fca184badf9d3e68538 100644 (file)
@@ -636,7 +636,7 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
                p->max         = swap_header->info.last_page;
 
                if (p->max >= 0x7fffffffL/PAGE_SIZE ||
-                   (void *) &swap_header->info.badpages[swap_header->info.nr_badpages-1] >= (void *) swap_header->magic.magic) {
+                   (void *) &swap_header->info.badpages[(int) swap_header->info.nr_badpages-1] >= (void *) swap_header->magic.magic) {
                        error = -EINVAL;
                        goto bad_swap;
                }
index 32fc3d9a85436a42bc7f64c8ae55ec0d799b3b89..9927a6484caf684b402bf6c9f0b0f991748ddc28 100644 (file)
@@ -538,7 +538,7 @@ int kswapd(void *unused)
                do {
                        if (!do_try_to_free_page(0))
                                break;
-                       if (nr_free_pages > 2*freepages.high)
+                       if (nr_free_pages > freepages.high + SWAP_CLUSTER_MAX)
                                break;
                } while (time_before_eq(jiffies,end_time));
        }
@@ -621,8 +621,6 @@ void swap_tick(void)
                 * priority.
                 */
                want_wakeup = 0;
-               if (buffer_over_max() || pgcache_over_max())
-                       want_wakeup = 1;
                pages = nr_free_pages;
                if (pages < freepages.high)
                        want_wakeup = 1;
index f9a4f24fcf4f37b75f4c49f440c8c43be78801e9..54a4578caccdaf20ebdb1f9573aa7219ac6a7da4 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             PF_INET protocol family socket handler.
  *
- * Version:    $Id: af_inet.c,v 1.79 1998/10/04 06:51:08 davem Exp $
+ * Version:    $Id: af_inet.c,v 1.80 1998/11/08 11:17:03 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
index 06b173549b5a8c9ddfd2a7db28937a89fb3863ef..fc6b1f2ee7f6be164b46f77b9176bd34be904a0a 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             RAW - implementation of IP "raw" sockets.
  *
- * Version:    $Id: raw.c,v 1.38 1998/10/03 09:37:45 davem Exp $
+ * Version:    $Id: raw.c,v 1.39 1998/11/08 11:17:04 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
index cfc606d761e95c63d71c9d4bd0a1503a9f296634..b6f1c7a93a958a03990e7970a772ea05329fb4c9 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp.c,v 1.130 1998/11/07 14:36:10 davem Exp $
+ * Version:    $Id: tcp.c,v 1.132 1998/11/08 13:21:14 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -541,17 +541,8 @@ static unsigned int tcp_listen_poll(struct sock *sk, poll_table *wait)
 /*
  *     Compute minimal free write space needed to queue new packets. 
  */
-static inline int tcp_min_write_space(struct sock *sk, struct tcp_opt *tp)
-{
-       int space;
-#if 1 /* This needs benchmarking and real world tests */
-       space = max(tp->mss_cache + 128, MIN_WRITE_SPACE);
-#else /* 2.0 way */
-       /* More than half of the socket queue free? */
-       space = atomic_read(&sk->wmem_alloc) / 2;
-#endif
-       return space;
-}
+#define tcp_min_write_space(__sk) \
+       (atomic_read(&(__sk)->wmem_alloc) / 2)
 
 /*
  *     Wait for a TCP event.
@@ -599,7 +590,7 @@ unsigned int tcp_poll(struct file * file, struct socket *sock, poll_table *wait)
                        mask |= POLLIN | POLLRDNORM;
 
                if (!(sk->shutdown & SEND_SHUTDOWN)) {
-                       if (sock_wspace(sk) >= tcp_min_write_space(sk, tp)) {
+                       if (sock_wspace(sk) >= tcp_min_write_space(sk)) {
                                mask |= POLLOUT | POLLWRNORM;
                        } else {  /* send SIGIO later */
                                sk->socket->flags |= SO_NOSPACE;
@@ -623,7 +614,7 @@ void tcp_write_space(struct sock *sk)
 
        wake_up_interruptible(sk->sleep);
        if (sock_wspace(sk) >=
-           tcp_min_write_space(sk, &(sk->tp_pinfo.af_tcp)))
+           tcp_min_write_space(sk))
                sock_wake_async(sk->socket, 2);
 }
 
index cfa0f74b7670bdbc9d4b7f717b40d3893d9683ac..fb11d17306f4e2459b3c2073fd5100fab5e682d1 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_input.c,v 1.136 1998/11/07 14:36:18 davem Exp $
+ * Version:    $Id: tcp_input.c,v 1.140 1998/11/12 06:45:15 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -262,7 +262,7 @@ extern __inline__ int tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq)
 }
 
 /* When we get a reset we do this. */
-static void tcp_reset(struct sock *sk, struct sk_buff *skb)
+static void tcp_reset(struct sock *sk)
 {
        sk->zapped = 1;
 
@@ -277,7 +277,7 @@ static void tcp_reset(struct sock *sk, struct sk_buff *skb)
                default:
                        sk->err = ECONNRESET;
        };
-       tcp_set_state(sk,TCP_CLOSE);
+       tcp_set_state(sk, TCP_CLOSE);
        sk->shutdown = SHUTDOWN_MASK;
        if (!sk->dead) 
                sk->state_change(sk);
@@ -483,33 +483,36 @@ static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup)
                if (tp->high_seq == 0 || after(ack, tp->high_seq)) {
                        tp->dup_acks++;
                        if ((tp->fackets_out > 3) || (tp->dup_acks == 3)) {
-                                tp->snd_ssthresh = max(tp->snd_cwnd >> 1, 2);
+                                tp->snd_ssthresh =
+                                       max(min(tp->snd_wnd, tp->snd_cwnd) >> 1, 2);
                                 tp->snd_cwnd = (tp->snd_ssthresh + 3);
                                tp->high_seq = tp->snd_nxt;
                                if(!tp->fackets_out)
-                                       tcp_retransmit_skb(sk, skb_peek(&sk->write_queue));
+                                       tcp_retransmit_skb(sk,
+                                                          skb_peek(&sk->write_queue));
                                else
                                        tcp_fack_retransmit(sk);
                                 tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
                        }
-               }
-
-                /* 2. Each time another duplicate ACK arrives, increment 
-                 * cwnd by the segment size. [...] Transmit a packet...
-                 *
-                 * Packet transmission will be done on normal flow processing
-                 * since we're not in "retransmit mode".  We do not use duplicate
-                * ACKs to artificially inflate the congestion window when
-                * doing FACK.
-                 */
-                if (tp->dup_acks > 3) {
+               } else if (++tp->dup_acks > 3) {
+                       /* 2. Each time another duplicate ACK arrives, increment 
+                        * cwnd by the segment size. [...] Transmit a packet...
+                        *
+                        * Packet transmission will be done on normal flow processing
+                        * since we're not in "retransmit mode".  We do not use
+                        * duplicate ACKs to artificially inflate the congestion
+                        * window when doing FACK.
+                        */
                        if(!tp->fackets_out) {
                                tp->snd_cwnd++;
                        } else {
-                               /* Fill any further holes which may have appeared.
-                                * We may want to change this to run every further
-                                * multiple-of-3 dup ack increments, to be more robust
-                                * against out-of-order packet delivery.  -DaveM
+                               /* Fill any further holes which may have
+                                * appeared.
+                                *
+                                * We may want to change this to run every
+                                * further multiple-of-3 dup ack increments,
+                                * to be more robust against out-of-order
+                                * packet delivery.  -DaveM
                                 */
                                tcp_fack_retransmit(sk);
                        }
@@ -552,7 +555,8 @@ static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup)
                                 * from snd_una is if this was a window update.
                                 */
                                if (ack != tp->snd_una && before(ack, tp->high_seq)) {
-                                       tcp_retransmit_skb(sk, skb_peek(&sk->write_queue));
+                                       tcp_retransmit_skb(sk,
+                                                          skb_peek(&sk->write_queue));
                                        tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
                                }
                        } else {
@@ -568,7 +572,7 @@ static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup)
 /* This is Jacobson's slow start and congestion avoidance. 
  * SIGCOMM '88, p. 328.
  */
-static void tcp_cong_avoid(struct tcp_opt *tp)
+static __inline__ void tcp_cong_avoid(struct tcp_opt *tp)
 {
         if (tp->snd_cwnd <= tp->snd_ssthresh) {
                 /* In "safe" area, increase. */
@@ -656,6 +660,33 @@ static void tcp_ack_probe(struct sock *sk, __u32 ack)
        }
 }
  
+/* Should we open up the congestion window? */
+static __inline__ int should_advance_cwnd(struct tcp_opt *tp, int flag)
+{
+       /* Data must have been acked. */
+       if ((flag & FLAG_DATA_ACKED) == 0)
+               return 0;
+
+       /* Some of the data acked was retransmitted somehow? */
+       if ((flag & FLAG_RETRANS_DATA_ACKED) != 0) {
+               /* We advance in all cases except during
+                * non-FACK fast retransmit/recovery.
+                */
+               if (tp->fackets_out != 0 ||
+                   tp->retransmits != 0)
+                       return 1;
+
+               /* Non-FACK fast retransmit does it's own
+                * congestion window management, don't get
+                * in the way.
+                */
+               return 0;
+       }
+
+       /* New non-retransmitted data acked, always advance.  */
+       return 1;
+}
+
 /* Read draft-ietf-tcplw-high-performance before mucking
  * with this code. (Superceeds RFC1323)
  */
@@ -691,8 +722,10 @@ static void tcp_ack_saw_tstamp(struct sock *sk, struct tcp_opt *tp,
                }
        } else {
                tcp_set_rto(tp);
-               tcp_cong_avoid(tp);
        }
+       if (should_advance_cwnd(tp, flag))
+               tcp_cong_avoid(tp);
+
        /* NOTE: safe here so long as cong_ctl doesn't use rto */
        tcp_bound_rto(tp);
 }
@@ -810,9 +843,10 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th,
                                        tcp_set_rto(tp);
                                        tcp_bound_rto(tp);
                                }
-                               tcp_cong_avoid(tp);
                        }
                }
+               if (should_advance_cwnd(tp, flag))
+                       tcp_cong_avoid(tp);
        }
 
        if (tp->packets_out) {
@@ -1814,12 +1848,12 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
        if(th->syn && TCP_SKB_CB(skb)->seq != tp->syn_seq) {
                SOCK_DEBUG(sk, "syn in established state\n");
                tcp_statistics.TcpInErrs++;
-               tcp_reset(sk, skb);
+               tcp_reset(sk);
                return 1;
        }
        
        if(th->rst) {
-               tcp_reset(sk,skb);
+               tcp_reset(sk);
                goto discard;
        }
 
@@ -1998,7 +2032,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                        }
 
                        if(th->rst) {
-                               tcp_reset(sk,skb);
+                               tcp_reset(sk);
                                goto discard;
                        }
 
@@ -2127,7 +2161,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
 
        /* step 2: check RST bit */
        if(th->rst) {
-               tcp_reset(sk,skb);
+               tcp_reset(sk);
                goto discard;
        }
 
@@ -2150,7 +2184,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
         */
 
        if (th->syn && TCP_SKB_CB(skb)->seq != tp->syn_seq) {
-               tcp_reset(sk, skb);
+               tcp_reset(sk);
                return 1;
        }
 
@@ -2230,7 +2264,7 @@ step6:
                 */
                if ((sk->shutdown & RCV_SHUTDOWN) && sk->dead) {
                        if (after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) {
-                               tcp_reset(sk, skb);
+                               tcp_reset(sk);
                                return 1;
                        }
                }
index 596c72eeeeb71fdb7884aee315afdb9e9a4f40f7..25695f05d627722b59fb668d0ca350a534bcbc9a 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_output.c,v 1.96 1998/11/07 10:54:40 davem Exp $
+ * Version:    $Id: tcp_output.c,v 1.97 1998/11/08 13:21:27 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -729,9 +729,9 @@ void tcp_send_active_reset(struct sock *sk)
        struct sk_buff *skb;
 
        /* NOTE: No TCP options attached and we never retransmit this. */
-       do {
-               skb = alloc_skb(MAX_HEADER + sk->prot->max_header, GFP_KERNEL);
-       } while(skb == NULL);
+       skb = alloc_skb(MAX_HEADER + sk->prot->max_header, GFP_KERNEL);
+       if (!skb)
+               return;
 
        /* Reserve space for headers and prepare control bits. */
        skb_reserve(skb, MAX_HEADER + sk->prot->max_header);
index 01ccf331e3b5b24f5e08c74214867f6c0da4ab50..113b06ef80c02d59836ddee8ff7ea135ab278c4f 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             The User Datagram Protocol (UDP).
  *
- * Version:    $Id: udp.c,v 1.63 1998/10/03 09:38:16 davem Exp $
+ * Version:    $Id: udp.c,v 1.64 1998/11/08 11:17:07 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
index a47d10e82fe8ea1b53766f641f6961e664662545..3b02e06d9b7794f8da852d47e18cd820c93acc34 100644 (file)
@@ -7,7 +7,7 @@
  *
  *     Adapted from linux/net/ipv4/raw.c
  *
- *     $Id: raw.c,v 1.22 1998/10/03 09:38:40 davem Exp $
+ *     $Id: raw.c,v 1.23 1998/11/08 11:17:09 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -597,7 +597,7 @@ static int rawv6_getsockopt(struct sock *sk, int level, int optname,
 }
 
 
-static void rawv6_close(struct sock *sk, unsigned long timeout)
+static void rawv6_close(struct sock *sk, long timeout)
 {
        /* See for explanation: raw_close in ipv4/raw.c */
        sk->state = TCP_CLOSE;
index 3540f05952f91ead0afeb3096b5c65fdb3ab6755..0670e875815836fe3c40bd0598ddcb478a1c4849 100644 (file)
@@ -7,7 +7,7 @@
  *
  *     Based on linux/ipv4/udp.c
  *
- *     $Id: udp.c,v 1.36 1998/10/03 09:38:54 davem Exp $
+ *     $Id: udp.c,v 1.37 1998/11/08 11:17:10 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -308,7 +308,7 @@ ipv4_connected:
        return(0);
 }
 
-static void udpv6_close(struct sock *sk, unsigned long timeout)
+static void udpv6_close(struct sock *sk, long timeout)
 {
        /* See for explanation: raw_close in ipv4/raw.c */
        sk->state = TCP_CLOSE;