- pre22.4.0-test8pre2
authorLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:38:25 +0000 (23 15:38 -0500)
committerLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:38:25 +0000 (23 15:38 -0500)
    - The TCP socket leak patch _really_ went in this time.
    - get rid of more suser() checks in networking.. It's "capable(CAP_NET_ADMIN)".
    - sparc updates
    - alpha updates. Fast alpha xor for raid. AP1000 updates.
    - Wonders never cease. digiboard driver updates. Christoph Lameter is BAAACK!
    - SiS frame buffer driver updates. Can be used without a BIOS.
    - nfsd interface cleanup.
    - fix potential buffer overruns in get_partition_list.  Remove
      limitation of one page.
    - floppy driver capability cleanups. Use "request_region()".
    - handle dcache flushing when there are shared user mappings that
      may be dirty.
    - get rid of the "xxxx_ret()" user access macros. They are more complex than
      just doing the return directly and they hide what's going on.
    - fix up broken BIOSes that don't give unique ID's to different APICs
    - make more of the drm drivers compile on other platforms and know
      about the signal blocking issues.
    - net/atm/mpoa_proc.c: user-space access thinko
    - pcmcia: David Hinds: merge updates from 3.1.20
    - pcmcia: non-ISA machines really shouldn't use ISA interrupts ;)
    - ext2: truncate races and error code return fixes
    - true shared signals for pthreads..

201 files changed:
Documentation/digiboard.txt
MAINTAINERS
arch/alpha/Makefile
arch/alpha/kernel/core_cia.c
arch/alpha/kernel/core_irongate.c
arch/i386/defconfig
arch/i386/kernel/i387.c
arch/i386/kernel/io_apic.c
arch/i386/kernel/signal.c
arch/sparc/kernel/irq.c
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/mm/srmmu.c
arch/sparc/mm/sun4c.c
arch/sparc/prom/console.c
arch/sparc/prom/devmap.c
arch/sparc/prom/devops.c
arch/sparc/prom/misc.c
arch/sparc/prom/mp.c
arch/sparc/prom/segment.c
arch/sparc/prom/tree.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/solaris/fs.c
arch/sparc64/solaris/misc.c
arch/sparc64/solaris/signal.c
drivers/block/floppy.c
drivers/block/xor.c
drivers/cdrom/cdrom.c
drivers/char/drm/agpsupport.c
drivers/char/drm/auth.c
drivers/char/drm/bufs.c
drivers/char/drm/context.c
drivers/char/drm/dma.c
drivers/char/drm/drawable.c
drivers/char/drm/drmP.h
drivers/char/drm/ffb_context.c
drivers/char/drm/fops.c
drivers/char/drm/gamma_dma.c
drivers/char/drm/gamma_drv.c
drivers/char/drm/i810_bufs.c
drivers/char/drm/i810_context.c
drivers/char/drm/i810_dma.c
drivers/char/drm/i810_drv.c
drivers/char/drm/ioctl.c
drivers/char/drm/lock.c
drivers/char/drm/mga_bufs.c
drivers/char/drm/mga_context.c
drivers/char/drm/mga_dma.c
drivers/char/drm/mga_drv.c
drivers/char/drm/mga_drv.h
drivers/char/drm/mga_state.c
drivers/char/drm/r128_bufs.c
drivers/char/drm/r128_context.c
drivers/char/drm/r128_dma.c
drivers/char/drm/r128_drv.c
drivers/char/drm/tdfx_context.c
drivers/char/drm/tdfx_drv.c
drivers/char/pcmcia/serial_cb.c
drivers/char/pcmcia/serial_cs.c
drivers/char/pcxx.c
drivers/i2c/i2c-dev.c
drivers/media/video/zr36120.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/3c589_cs.c
drivers/net/pcmcia/netwave_cs.c
drivers/net/pcmcia/nmclan_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcmcia/ray_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/pcmcia/xirc2ps_cs.c
drivers/net/wan/cosa.c
drivers/pcmcia/bulkmem.c
drivers/pcmcia/cardbus.c
drivers/pcmcia/cb_enabler.c
drivers/pcmcia/cistpl.c
drivers/pcmcia/cs.c
drivers/pcmcia/cs_internal.h
drivers/pcmcia/ds.c
drivers/pcmcia/rsrc_mgr.c
drivers/pcmcia/rsrc_mgr.h
drivers/pnp/isapnp.c
drivers/sbus/char/bpp.c
drivers/sbus/char/display7seg.c
drivers/sbus/char/openprom.c
drivers/sbus/char/rtc.c
drivers/sbus/char/sunkbd.c
drivers/sbus/char/sunmouse.c
drivers/sbus/char/zs.c
drivers/scsi/esp.c
drivers/scsi/ips.h
drivers/scsi/pcmcia/aha152x_stub.c
drivers/scsi/pcmcia/apa1480_stub.c
drivers/scsi/pcmcia/fdomain_stub.c
drivers/scsi/pcmcia/qlogic_stub.c
drivers/sgi/char/graphics.c
drivers/sgi/char/rrm.c
drivers/sound/ac97_codec.c
drivers/sound/cmpci.c
drivers/sound/cs46xx.c
drivers/sound/dmasound/dmasound_core.c
drivers/sound/emu10k1/audio.c
drivers/sound/emu10k1/mixer.c
drivers/sound/es1370.c
drivers/sound/es1371.c
drivers/sound/esssolo1.c
drivers/sound/i810_audio.c
drivers/sound/maestro.c
drivers/sound/nm256_audio.c
drivers/sound/sonicvibes.c
drivers/sound/trident.c
drivers/sound/via82cxxx_audio.c
drivers/sound/vwsnd.c
drivers/sound/waveartist.c
drivers/usb/audio.c
drivers/usb/devio.c
drivers/usb/rio500.c
drivers/video/atyfb.c
drivers/video/cgfourteenfb.c
drivers/video/matrox/matroxfb_base.c
drivers/video/matrox/matroxfb_crtc2.c
drivers/video/sbusfb.c
drivers/video/sisfb.c
fs/Makefile
fs/autofs/waitq.c
fs/autofs4/waitq.c
fs/binfmt_elf.c
fs/buffer.c
fs/exec.c
fs/ext2/Makefile
fs/ext2/ialloc.c
fs/ext2/inode.c
fs/ext2/namei.c
fs/ext2/truncate.c[deleted file]
fs/filesystems.c
fs/locks.c
fs/ncpfs/ioctl.c
fs/nfsd/nfsctl.c
fs/nfsd/nfssvc.c
fs/nfsd/vfs.c
fs/partitions/check.c
fs/proc/array.c
fs/proc/proc_misc.c
include/asm-alpha/bitops.h
include/asm-alpha/core_irongate.h
include/asm-alpha/uaccess.h
include/asm-arm/uaccess.h
include/asm-i386/uaccess.h
include/asm-ia64/uaccess.h
include/asm-m68k/uaccess.h
include/asm-mips/uaccess.h
include/asm-mips64/uaccess.h
include/asm-ppc/uaccess.h
include/asm-s390/uaccess.h
include/asm-sh/uaccess.h
include/asm-sparc/hardirq.h
include/asm-sparc/irq.h
include/asm-sparc/oplib.h
include/asm-sparc/uaccess.h
include/asm-sparc64/uaccess.h
include/linux/fs.h
include/linux/mm.h
include/linux/nfsd/interface.h[new file with mode: 0644]
include/linux/nfsd/nfsd.h
include/linux/pci_ids.h
include/linux/sched.h
include/linux/signal.h
include/pcmcia/bulkmem.h
include/pcmcia/bus_ops.h
include/pcmcia/ciscode.h
include/pcmcia/cisreg.h
include/pcmcia/cistpl.h
include/pcmcia/cs.h
include/pcmcia/cs_types.h
include/pcmcia/driver_ops.h
include/pcmcia/ds.h
include/pcmcia/ftl.h
include/pcmcia/mem_op.h
include/pcmcia/memory.h
include/pcmcia/ss.h
include/pcmcia/version.h
init/main.c
kernel/exit.c
kernel/fork.c
kernel/ksyms.c
kernel/sched.c
kernel/signal.c
mm/filemap.c
mm/memory.c
mm/mmap.c
mm/vmscan.c
net/atm/mpoa_proc.c
net/ax25/af_ax25.c
net/ax25/ax25_route.c
net/ax25/ax25_uid.c
net/decnet/af_decnet.c
net/econet/af_econet.c
net/ipv4/tcp_minisocks.c
net/netrom/af_netrom.c
net/packet/af_packet.c
net/rose/af_rose.c
net/x25/af_x25.c

index b25fc15..6a2da7f 100644 (file)
@@ -8,11+8,6 @@ The Digiboard Driver for Linux supports the following boards:
  switches) You can use up to 4 cards with this driver and it should work
  on other architectures than intel also.
 
-In case you have problems with this version (1.6.1) of this driver, please
-email directly to me as I made the last update. It you have a report about
-running it on other architectures than intel, email me, so I can document
-it here.
-
 A version of this driver has been taken by Digiboard to make a driver
 software package which supports also PC/Xem cards and newer PCI cards
 but it doesn't support the old PC/Xi cards and it isn't yet ported to
@@ -154,22+149,12 @@ Sources of Information
 ----------------------
 
 Please contact digi directly digilnux@dgii.com. Forward any information of
-general interest to me.
+general interest to me so that I can include it on the webpage.
 
-Web page (mainly of historical interest): http://lameter.com/digi
+Web page: http://lameter.com/digi
 
 Christoph Lameter (christoph@lameter.com) Aug 14, 2000.
 
-Supporting Tools
-----------------
-
-Some (old) tools and more detailed information can be found at
-ftp://lameter.com/digi
-
-The "ditty" tool described in the Digiboard Manuals for other Unixes
-is also available.
-
-
 Device file creation
 --------------------
 
index 65cf9b3..1a4cc0d 100644 (file)
@@ -655,10+655,12 @@ L:        autofs@linux.kernel.org
 S:     Maintained
 
 KERNEL NFSD
-P:     G. Allen Morris III
-M:     gam3@acm.org
+P:     Neil Brown
+M:     neilb@cse.unsw.edu.au
 L:     nfs-devel@linux.kernel.org (Linux NFS)
-W:     http://csua.berkeley.edu/~gam3/knfsd
+L:     nfs@lists.sourceforge.net
+W:     http://nfs.sourceforge.net/
+W:     http://www.cse.unsw.edu.au/~neilb/oss/knfsd/
 S:     Maintained
 
 LANMEDIA WAN CARD DRIVER
@@ -894,7+896,7 @@ PCMCIA SUBSYSTEM
 P:     David Hinds
 M:     dhinds@zen.stanford.edu
 L:     linux-kernel@vger.kernel.org
-W:     http://pcmcia.sourceforge.org
+W:     http://pcmcia-cs.sourceforge.net
 S:     Maintained
 
 PCNET32 NETWORK DRIVER
index 3daa2c7..4f6c6b6 100644 (file)
@@ -23,6+23,8 @@ have_mcpu_pca56 := $(shell if $(CC) -mcpu=pca56 -S -o /dev/null -xc /dev/null >
 
 have_mcpu_ev6 := $(shell if $(CC) -mcpu=ev6 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
 
+have_mcpu_ev67 := $(shell if $(CC) -mcpu=ev67 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
+
 # Turn on the proper cpu optimizations.
 ifeq ($(have_mcpu),y)
   # If GENERIC, make sure to turn off any instruction set extensions that
index 5aa0025..c686fd2 100644 (file)
@@ -754,6+754,364 @@ cia_pci_clr_err(void)
        *(vip)CIA_IOC_CIA_ERR;          /* re-read to force write.  */
 }
 
+static void
+cia_decode_pci_error(struct el_CIA_sysdata_mcheck *cia, const char *msg)
+{
+       static const char * const pci_cmd_desc[16] = {
+               "Interrupt Acknowledge", "Special Cycle", "I/O Read",
+               "I/O Write", "Reserved 0x4", "Reserved 0x5", "Memory Read",
+               "Memory Write", "Reserved 0x8", "Reserved 0x9",
+               "Configuration Read", "Configuration Write",
+               "Memory Read Multiple", "Dual Address Cycle",
+               "Memory Read Line", "Memory Write and Invalidate"
+       };
+
+       if (cia->cia_err & (CIA_ERR_COR_ERR
+                           | CIA_ERR_UN_COR_ERR
+                           | CIA_ERR_MEM_NEM
+                           | CIA_ERR_PA_PTE_INV)) {
+               static const char * const window_desc[6] = {
+                       "No window active", "Window 0 hit", "Window 1 hit",
+                       "Window 2 hit", "Window 3 hit", "Monster window hit"
+               };
+
+               const char *window;
+               const char *cmd;
+               unsigned long addr, tmp;
+               int lock, dac;
+       
+               cmd = pci_cmd_desc[cia->pci_err0 & 0x7];
+               lock = (cia->pci_err0 >> 4) & 1;
+               dac = (cia->pci_err0 >> 5) & 1;
+
+               tmp = (cia->pci_err0 >> 8) & 0x1F;
+               tmp = ffs(tmp);
+               window = window_desc[tmp];
+
+               addr = cia->pci_err1;
+               if (dac) {
+                       tmp = *(vip)CIA_IOC_PCI_W_DAC & 0xFFUL;
+                       addr |= tmp << 32;
+               }
+
+               printk(KERN_CRIT "CIA machine check: %s\n", msg);
+               printk(KERN_CRIT "  DMA command: %s\n", cmd);
+               printk(KERN_CRIT "  PCI address: %#010lx\n", addr);
+               printk(KERN_CRIT "  %s, Lock: %d, DAC: %d\n",
+                      window, lock, dac);
+       } else if (cia->cia_err & (CIA_ERR_PERR
+                                  | CIA_ERR_PCI_ADDR_PE
+                                  | CIA_ERR_RCVD_MAS_ABT
+                                  | CIA_ERR_RCVD_TAR_ABT
+                                  | CIA_ERR_IOA_TIMEOUT)) {
+               static const char * const master_st_desc[16] = {
+                       "Idle", "Drive bus", "Address step cycle",
+                       "Address cycle", "Data cycle", "Last read data cycle",
+                       "Last write data cycle", "Read stop cycle",
+                       "Write stop cycle", "Read turnaround cycle",
+                       "Write turnaround cycle", "Reserved 0xB",
+                       "Reserved 0xC", "Reserved 0xD", "Reserved 0xE",
+                       "Unknown state"
+               };
+               static const char * const target_st_desc[16] = {
+                       "Idle", "Busy", "Read data cycle", "Write data cycle",
+                       "Read stop cycle", "Write stop cycle",
+                       "Read turnaround cycle", "Write turnaround cycle",
+                       "Read wait cycle", "Write wait cycle",
+                       "Reserved 0xA", "Reserved 0xB", "Reserved 0xC",
+                       "Reserved 0xD", "Reserved 0xE", "Unknown state"
+               };
+
+               const char *cmd;
+               const char *master, *target;
+               unsigned long addr, tmp;
+               int dac;
+
+               master = master_st_desc[(cia->pci_err0 >> 16) & 0xF];
+               target = target_st_desc[(cia->pci_err0 >> 20) & 0xF];
+               cmd = pci_cmd_desc[(cia->pci_err0 >> 24) & 0xF];
+               dac = (cia->pci_err0 >> 28) & 1;
+
+               addr = cia->pci_err2;
+               if (dac) {
+                       tmp = *(volatile int *)CIA_IOC_PCI_W_DAC & 0xFFUL;
+                       addr |= tmp << 32;
+               }
+
+               printk(KERN_CRIT "CIA machine check: %s\n", msg);
+               printk(KERN_CRIT "  PCI command: %s\n", cmd);
+               printk(KERN_CRIT "  Master state: %s, Target state: %s\n",
+                      master, target);
+               printk(KERN_CRIT "  PCI address: %#010lx, DAC: %d\n",
+                      addr, dac);
+       } else {
+               printk(KERN_CRIT "CIA machine check: %s\n", msg);
+               printk(KERN_CRIT "  Unknown PCI error\n");
+               printk(KERN_CRIT "  PCI_ERR0 = %#08lx", cia->pci_err0);
+               printk(KERN_CRIT "  PCI_ERR1 = %#08lx", cia->pci_err1);
+               printk(KERN_CRIT "  PCI_ERR2 = %#08lx", cia->pci_err2);
+       }
+}
+
+static void
+cia_decode_mem_error(struct el_CIA_sysdata_mcheck *cia, const char *msg)
+{
+       unsigned long mem_port_addr;
+       unsigned long mem_port_mask;
+       const char *mem_port_cmd;
+       const char *seq_state;
+       const char *set_select;
+       unsigned long tmp;
+
+       /* If this is a DMA command, also decode the PCI bits.  */
+       if ((cia->mem_err1 >> 20) & 1)
+               cia_decode_pci_error(cia, msg);
+       else
+               printk(KERN_CRIT "CIA machine check: %s\n", msg);
+
+       mem_port_addr = cia->mem_err0 & 0xfffffff0;
+       mem_port_addr |= (cia->mem_err1 & 0x83UL) << 32;
+
+       mem_port_mask = (cia->mem_err1 >> 12) & 0xF;
+
+       tmp = (cia->mem_err1 >> 8) & 0xF;
+       tmp |= ((cia->mem_err1 >> 20) & 1) << 4;
+       if ((tmp & 0x1E) == 0x06)
+               mem_port_cmd = "WRITE BLOCK or WRITE BLOCK LOCK";
+       else if ((tmp & 0x1C) == 0x08)
+               mem_port_cmd = "READ MISS or READ MISS MODIFY";
+       else if (tmp == 0x1C)
+               mem_port_cmd = "BC VICTIM";
+       else if ((tmp & 0x1E) == 0x0E)
+               mem_port_cmd = "READ MISS MODIFY";
+       else if ((tmp & 0x1C) == 0x18)
+               mem_port_cmd = "DMA READ or DMA READ MODIFY";
+       else if ((tmp & 0x1E) == 0x12)
+               mem_port_cmd = "DMA WRITE";
+       else
+               mem_port_cmd = "Unknown";
+
+       tmp = (cia->mem_err1 >> 16) & 0xF;
+       switch (tmp) {
+       case 0x0:
+               seq_state = "Idle";
+               break;
+       case 0x1:
+               seq_state = "DMA READ or DMA WRITE";
+               break;
+       case 0x2: case 0x3:
+               seq_state = "READ MISS (or READ MISS MODIFY) with victim";
+               break;
+       case 0x4: case 0x5: case 0x6:
+               seq_state = "READ MISS (or READ MISS MODIFY) with no victim";
+               break;
+       case 0x8: case 0x9: case 0xB:
+               seq_state = "Refresh";
+               break;
+       case 0xC:
+               seq_state = "Idle, waiting for DMA pending read";
+               break;
+       case 0xE: case 0xF:
+               seq_state = "Idle, ras precharge";
+               break;
+       default:
+               seq_state = "Unknown";
+               break;
+       }
+
+       tmp = (cia->mem_err1 >> 24) & 0x1F;
+       switch (tmp) {
+       case 0x00: set_select = "Set 0 selected"; break;
+       case 0x01: set_select = "Set 1 selected"; break;
+       case 0x02: set_select = "Set 2 selected"; break;
+       case 0x03: set_select = "Set 3 selected"; break;
+       case 0x04: set_select = "Set 4 selected"; break;
+       case 0x05: set_select = "Set 5 selected"; break;
+       case 0x06: set_select = "Set 6 selected"; break;
+       case 0x07: set_select = "Set 7 selected"; break;
+       case 0x08: set_select = "Set 8 selected"; break;
+       case 0x09: set_select = "Set 9 selected"; break;
+       case 0x0A: set_select = "Set A selected"; break;
+       case 0x0B: set_select = "Set B selected"; break;
+       case 0x0C: set_select = "Set C selected"; break;
+       case 0x0D: set_select = "Set D selected"; break;
+       case 0x0E: set_select = "Set E selected"; break;
+       case 0x0F: set_select = "Set F selected"; break;
+       case 0x10: set_select = "No set selected"; break;
+       case 0x1F: set_select = "Refresh cycle"; break;
+       default:   set_select = "Unknown"; break;
+       }
+
+       printk(KERN_CRIT "  Memory port command: %s\n", mem_port_cmd);
+       printk(KERN_CRIT "  Memory port address: %#010lx, mask: %#lx\n",
+              mem_port_addr, mem_port_mask);
+       printk(KERN_CRIT "  Memory sequencer state: %s\n", seq_state);
+       printk(KERN_CRIT "  Memory set: %s\n", set_select);
+}
+
+static void
+cia_decode_ecc_error(struct el_CIA_sysdata_mcheck *cia, const char *msg)
+{
+       long syn;
+       long i;
+       const char *fmt;
+
+       cia_decode_mem_error(cia, msg);
+
+       syn = cia->cia_syn & 0xff;
+       if (syn == (syn & -syn)) {
+               fmt = KERN_CRIT "  ECC syndrome %#x -- check bit %d\n";
+               i = ffs(syn) - 1;
+       } else {
+               static unsigned char const data_bit[64] = {
+                       0xCE, 0xCB, 0xD3, 0xD5,
+                       0xD6, 0xD9, 0xDA, 0xDC,
+                       0x23, 0x25, 0x26, 0x29,
+                       0x2A, 0x2C, 0x31, 0x34,
+                       0x0E, 0x0B, 0x13, 0x15,
+                       0x16, 0x19, 0x1A, 0x1C,
+                       0xE3, 0xE5, 0xE6, 0xE9,
+                       0xEA, 0xEC, 0xF1, 0xF4,
+                       0x4F, 0x4A, 0x52, 0x54,
+                       0x57, 0x58, 0x5B, 0x5D,
+                       0xA2, 0xA4, 0xA7, 0xA8,
+                       0xAB, 0xAD, 0xB0, 0xB5,
+                       0x8F, 0x8A, 0x92, 0x94,
+                       0x97, 0x98, 0x9B, 0x9D,
+                       0x62, 0x64, 0x67, 0x68,
+                       0x6B, 0x6D, 0x70, 0x75
+               };
+
+               for (i = 0; i < 64; ++i)
+                       if (data_bit[i] == syn)
+                               break;
+
+               if (i < 64)
+                       fmt = KERN_CRIT "  ECC syndrome %#x -- data bit %d\n";
+               else
+                       fmt = KERN_CRIT "  ECC syndrome %#x -- unknown bit\n";
+       }
+
+       printk (fmt, syn, i);
+}
+
+static void
+cia_decode_parity_error(struct el_CIA_sysdata_mcheck *cia)
+{
+       static const char * const cmd_desc[16] = {
+               "NOP", "LOCK", "FETCH", "FETCH_M", "MEMORY BARRIER",
+               "SET DIRTY", "WRITE BLOCK", "WRITE BLOCK LOCK",
+               "READ MISS0", "READ MISS1", "READ MISS MOD0",
+               "READ MISS MOD1", "BCACHE VICTIM", "Spare",
+               "READ MISS MOD STC0", "READ MISS MOD STC1"
+       };
+
+       unsigned long addr;
+       unsigned long mask;
+       const char *cmd;
+       int par;
+
+       addr = cia->cpu_err0 & 0xfffffff0;
+       addr |= (cia->cpu_err1 & 0x83UL) << 32;
+       cmd = cmd_desc[(cia->cpu_err1 >> 8) & 0xF];
+       mask = (cia->cpu_err1 >> 12) & 0xF;
+       par = (cia->cpu_err1 >> 21) & 1;
+
+       printk(KERN_CRIT "CIA machine check: System bus parity error\n");
+       printk(KERN_CRIT "  Command: %s, Parity bit: %d\n", cmd, par);
+       printk(KERN_CRIT "  Address: %#010lx, Mask: %#lx\n", addr, mask);
+}
+
+static int
+cia_decode_mchk(unsigned long la_ptr)
+{
+       struct el_common *com;
+       struct el_CIA_sysdata_mcheck *cia;
+       int which;
+
+       com = (void *)la_ptr;
+       cia = (void *)(la_ptr + com->sys_offset);
+
+       if ((cia->cia_err & CIA_ERR_VALID) == 0)
+               return 0;
+
+       which = cia->cia_err & 0xfff;
+       switch (ffs(which) - 1) {
+       case 0: /* CIA_ERR_COR_ERR */
+               cia_decode_ecc_error(cia, "Corrected ECC error");
+               break;
+       case 1: /* CIA_ERR_UN_COR_ERR */
+               cia_decode_ecc_error(cia, "Uncorrected ECC error");
+               break;
+       case 2: /* CIA_ERR_CPU_PE */
+               cia_decode_parity_error(cia);
+               break;
+       case 3: /* CIA_ERR_MEM_NEM */
+               cia_decode_mem_error(cia, "Access to nonexistent memory");
+               break;
+       case 4: /* CIA_ERR_PCI_SERR */
+               cia_decode_pci_error(cia, "PCI bus system error");
+               break;
+       case 5: /* CIA_ERR_PERR */
+               cia_decode_pci_error(cia, "PCI data parity error");
+               break;
+       case 6: /* CIA_ERR_PCI_ADDR_PE */
+               cia_decode_pci_error(cia, "PCI address parity error");
+               break;
+       case 7: /* CIA_ERR_RCVD_MAS_ABT */
+               cia_decode_pci_error(cia, "PCI master abort");
+               break;
+       case 8: /* CIA_ERR_RCVD_TAR_ABT */
+               cia_decode_pci_error(cia, "PCI target abort");
+               break;
+       case 9: /* CIA_ERR_PA_PTE_INV */
+               cia_decode_pci_error(cia, "PCI invalid PTE");
+               break;
+       case 10: /* CIA_ERR_FROM_WRT_ERR */
+               cia_decode_mem_error(cia, "Write to flash ROM attempted");
+               break;
+       case 11: /* CIA_ERR_IOA_TIMEOUT */
+               cia_decode_pci_error(cia, "I/O timeout");
+               break;
+       }
+
+       if (cia->cia_err & CIA_ERR_LOST_CORR_ERR)
+               printk(KERN_CRIT "CIA lost machine check: "
+                      "Correctable ECC error\n");
+       if (cia->cia_err & CIA_ERR_LOST_UN_CORR_ERR)
+               printk(KERN_CRIT "CIA lost machine check: "
+                      "Uncorrectable ECC error\n");
+       if (cia->cia_err & CIA_ERR_LOST_CPU_PE)
+               printk(KERN_CRIT "CIA lost machine check: "
+                      "System bus parity error\n");
+       if (cia->cia_err & CIA_ERR_LOST_MEM_NEM)
+               printk(KERN_CRIT "CIA lost machine check: "
+                      "Access to nonexistent memory\n");
+       if (cia->cia_err & CIA_ERR_LOST_PERR)
+               printk(KERN_CRIT "CIA lost machine check: "
+                      "PCI data parity error\n");
+       if (cia->cia_err & CIA_ERR_LOST_PCI_ADDR_PE)
+               printk(KERN_CRIT "CIA lost machine check: "
+                      "PCI address parity error\n");
+       if (cia->cia_err & CIA_ERR_LOST_RCVD_MAS_ABT)
+               printk(KERN_CRIT "CIA lost machine check: "
+                      "PCI master abort\n");
+       if (cia->cia_err & CIA_ERR_LOST_RCVD_TAR_ABT)
+               printk(KERN_CRIT "CIA lost machine check: "
+                      "PCI target abort\n");
+       if (cia->cia_err & CIA_ERR_LOST_PA_PTE_INV)
+               printk(KERN_CRIT "CIA lost machine check: "
+                      "PCI invalid PTE\n");
+       if (cia->cia_err & CIA_ERR_LOST_FROM_WRT_ERR)
+               printk(KERN_CRIT "CIA lost machine check: "
+                      "Write to flash ROM attempted\n");
+       if (cia->cia_err & CIA_ERR_LOST_IOA_TIMEOUT)
+               printk(KERN_CRIT "CIA lost machine check: "
+                      "I/O timeout\n");
+
+       return 1;
+}
+
 void
 cia_machine_check(unsigned long vector, unsigned long la_ptr,
                  struct pt_regs * regs)
@@ -769,30+1127,7 @@ cia_machine_check(unsigned long vector, unsigned long la_ptr,
        mb();
 
        expected = mcheck_expected(0);
-       if (!expected && vector == 0x660) {
-               struct el_common *com;
-               struct el_common_EV5_uncorrectable_mcheck *ev5;
-               struct el_CIA_sysdata_mcheck *cia;
-
-               com = (void *)la_ptr;
-               ev5 = (void *)(la_ptr + com->proc_offset);
-               cia = (void *)(la_ptr + com->sys_offset);
-
-               if (com->code == 0x202) {
-                       printk(KERN_CRIT "CIA PCI machine check: code=%x\n"
-                              "  cpu_err0=%08x cpu_err1=%08x cia_err=%08x\n"
-                              "  cia_stat=%08x err_mask=%08x cia_syn=%08x\n"
-                              "  mem_err0=%08x mem_err1=%08x\n"
-                              "  pci_err0=%08x pci_err1=%08x pci_err2=%08x\n",
-                              (int) com->code,
-                              (int) cia->cpu_err0, (int) cia->cpu_err1,
-                              (int) cia->cia_err,  (int) cia->cia_stat,
-                              (int) cia->err_mask, (int) cia->cia_syn,
-                              (int) cia->mem_err0, (int) cia->mem_err1,
-                              (int) cia->pci_err0, (int) cia->pci_err1,
-                              (int) cia->pci_err2);
-                       expected = 1;
-               }
-       }
+       if (!expected && vector == 0x660)
+               expected = cia_decode_mchk(la_ptr);
        process_mcheck_info(vector, la_ptr, regs, "CIA", expected);
 }
index 453766d..0303487 100644 (file)
 #include "proto.h"
 #include "pci_impl.h"
 
-
-/*
- * NOTE: Herein lie back-to-back mb instructions.  They are magic.
- * One plausible explanation is that the I/O controller does not properly
- * handle the system transaction.  Another involves timing.  Ho hum.
- */
+#undef DEBUG_IRONGATE          /* define to enable verbose Irongate debug */
 
 /*
  * BIOS32-style PCI interface:
@@ -200,11+195,12 @@ struct pci_ops irongate_pci_ops =
        write_dword:    irongate_write_config_dword
 };
 \f
-#if 0
+#ifdef DEBUG_IRONGATE
 static void
 irongate_register_dump(const char *function_name)
 {
        printk("%s: Irongate registers:\n"
+              "\tFunction 0:\n"
               "\tdev_vendor\t0x%08x\n"
               "\tstat_cmd\t0x%08x\n"
               "\tclass\t\t0x%08x\n"
@@ -249,7+245,26 @@ irongate_register_dump(const char *function_name)
               "\tagpstat\t\t0x%08x\n"
               "\tagpcmd\t\t0x%08x\n"
               "\tagpva\t\t0x%08x\n"
-              "\tagpmode\t\t0x%08x\n",
+              "\tagpmode\t\t0x%08x\n"
+
+              "\n\tFunction 1:\n"
+              "\tdev_vendor:\t0x%08x\n"
+              "\tcmd_status:\t0x%08x\n"
+              "\trevid_etc :\t0x%08x\n"
+              "\thtype_etc :\t0x%08x\n"
+              "\trsrvd0[0] :\t0x%08x\n"
+              "\trsrvd0[1] :\t0x%08x\n"
+              "\tbus_nmbers:\t0x%08x\n"
+              "\tio_baselim:\t0x%08x\n"
+              "\tmem_bselim:\t0x%08x\n"
+              "\tpf_baselib:\t0x%08x\n"
+              "\trsrvd1[0] :\t0x%08x\n"
+              "\trsrvd1[1] :\t0x%08x\n"
+              "\tio_baselim:\t0x%08x\n"
+              "\trsrvd2[0] :\t0x%08x\n"
+              "\trsrvd2[1] :\t0x%08x\n"
+              "\tinterrupt :\t0x%08x\n",
+
               function_name,
               IRONGATE0->dev_vendor,
               IRONGATE0->stat_cmd,
@@ -295,7+310,23 @@ irongate_register_dump(const char *function_name)
               IRONGATE0->agpstat,
               IRONGATE0->agpcmd,
               IRONGATE0->agpva,
-              IRONGATE0->agpmode);
+              IRONGATE0->agpmode,
+              IRONGATE1->dev_vendor,
+              IRONGATE1->stat_cmd,
+              IRONGATE1->class,
+              IRONGATE1->htype,
+              IRONGATE1->rsrvd0[0],
+              IRONGATE1->rsrvd0[1],
+              IRONGATE1->busnos,
+              IRONGATE1->io_baselim_regs,
+              IRONGATE1->mem_baselim,
+              IRONGATE1->pfmem_baselim,
+              IRONGATE1->rsrvd1[0],
+              IRONGATE1->rsrvd1[1],
+              IRONGATE1->io_baselim,
+              IRONGATE1->rsrvd2[0],
+              IRONGATE1->rsrvd2[1],
+              IRONGATE1->interrupt );
 }
 #else
 #define irongate_register_dump(x)
index ce51570..1a9a69b 100644 (file)
@@ -501,10+501,6 @@ CONFIG_PCMCIA_SERIAL=y
 #
 # Multimedia devices
 #
-
-#
-# Video For Linux
-#
 # CONFIG_VIDEO_DEV is not set
 
 #
index b264c54..b71cf06 100644 (file)
@@ -279,7+279,6 @@ static inline int save_i387_fsave( struct _fpstate *buf )
 {
        struct task_struct *tsk = current;
 
-       unlazy_fpu( tsk );
        tsk->thread.i387.fsave.status = tsk->thread.i387.fsave.swd;
        if ( __copy_to_user( buf, &tsk->thread.i387.fsave,
                             sizeof(struct i387_fsave_struct) ) )
@@ -292,8+291,6 @@ static inline int save_i387_fxsave( struct _fpstate *buf )
        struct task_struct *tsk = current;
        int err = 0;
 
-       unlazy_fpu( tsk );
-
        if ( convert_fxsr_to_user( buf, &tsk->thread.i387.fxsave ) )
                return -1;
 
index e1b00a7..66e1bd9 100644 (file)
@@ -982,7+982,10 @@ void disable_IO_APIC(void)
 static void __init setup_ioapic_ids_from_mpc (void)
 {
        struct IO_APIC_reg_00 reg_00;
+       unsigned long phys_id_present_map = phys_cpu_present_map;
        int apic;
+       int i;
+       unsigned char old_id;
 
        /*
         * Set the IOAPIC ID to the value stored in the MPC table.
@@ -992,6+995,8 @@ static void __init setup_ioapic_ids_from_mpc (void)
                /* Read the register 0 value */
                *(int *)&reg_00 = io_apic_read(apic, 0);
                
+               old_id = mp_ioapics[apic].mpc_apicid;
+
                if (mp_ioapics[apic].mpc_apicid >= 0xf) {
                        printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
                                apic, mp_ioapics[apic].mpc_apicid);
@@ -1001,21+1006,41 @@ static void __init setup_ioapic_ids_from_mpc (void)
                }
 
                /*
+                * Sanity check, is the ID really free? Every APIC in a
+                * system must have a unique ID or we get lots of nice
+                * 'stuck on smp_invalidate_needed IPI wait' messages.
+                */
+               if (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid)) {
+                       printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
+                               apic, mp_ioapics[apic].mpc_apicid);
+                       for (i = 0; i < 0xf; i++)
+                               if (!(phys_id_present_map & (1 << i)))
+                                       break;
+                       if (i >= 0xf)
+                               panic("Max APIC ID exceeded!\n");
+                       printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
+                               i);
+                       phys_id_present_map |= 1 << i;
+                       mp_ioapics[apic].mpc_apicid = i;
+               }
+
+               /*
+                * We need to adjust the IRQ routing table
+                * if the ID changed.
+                */
+               if (old_id != mp_ioapics[apic].mpc_apicid)
+                       for (i = 0; i < mp_irq_entries; i++)
+                               if (mp_irqs[i].mpc_dstapic == old_id)
+                                       mp_irqs[i].mpc_dstapic
+                                               = mp_ioapics[apic].mpc_apicid;
+
+               /*
                 * Read the right value from the MPC table and
                 * write it into the ID register.
                 */
                printk(KERN_INFO "...changing IO-APIC physical APIC ID to %d ...",
                                        mp_ioapics[apic].mpc_apicid);
 
-               /*
-                * Sanity check, is the ID really free? Every APIC in the
-                * system must have a unique ID or we get lots of nice
-                * 'stuck on smp_invalidate_needed IPI wait' messages.
-                */
-               if (phys_cpu_present_map & (1<<mp_ioapics[apic].mpc_apicid))
-                       panic("APIC ID %d already used",
-                               mp_ioapics[apic].mpc_apicid);
-
                reg_00.ID = mp_ioapics[apic].mpc_apicid;
                io_apic_write(apic, 0, *(int *)&reg_00);
 
index 116816f..497efd6 100644 (file)
@@ -682,7+682,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
                                /* FALLTHRU */
 
                        default:
-                               sigaddset(&current->signal, signr);
+                               sigaddset(&current->pending.signal, signr);
                                recalc_sigpending(current);
                                current->flags |= PF_SIGNALED;
                                do_exit(exit_code);
index f2aa6ca..a088424 100644 (file)
@@ -1,4+1,4 @@
-/*  $Id: irq.c,v 1.106 2000/08/05 10:48:40 davem Exp $
+/*  $Id: irq.c,v 1.107 2000/08/26 02:42:28 anton Exp $
  *  arch/sparc/kernel/irq.c:  Interrupt request handling routines. On the
  *                            Sparc the IRQ's are basically 'cast in stone'
  *                            and you are supposed to probe the prom's device
@@ -8,7+8,7 @@
  *  Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
  *  Copyright (C) 1995 Pete A. Zaitcev (zaitcev@metabyte.com)
  *  Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
- *  Copyright (C) 1998-99 Anton Blanchard (anton@progsoc.uts.edu.au)
+ *  Copyright (C) 1998-2000 Anton Blanchard (anton@linuxcare.com)
  */
 
 #include <linux/config.h>
@@ -196,41+196,29 @@ void free_irq(unsigned int irq, void *dev_id)
 }
 
 #ifdef CONFIG_SMP
-/* SMP interrupt locking on Sparc. */
 
 /* Who has global_irq_lock. */
 unsigned char global_irq_holder = NO_PROC_ID;
 
-/* This protects IRQ's. */
-spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED;
-
-/* Global IRQ locking depth. */
-atomic_t global_irq_count = ATOMIC_INIT(0);
-
 void smp_show_backtrace_all_cpus(void);
 void show_backtrace(void);
 
-#define MAXCOUNT 100000000
 #define VERBOSE_DEBUG_IRQLOCK
+#define MAXCOUNT 100000000
 
 static void show(char * str)
 {
-       int i;
        int cpu = smp_processor_id();
+       int i;
 
        printk("\n%s, CPU %d:\n", str, cpu);
-       printk("irq:  %d [ ", atomic_read(&global_irq_count));
-
-       for (i = 0; i < NR_CPUS; i++) {
-               printk("%d ", local_irq_count(i));
-       }
-       printk("]\n");
-
-       printk("bh:   %d [ ", (spin_is_locked(&global_bh_lock) ? 1 : 0));
-
-       for (i = 0; i < NR_CPUS; i++) {
-               printk("%d ", local_bh_count(cpu));
-       }
+       printk("irq:  %d [ ", irqs_running());
+       for (i = 0; i < smp_num_cpus; i++)
+               printk("%u ", __brlock_array[i][BR_GLOBALIRQ_LOCK]);
+       printk("]\nbh:   %d [ ",
+              (spin_is_locked(&global_bh_lock) ? 1 : 0));
+       for (i = 0; i < smp_num_cpus; i++)
+               printk("%u ", local_bh_count(i));
        printk("]\n");
 
 #ifdef VERBOSE_DEBUG_IRQLOCK
@@ -240,48+228,11 @@ static void show(char * str)
 #endif
 }
 
+
 /*
  * We have to allow irqs to arrive between __sti and __cli
  */
-#define SYNC_OTHER_CORES(x) udelay(x+1)
-
-static inline void wait_on_irq(int cpu)
-{
-       int count = MAXCOUNT;
-
-       for (;;) {
-               /*
-                * Wait until all interrupts are gone. Wait
-                * for bottom half handlers unless we're
-                * already executing in one..
-                */
-               if (!atomic_read(&global_irq_count)) {
-                       if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
-                               break;
-               }
-
-               /* Duh, we have to loop. Release the lock to avoid deadlocks */
-               spin_unlock(&global_irq_lock);
-
-               for (;;) {
-                       if (!--count) {
-                               show("wait_on_irq");
-                               count = ~0;
-                       }
-                       __sti();
-                       SYNC_OTHER_CORES(cpu);
-                       __cli();
-                       if (atomic_read(&global_irq_count))
-                               continue;
-                       if (spin_is_locked (&global_irq_lock))
-                               continue;
-                       if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
-                               continue;
-                       if (spin_trylock(&global_irq_lock))
-                               break;
-               }
-       }
-}
+#define SYNC_OTHER_CORES(x) barrier()
 
 /*
  * This is called when we want to synchronize with
@@ -292,8+243,7 @@ static inline void wait_on_irq(int cpu)
  */
 void synchronize_irq(void)
 {
-       if (atomic_read(&global_irq_count)) {
-               /* Stupid approach */
+       if (irqs_running()) {
                cli();
                sti();
        }
@@ -301,32+251,37 @@ void synchronize_irq(void)
 
 static inline void get_irqlock(int cpu)
 {
-       int count = MAXCOUNT;
+       int count;
 
-       if (!spin_trylock(&global_irq_lock)) {
-               /* do we already hold the lock? */
-               if ((unsigned char) cpu == global_irq_holder)
-                       return;
-               /* Uhhuh.. Somebody else got it. Wait.. */
-               do {
-                       while (spin_is_locked(&global_irq_lock)) {
-                               if (!--count) {
-                                       show("get_irqlock");
-                                       count = ~0;
-                               }
-                               barrier();
+       if ((unsigned char)cpu == global_irq_holder)
+               return;
+
+       count = MAXCOUNT;
+again:
+       br_write_lock(BR_GLOBALIRQ_LOCK);
+       for (;;) {
+               spinlock_t *lock;
+
+               if (!irqs_running() &&
+                   (local_bh_count(smp_processor_id()) || !spin_is_locked(&global_bh_lock)))
+                       break;
+
+               br_write_unlock(BR_GLOBALIRQ_LOCK);
+               lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock;
+               while (irqs_running() ||
+                      spin_is_locked(lock) ||
+                      (!local_bh_count(smp_processor_id()) && spin_is_locked(&global_bh_lock))) {
+                       if (!--count) {
+                               show("get_irqlock");
+                               count = (~0 >> 1);
                        }
-               } while (!spin_trylock(&global_irq_lock));
+                       __sti();
+                       SYNC_OTHER_CORES(cpu);
+                       __cli();
+               }
+               goto again;
        }
-       /* 
-        * We also to make sure that nobody else is running
-        * in an interrupt context. 
-        */
-       wait_on_irq(cpu);
 
-       /*
-        * Ok, finally..
-        */
        global_irq_holder = cpu;
 }
 
@@ -344,7+299,7 @@ static inline void get_irqlock(int cpu)
  */
 void __global_cli(void)
 {
-       unsigned int flags;
+       unsigned long flags;
 
        __save_flags(flags);
 
@@ -374,9+329,7 @@ void __global_sti(void)
  */
 unsigned long __global_save_flags(void)
 {
-       int retval;
-       int local_enabled = 0;
-       unsigned long flags;
+       unsigned long flags, local_enabled, retval;
 
        __save_flags(flags);
 
index e05b20f..a1742c2 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: sparc_ksyms.c,v 1.102 2000/08/05 10:48:40 davem Exp $
+/* $Id: sparc_ksyms.c,v 1.103 2000/08/26 02:42:28 anton Exp $
  * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -111,13+111,6 @@ EXPORT_SYMBOL_PRIVATE(_rw_read_enter);
 EXPORT_SYMBOL_PRIVATE(_rw_read_exit);
 EXPORT_SYMBOL_PRIVATE(_rw_write_enter);
 #endif
-#ifdef CONFIG_SMP
-EXPORT_SYMBOL(__global_save_flags);
-EXPORT_SYMBOL(__global_restore_flags);
-EXPORT_SYMBOL(__global_sti);
-EXPORT_SYMBOL(__global_cli);
-#endif
-
 /* rw semaphores */
 EXPORT_SYMBOL_NOVERS(___down_read);
 EXPORT_SYMBOL_NOVERS(___down_write);
@@ -137,14+130,17 @@ EXPORT_SYMBOL_PRIVATE(_change_bit);
 EXPORT_SYMBOL_PRIVATE(_set_le_bit);
 EXPORT_SYMBOL_PRIVATE(_clear_le_bit);
 
-/* IRQ implementation. */
 #ifdef CONFIG_SMP
+/* Kernel wide locking */
 EXPORT_SYMBOL(kernel_flag);
+
+/* IRQ implementation. */
 EXPORT_SYMBOL(global_irq_holder);
-EXPORT_SYMBOL(global_irq_lock);
-EXPORT_SYMBOL(global_bh_lock);
-EXPORT_SYMBOL(global_irq_count);
 EXPORT_SYMBOL(synchronize_irq);
+EXPORT_SYMBOL(__global_cli);
+EXPORT_SYMBOL(__global_sti);
+EXPORT_SYMBOL(__global_save_flags);
+EXPORT_SYMBOL(__global_restore_flags);
 #endif
 
 EXPORT_SYMBOL(udelay);
index 4f5bd16..408d59c 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: srmmu.c,v 1.221 2000/08/14 00:46:13 anton Exp $
+/* $Id: srmmu.c,v 1.222 2000/08/29 08:59:23 davem Exp $
  * srmmu.c:  SRMMU specific routines for memory management.
  *
  * Copyright (C) 1995 David S. Miller  (davem@caip.rutgers.edu)
@@ -1323,8+1323,8 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma,
                mapping = file->f_dentry->d_inode->i_mapping;
                offset = (address & PAGE_MASK) - vma->vm_start;
                spin_lock(&mapping->i_shared_lock);
-               vmaring = mapping->i_mmap; 
-               do {
+               vmaring = mapping->i_mmap_shared
+               if (vmaring != NULL) do {
                        /* Do not mistake ourselves as another mapping. */
                        if(vmaring == vma)
                                continue;
index 66bc3af..a99ce73 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: sun4c.c,v 1.198 2000/08/14 00:46:13 anton Exp $
+/* $Id: sun4c.c,v 1.199 2000/08/29 08:59:23 davem Exp $
  * sun4c.c: Doing in software what should be done in hardware.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -2404,8+2404,8 @@ static void sun4c_vac_alias_fixup(struct vm_area_struct *vma, unsigned long addr
 
                mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
                spin_lock(&mapping->i_shared_lock);
-               vmaring = mapping->i_mmap; 
-               do {
+               vmaring = mapping->i_mmap_shared
+               if (vmaring != NULL) do {
                        unsigned long vaddr = vmaring->vm_start + offset;
                        unsigned long start;
 
index c2b8574..bf61ff1 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: console.c,v 1.22 2000/02/08 20:24:23 davem Exp $
+/* $Id: console.c,v 1.23 2000/08/26 02:38:03 anton Exp $
  * console.c: Routines that deal with sending and receiving IO
  *            to/from the current console device using the PROM.
  *
@@ -30,7+30,7 @@ prom_nbgetchar(void)
        int i = -1;
        unsigned long flags;
 
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
        case PROM_SUN4:
@@ -49,7+49,7 @@ prom_nbgetchar(void)
                break;
        };
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
        return i; /* Ugh, we could spin forever on unsupported proms ;( */
 }
 
@@ -63,7+63,7 @@ prom_nbputchar(char c)
        unsigned long flags;
        int i = -1;
 
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
        case PROM_SUN4:
@@ -82,7+82,7 @@ prom_nbputchar(char c)
                break;
        };
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
        return i; /* Ugh, we could spin forever on unsupported proms ;( */
 }
 
@@ -125,10+125,10 @@ prom_query_input_device()
                        return PROMDEV_I_UNK;
                };
        case PROM_V3:
-               save_flags(flags); cli();
+               spin_lock_irqsave(&prom_lock, flags);
                st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin);
                restore_current();
-               restore_flags(flags);
+               spin_unlock_irqrestore(&prom_lock, flags);
                if(prom_node_has_property(st_p, "keyboard"))
                        return PROMDEV_IKBD;
                if (prom_getproperty(st_p, "name", propb, sizeof(propb)) != -1) {
@@ -174,10+174,10 @@ prom_query_output_device()
                break;
        case PROM_V2:
        case PROM_V3:
-               save_flags(flags); cli();
+               spin_lock_irqsave(&prom_lock, flags);
                st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout);
                restore_current();
-               restore_flags(flags);
+               spin_unlock_irqrestore(&prom_lock, flags);
                propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
                if (propl >= 0 && propl == sizeof("display") &&
                        strncmp("display", propb, sizeof("display")) == 0)
index 463b075..eb12073 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: devmap.c,v 1.6 1998/03/09 14:04:23 jj Exp $
+/* $Id: devmap.c,v 1.7 2000/08/26 02:38:03 anton Exp $
  * promdevmap.c:  Map device/IO areas to virtual addresses.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -29,13+29,13 @@ prom_mapio(char *vhint, int ios, unsigned int paddr, unsigned int num_bytes)
        unsigned long flags;
        char *ret;
 
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        if((num_bytes == 0) || (paddr == 0)) ret = (char *) 0x0;
        else
        ret = (*(romvec->pv_v2devops.v2_dumb_mmap))(vhint, ios, paddr,
                                                    num_bytes);
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
        return ret;
 }
 
@@ -46,9+46,9 @@ prom_unmapio(char *vaddr, unsigned int num_bytes)
        unsigned long flags;
 
        if(num_bytes == 0x0) return;
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        (*(romvec->pv_v2devops.v2_dumb_munmap))(vaddr, num_bytes);
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
        return;
 }
index 5a58efa..61919b5 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: devops.c,v 1.12 2000/01/29 01:09:12 anton Exp $
+/* $Id: devops.c,v 1.13 2000/08/26 02:38:03 anton Exp $
  * devops.c:  Device operations using the PROM.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -21,7+21,7 @@ prom_devopen(char *dstr)
 {
        int handle;
        unsigned long flags;
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
                handle = (*(romvec->pv_v0devops.v0_devopen))(dstr);
@@ -36,7+36,7 @@ prom_devopen(char *dstr)
                break;
        };
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
 
        return handle;
 }
@@ -46,7+46,7 @@ int
 prom_devclose(int dhandle)
 {
        unsigned long flags;
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
                (*(romvec->pv_v0devops.v0_devclose))(dhandle);
@@ -59,7+59,7 @@ prom_devclose(int dhandle)
                break;
        };
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
        return 0;
 }
 
@@ -70,7+70,7 @@ void
 prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
 {
        unsigned long flags;
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
                (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo);
@@ -83,7+83,7 @@ prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
                break;
        };
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
 
        return;
 }
index 3c2f243..86ce399 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: misc.c,v 1.17 1998/07/21 10:36:22 jj Exp $
+/* $Id: misc.c,v 1.18 2000/08/26 02:38:03 anton Exp $
  * misc.c:  Miscellaneous prom functions that don't belong
  *          anywhere else.
  *
 
 extern void restore_current(void);
 
+spinlock_t prom_lock = SPIN_LOCK_UNLOCKED;
+
 /* Reset and reboot the machine with the command 'bcommand'. */
 void
 prom_reboot(char *bcommand)
 {
        unsigned long flags;
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        (*(romvec->pv_reboot))(bcommand);
        /* Never get here. */
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
 }
 
 /* Forth evaluate the expression contained in 'fstring'. */
@@ -34,13+36,13 @@ prom_feval(char *fstring)
        unsigned long flags;
        if(!fstring || fstring[0] == 0)
                return;
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        if(prom_vers == PROM_V0)
                (*(romvec->pv_fortheval.v0_eval))(strlen(fstring), fstring);
        else
                (*(romvec->pv_fortheval.v2_eval))(fstring);
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
 }
 
 /* We want to do this more nicely some day. */
@@ -66,10+68,10 @@ prom_cmdline(void)
                prom_palette (1);
 #endif
        install_obp_ticker();
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        (*(romvec->pv_abort))();
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
        install_linux_ticker();
 #ifdef CONFIG_SUN_AUXIO
        TURN_ON_LED;
@@ -88,11+90,11 @@ prom_halt(void)
 {
        unsigned long flags;
 again:
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        (*(romvec->pv_halt))();
        /* Never get here. */
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
        goto again; /* PROM is out to get me -DaveM */
 }
 
index ba62467..92fe373 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: mp.c,v 1.11 2000/01/29 01:09:12 anton Exp $
+/* $Id: mp.c,v 1.12 2000/08/26 02:38:03 anton Exp $
  * mp.c:  OpenBoot Prom Multiprocessor support routines.  Don't call
  *        these on a UP or else you will halt and catch fire. ;)
  *
@@ -25,7+25,7 @@ prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, cha
        int ret;
        unsigned long flags;
 
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
        case PROM_V2:
@@ -37,7+37,7 @@ prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, cha
                break;
        };
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
 
        return ret;
 }
@@ -51,7+51,7 @@ prom_stopcpu(int cpunode)
        int ret;
        unsigned long flags;
 
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
        case PROM_V2:
@@ -63,7+63,7 @@ prom_stopcpu(int cpunode)
                break;
        };
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
 
        return ret;
 }
@@ -77,7+77,7 @@ prom_idlecpu(int cpunode)
        int ret;
        unsigned long flags;
 
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
        case PROM_V2:
@@ -89,7+89,7 @@ prom_idlecpu(int cpunode)
                break;
        };
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
 
        return ret;
 }
@@ -103,7+103,7 @@ prom_restartcpu(int cpunode)
        int ret;
        unsigned long flags;
 
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
        case PROM_V2:
@@ -115,7+115,7 @@ prom_restartcpu(int cpunode)
                break;
        };
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
 
        return ret;
 }
index 62b3f85..09d6460 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: segment.c,v 1.6 1998/03/09 14:04:27 jj Exp $
+/* $Id: segment.c,v 1.7 2000/08/26 02:38:03 anton Exp $
  * segment.c:  Prom routine to map segments in other contexts before
  *             a standalone is completely mapped.  This is for sun4 and
  *             sun4c architectures only.
@@ -21,9+21,9 @@ void
 prom_putsegment(int ctx, unsigned long vaddr, int segment)
 {
        unsigned long flags;
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        (*(romvec->pv_setctxt))(ctx, (char *) vaddr, segment);
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
        return;
 }
index 2e79057..adfe6e7 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: tree.c,v 1.25 1998/09/17 11:04:58 jj Exp $
+/* $Id: tree.c,v 1.26 2000/08/26 02:38:03 anton Exp $
  * tree.c: Basic device tree traversal/scanning for the Linux
  *         prom library.
  *
@@ -26,10+26,10 @@ int __prom_getchild(int node)
        unsigned long flags;
        int cnode;
 
-       save_and_cli(flags);
+       spin_lock_irqsave(&prom_lock, flags);
        cnode = prom_nodeops->no_child(node);
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
 
        return cnode;
 }
@@ -57,10+57,10 @@ int __prom_getsibling(int node)
        unsigned long flags;
        int cnode;
 
-       save_and_cli(flags);
+       spin_lock_irqsave(&prom_lock, flags);
        cnode = prom_nodeops->no_nextnode(node);
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
 
        return cnode;
 }
@@ -93,10+93,10 @@ int prom_getproplen(int node, char *prop)
        if((!node) || (!prop))
                return -1;
                
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        ret = prom_nodeops->no_proplen(node, prop);
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
        return ret;
 }
 
@@ -113,10+113,10 @@ int prom_getproperty(int node, char *prop, char *buffer, int bufsize)
        if((plen > bufsize) || (plen == 0) || (plen == -1))
                return -1;
        /* Ok, things seem all right. */
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        ret = prom_nodeops->no_getprop(node, prop, buffer);
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
        return ret;
 }
 
@@ -226,10+226,10 @@ char * __prom_nextprop(int node, char * oprop)
        unsigned long flags;
        char *prop;
 
-       save_and_cli(flags);
+       spin_lock_irqsave(&prom_lock, flags);
        prop = prom_nodeops->no_nextprop(node, oprop);
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
 
        return prop;
 }
@@ -325,10+325,10 @@ int prom_setprop(int node, char *pname, char *value, int size)
 
        if(size == 0) return 0;
        if((pname == 0) || (value == 0)) return 0;
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        ret = prom_nodeops->no_setprop(node, pname, value, size);
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
        return ret;
 }
 
@@ -337,10+337,10 @@ int prom_inst2pkg(int inst)
        int node;
        unsigned long flags;
        
-       save_flags(flags); cli();
+       spin_lock_irqsave(&prom_lock, flags);
        node = (*romvec->pv_v2devops.v2_inst2pkg)(inst);
        restore_current();
-       restore_flags(flags);
+       spin_unlock_irqrestore(&prom_lock, flags);
        if (node == -1) return 0;
        return node;
 }
index 7f2e21a..9e1c652 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: irq.c,v 1.91 2000/08/05 10:48:40 davem Exp $
+/* $Id: irq.c,v 1.92 2000/08/26 02:42:28 anton Exp $
  * irq.c: UltraSparc IRQ handling/init/registry.
  *
  * Copyright (C) 1997  David S. Miller  (davem@caip.rutgers.edu)
@@ -608,7+608,7 @@ again:
                       spin_is_locked(lock) ||
                       (!local_bh_count(smp_processor_id()) && spin_is_locked(&global_bh_lock))) {
                        if (!--count) {
-                               show("wait_on_irq");
+                               show("get_irqlock");
                                count = (~0 >> 1);
                        }
                        __sti();
index e869af4..235d348 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: sys_sparc.c,v 1.45 2000/07/30 23:12:24 davem Exp $
+/* $Id: sys_sparc.c,v 1.46 2000/08/29 07:01:54 davem Exp $
  * linux/arch/sparc64/kernel/sys_sparc.c
  *
  * This file contains various random system calls that
@@ -398,13+398,18 @@ asmlinkage int sys_utrap_install(utrap_entry_t type, utrap_handler_t new_p,
                return -EINVAL;
        if (new_p == (utrap_handler_t)(long)UTH_NOCHANGE) {
                if (old_p) {
-                       if (!current->thread.utraps)
-                               put_user_ret(NULL, old_p, -EFAULT);
-                       else
-                               put_user_ret((utrap_handler_t)(current->thread.utraps[type]), old_p, -EFAULT);
+                       if (!current->thread.utraps) {
+                               if (put_user(NULL, old_p))
+                                       return -EFAULT;
+                       } else {
+                               if (put_user((utrap_handler_t)(current->thread.utraps[type]), old_p))
+                                       return -EFAULT;
+                       }
+               }
+               if (old_d) {
+                       if (put_user(NULL, old_d))
+                               return -EFAULT;
                }
-               if (old_d)
-                       put_user_ret(NULL, old_d, -EFAULT);
                return 0;
        }
        if (!current->thread.utraps) {
@@ -431,11+436,14 @@ asmlinkage int sys_utrap_install(utrap_entry_t type, utrap_handler_t new_p,
                               UT_TRAP_INSTRUCTION_31*sizeof(long));
                }
        }
-       if (old_p)
-               put_user_ret((utrap_handler_t)(current->thread.utraps[type]),
-                            old_p, -EFAULT);
-       if (old_d)
-               put_user_ret(NULL, old_d, -EFAULT);
+       if (old_p) {
+               if (put_user((utrap_handler_t)(current->thread.utraps[type]), old_p))
+                       return -EFAULT;
+       }
+       if (old_d) {
+               if (put_user(NULL, old_d))
+                       return -EFAULT;
+       }
        current->thread.utraps[type] = (long)new_p;
 
        return 0;
index 3cf5b68..e80d6b1 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: fs.c,v 1.22 2000/07/28 12:15:02 davem Exp $
+/* $Id: fs.c,v 1.23 2000/08/29 07:01:54 davem Exp $
  * fs.c: fs related syscall emulation for Solaris
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -612,20+612,25 @@ asmlinkage int solaris_fcntl(unsigned fd, unsigned cmd, u32 arg)
                        case SOL_F_SETLKW: cmd = F_SETLKW; break;
                        }
 
-                       get_user_ret (f.l_type, &((struct sol_flock *)A(arg))->l_type, -EFAULT);
-                       __get_user_ret (f.l_whence, &((struct sol_flock *)A(arg))->l_whence, -EFAULT);
-                       __get_user_ret (f.l_start, &((struct sol_flock *)A(arg))->l_start, -EFAULT);
-                       __get_user_ret (f.l_len, &((struct sol_flock *)A(arg))->l_len, -EFAULT);
-                       __get_user_ret (f.l_pid, &((struct sol_flock *)A(arg))->l_sysid, -EFAULT);
+                       if (get_user (f.l_type, &((struct sol_flock *)A(arg))->l_type) ||
+                           __get_user (f.l_whence, &((struct sol_flock *)A(arg))->l_whence) ||
+                           __get_user (f.l_start, &((struct sol_flock *)A(arg))->l_start) ||
+                           __get_user (f.l_len, &((struct sol_flock *)A(arg))->l_len) ||
+                           __get_user (f.l_pid, &((struct sol_flock *)A(arg))->l_sysid))
+                               return -EFAULT;
+
                        set_fs(KERNEL_DS);
                        ret = sys_fcntl(fd, cmd, (unsigned long)&f);
                        set_fs(old_fs);
-                       __put_user_ret (f.l_type, &((struct sol_flock *)A(arg))->l_type, -EFAULT);
-                       __put_user_ret (f.l_whence, &((struct sol_flock *)A(arg))->l_whence, -EFAULT);
-                       __put_user_ret (f.l_start, &((struct sol_flock *)A(arg))->l_start, -EFAULT);
-                       __put_user_ret (f.l_len, &((struct sol_flock *)A(arg))->l_len, -EFAULT);
-                       __put_user_ret (f.l_pid, &((struct sol_flock *)A(arg))->l_pid, -EFAULT);
-                       __put_user_ret (0, &((struct sol_flock *)A(arg))->l_sysid, -EFAULT);
+
+                       if (__put_user (f.l_type, &((struct sol_flock *)A(arg))->l_type) ||
+                           __put_user (f.l_whence, &((struct sol_flock *)A(arg))->l_whence) ||
+                           __put_user (f.l_start, &((struct sol_flock *)A(arg))->l_start) ||
+                           __put_user (f.l_len, &((struct sol_flock *)A(arg))->l_len) ||
+                           __put_user (f.l_pid, &((struct sol_flock *)A(arg))->l_pid) ||
+                           __put_user (0, &((struct sol_flock *)A(arg))->l_sysid))
+                               return -EFAULT;
+
                        return ret;
                }
        case SOL_F_FREESP:
@@ -634,7+639,9 @@ asmlinkage int solaris_fcntl(unsigned fd, unsigned cmd, u32 arg)
                    int (*sys_newftruncate)(unsigned int, unsigned long)=
                            (int (*)(unsigned int, unsigned long))SYS(ftruncate);
 
-                   get_user_ret(length, &((struct sol_flock*)A(arg))->l_start, -EFAULT);
+                   if (get_user(length, &((struct sol_flock*)A(arg))->l_start))
+                           return -EFAULT;
+
                    return sys_newftruncate(fd, length);
                }
        };
index a7edd18..ca8bf25 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: misc.c,v 1.29 2000/08/14 23:50:31 anton Exp $
+/* $Id: misc.c,v 1.30 2000/08/29 07:01:54 davem Exp $
  * misc.c: Miscelaneous syscall emulation for Solaris
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -139,12+139,14 @@ asmlinkage int solaris_brk(u32 brk)
        int i, len = (countfrom) ?                                      \
                ((sizeof(to) > sizeof(from) ?                           \
                        sizeof(from) : sizeof(to))) : sizeof(to);       \
-       copy_to_user_ret(to, from, len, -EFAULT);                       \
+       if (copy_to_user(to, from, len))                                \
+               return -EFAULT;                                         \
        if (dotchop)                                                    \
                for (p=from,i=0; *p && *p != '.' && --len; p++,i++);    \
        else                                                            \
                i = len - 1;                                            \
-       __put_user_ret('\0', (char *)(to+i), -EFAULT);                  \
+       if (__put_user('\0', (char *)(to+i)))                           \
+               return -EFAULT;                                         \
 }
 
 struct sol_uname {
@@ -297,10+299,13 @@ asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count)
        }
        len = strlen(r) + 1;
        if (count < len) {
-               copy_to_user_ret((char *)A(buf), r, count - 1, -EFAULT);
-               __put_user_ret(0, (char *)A(buf) + count - 1, -EFAULT);
-       } else
-               copy_to_user_ret((char *)A(buf), r, len, -EFAULT);
+               if (copy_to_user((char *)A(buf), r, count - 1) ||
+                   __put_user(0, (char *)A(buf) + count - 1))
+                       return -EFAULT;
+       } else {
+               if (copy_to_user((char *)A(buf), r, len))
+                       return -EFAULT;
+       }
        return len;
 }
 
index 7105bc0..a399238 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: signal.c,v 1.5 1997/12/15 15:04:59 jj Exp $
+/* $Id: signal.c,v 1.6 2000/08/29 07:01:54 davem Exp $
  * signal.c: Signal emulation for Solaris
  *
  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -368,9+368,13 @@ asmlinkage int solaris_waitid(int idtype, s32 pid, u32 info, int options)
        if (info) {
                struct sol_siginfo *s = (struct sol_siginfo *)A(info);
        
-               if (get_user (status, (unsigned int *)A(info))) return -EFAULT;
-               __put_user_ret (SOLARIS_SIGCLD, &s->si_signo, -EFAULT);
-               __put_user_ret (ret, &s->_data._proc._pid, -EFAULT);
+               if (get_user (status, (unsigned int *)A(info)))
+                       return -EFAULT;
+
+               if (__put_user (SOLARIS_SIGCLD, &s->si_signo) ||
+                   __put_user (ret, &s->_data._proc._pid))
+                       return -EFAULT;
+
                switch (status & 0xff) {
                case 0: ret = SOLARIS_CLD_EXITED;
                        status = (status >> 8) & 0xff;
@@ -390,8+394,10 @@ asmlinkage int solaris_waitid(int idtype, s32 pid, u32 info, int options)
                        status = linux_to_solaris_signals[status & 0x7f];
                        break;
                }
-               __put_user_ret (ret, &s->si_code, -EFAULT);
-               __put_user_ret (status, &s->_data._proc._pdata._cld._status, -EFAULT);
+
+               if (__put_user (ret, &s->si_code) ||
+                   __put_user (status, &s->_data._proc._pdata._cld._status))
+                       return -EFAULT;
        }
        return 0;
 }
index dcd9d10..16221e3 100644 (file)
  * being used to store jiffies, which are unsigned longs).
  */
 
+/*
+ * 2000/08/28 -- Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * - get rid of check_region
+ * - s/suser/capable/
+ */
+
 #define FLOPPY_SANITY_CHECK
 #undef  FLOPPY_SILENT_DCL_CLEAR
 
@@ -3497,7+3503,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 
        /* permission checks */
        if (((cmd & 0x40) && !(filp->f_mode & 2)) ||
-           ((cmd & 0x80) && !suser()))
+           ((cmd & 0x80) && !capable(CAP_SYS_ADMIN)))
                return -EPERM;
 
        /* copyin */
@@ -4299,23+4305,14 @@ static int floppy_grab_irq_and_dma(void)
 
        for (fdc=0; fdc< N_FDC; fdc++){
                if (FDCS->address != -1){
-                       if (check_region(FDCS->address, 6) < 0 ||
-                           check_region(FDCS->address+7, 1) < 0) {
+                       if (!request_region(FDCS->address, 6, "floppy")) {
                                DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address);
-                               fd_free_irq();
-                               fd_free_dma();
-                               while(--fdc >= 0) {
-                                       release_region(FDCS->address, 6);
-                                       release_region(FDCS->address+7, 1);
-                               }
-                               MOD_DEC_USE_COUNT;
-                               spin_lock_irqsave(&floppy_usage_lock, flags);
-                               usage_count--;
-                               spin_unlock_irqrestore(&floppy_usage_lock, flags);
-                               return -1;
+                               goto cleanup1;
+                       }
+                       if (!request_region(FDCS->address + 7, 1, "floppy DIR")) {
+                               DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + 7);
+                               goto cleanup2;
                        }
-                       request_region(FDCS->address, 6, "floppy");
-                       request_region(FDCS->address+7, 1, "floppy DIR");
                        /* address + 6 is reserved, and may be taken by IDE.
                         * Unfortunately, Adaptec doesn't know this :-(, */
                }
@@ -4339,6+4336,20 @@ static int floppy_grab_irq_and_dma(void)
        fdc = 0;
        irqdma_allocated = 1;
        return 0;
+cleanup2:
+       release_region(FDCS->address, 6);
+cleanup1:
+       fd_free_irq();
+       fd_free_dma();
+       while(--fdc >= 0) {
+               release_region(FDCS->address, 6);
+               release_region(FDCS->address + 7, 1);
+       }
+       MOD_DEC_USE_COUNT;
+       spin_lock_irqsave(&floppy_usage_lock, flags);
+       usage_count--;
+       spin_unlock_irqrestore(&floppy_usage_lock, flags);
+       return -1;
 }
 
 static void floppy_release_irq_and_dma(void)
index eb99582..4fe04fb 100644 (file)
@@ -1406,6+1406,818 @@ XORBLOCK_TEMPLATE(SPARC)
 }
 #endif /* __sparc_v[78]__ */
 
+#ifdef __alpha__
+/*
+ * High speed xor_block operation for RAID4/5 pipelined for Alpha EV5.
+ * There is a second version using EV6 prefetch instructions.
+ *
+ * Copyright (C) 2000 Richard Henderson (rth@redhat.com)
+ */
+
+XORBLOCK_TEMPLATE(alpha)
+{
+       long lines = bh_ptr[0]->b_size / sizeof (long) / 8;
+       long *d = (long *) bh_ptr[0]->b_data;
+       long *s1 = (long *) bh_ptr[1]->b_data;
+       long *s2, *s3, *s4;
+
+       if (count == 2) goto two_blocks;
+
+       s2 = (long *) bh_ptr[2]->b_data;
+       if (count == 3) goto three_blocks;
+
+       s3 = (long *) bh_ptr[3]->b_data;
+       if (count == 4) goto four_blocks;
+
+       s4 = (long *) bh_ptr[4]->b_data;
+       goto five_blocks;
+
+two_blocks:
+asm volatile ("
+       .align 4
+2:
+       ldq $0,0(%0)
+       ldq $1,0(%1)
+       ldq $2,8(%0)
+       ldq $3,8(%1)
+
+       ldq $4,16(%0)
+       ldq $5,16(%1)
+       ldq $6,24(%0)
+       ldq $7,24(%1)
+
+       ldq $16,32(%0)
+       ldq $17,32(%1)
+       ldq $18,40(%0)
+       ldq $19,40(%1)
+
+       ldq $20,48(%0)
+       ldq $21,48(%1)
+       ldq $22,56(%0)
+       xor $0,$1,$0            # 7 cycles from $1 load
+
+       ldq $23,56(%1)
+       xor $2,$3,$2
+       stq $0,0(%0)
+       xor $4,$5,$4
+
+       stq $2,8(%0)
+       xor $6,$7,$6
+       stq $4,16(%0)
+       xor $16,$17,$16
+
+       stq $6,24(%0)
+       xor $18,$19,$18
+       stq $16,32(%0)
+       xor $20,$21,$20
+
+       stq $18,40(%0)
+       xor $22,$23,$22
+       stq $20,48(%0)
+       subq %2,1,%2
+
+       stq $22,56(%0)
+       addq %0,64,%0
+       addq %1,64,%1
+       bgt %2,2b"
+       : "=r"(d), "=r"(s1), "=r"(lines)
+       : "0"(d), "1"(s1), "2"(lines)
+       : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+         "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23");
+       return;
+
+three_blocks:
+asm volatile ("
+       .align 4
+3:
+       ldq $0,0(%0)
+       ldq $1,0(%1)
+       ldq $2,0(%2)
+       ldq $3,8(%0)
+
+       ldq $4,8(%1)
+       ldq $6,16(%0)
+       ldq $7,16(%1)
+       ldq $17,24(%0)
+
+       ldq $18,24(%1)
+       ldq $20,32(%0)
+       ldq $21,32(%1)
+       ldq $5,8(%2)
+
+       ldq $16,16(%2)
+       ldq $19,24(%2)
+       ldq $22,32(%2)
+       nop
+
+       xor $0,$1,$1            # 8 cycles from $0 load
+       xor $3,$4,$4            # 6 cycles from $4 load
+       xor $6,$7,$7            # 6 cycles from $7 load
+       xor $17,$18,$18         # 5 cycles from $18 load
+
+       xor $1,$2,$2            # 9 cycles from $2 load
+       xor $20,$21,$21         # 5 cycles from $21 load
+       stq $2,0(%0)
+       xor $4,$5,$5            # 6 cycles from $5 load
+
+       stq $5,8(%0)
+       xor $7,$16,$16          # 7 cycles from $16 load
+       stq $16,16(%0)
+       xor $18,$19,$19         # 7 cycles from $19 load
+
+       stq $19,24(%0)
+       xor $21,$22,$22         # 7 cycles from $22 load
+       stq $22,32(%0)
+       nop
+
+       ldq $0,40(%0)
+       ldq $1,40(%1)
+       ldq $3,48(%0)
+       ldq $4,48(%1)
+
+       ldq $6,56(%0)
+       ldq $7,56(%1)
+       ldq $2,40(%2)
+       ldq $5,48(%2)
+
+       ldq $16,56(%2)
+       xor $0,$1,$1            # 4 cycles from $1 load
+       xor $3,$4,$4            # 5 cycles from $4 load
+       xor $6,$7,$7            # 5 cycles from $7 load
+
+       xor $1,$2,$2            # 4 cycles from $2 load
+       xor $4,$5,$5            # 5 cycles from $5 load
+       stq $2,40(%0)
+       xor $7,$16,$16          # 4 cycles from $16 load
+
+       stq $5,48(%0)
+       subq %3,1,%3
+       stq $16,56(%0)
+       addq %2,64,%2
+
+       addq %1,64,%1
+       addq %0,64,%0
+       bgt %3,3b"
+       : "=r"(d), "=r"(s1), "=r"(s2), "=r"(lines)
+       : "0"(d), "1"(s1), "2"(s2), "3"(lines)
+       : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+         "$16", "$17", "$18", "$19", "$20", "$21", "$22");
+       return;
+
+four_blocks:
+asm volatile ("
+       .align 4
+4:
+       ldq $0,0(%0)
+       ldq $1,0(%1)
+       ldq $2,0(%2)
+       ldq $3,0(%3)
+
+       ldq $4,8(%0)
+       ldq $5,8(%1)
+       ldq $6,8(%2)
+       ldq $7,8(%3)
+
+       ldq $16,16(%0)
+       ldq $17,16(%1)
+       ldq $18,16(%2)
+       ldq $19,16(%3)
+
+       ldq $20,24(%0)
+       xor $0,$1,$1            # 6 cycles from $1 load
+       ldq $21,24(%1)
+       xor $2,$3,$3            # 6 cycles from $3 load
+
+       ldq $0,24(%2)
+       xor $1,$3,$3
+       ldq $1,24(%3)
+       xor $4,$5,$5            # 7 cycles from $5 load
+
+       stq $3,0(%0)
+       xor $6,$7,$7
+       xor $16,$17,$17         # 7 cycles from $17 load
+       xor $5,$7,$7
+
+       stq $7,8(%0)
+       xor $18,$19,$19         # 7 cycles from $19 load
+       ldq $2,32(%0)
+       xor $17,$19,$19
+
+       ldq $3,32(%1)
+       ldq $4,32(%2)
+       ldq $5,32(%3)
+       xor $20,$21,$21         # 8 cycles from $21 load
+
+       ldq $6,40(%0)
+       ldq $7,40(%1)
+       ldq $16,40(%2)
+       ldq $17,40(%3)
+
+       stq $19,16(%0)
+       xor $0,$1,$1            # 9 cycles from $1 load
+       xor $2,$3,$3            # 5 cycles from $3 load
+       xor $21,$1,$1
+
+       ldq $18,48(%0)
+       xor $4,$5,$5            # 5 cycles from $5 load
+       ldq $19,48(%1)
+       xor $3,$5,$5
+
+       ldq $20,48(%2)
+       ldq $21,48(%3)
+       ldq $0,56(%0)
+       ldq $1,56(%1)
+
+       ldq $2,56(%2)
+       xor $6,$7,$7            # 8 cycles from $6 load
+       ldq $3,56(%3)
+       xor $16,$17,$17         # 8 cycles from $17 load
+
+       xor $7,$17,$17
+       xor $18,$19,$19         # 5 cycles from $19 load
+       xor $20,$21,$21         # 5 cycles from $21 load
+       xor $19,$21,$21
+
+       stq $1,24(%0)
+       xor $0,$1,$1            # 5 cycles from $1 load
+       stq $5,32(%0)
+       xor $2,$3,$3            # 4 cycles from $3 load
+
+       stq $17,40(%0)
+       xor $1,$3,$3
+       stq $21,48(%0)
+       subq %4,1,%4
+
+       stq $3,56(%0)
+       addq %3,64,%3
+       addq %2,64,%2
+       addq %1,64,%1
+
+       addq %0,64,%0
+       bgt %4,4b"
+       : "=r"(d), "=r"(s1), "=r"(s2), "=r"(s3), "=r"(lines)
+       : "0"(d), "1"(s1), "2"(s2), "3"(s3), "4"(lines)
+       : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+         "$16", "$17", "$18", "$19", "$20", "$21");
+       return;
+
+five_blocks:
+asm volatile ("
+       ldq %0,0(%6)
+       ldq %1,8(%6)
+       ldq %2,16(%6)
+       ldq %3,24(%6)
+       ldq %4,32(%6)
+       ldq %0,%7(%0)
+       ldq %1,%7(%1)
+       ldq %2,%7(%2)
+       ldq %3,%7(%3)
+       ldq %4,%7(%4)
+       .align 4
+5:
+       ldq $0,0(%0)
+       ldq $1,0(%1)
+       ldq $2,0(%2)
+       ldq $3,0(%3)
+
+       ldq $4,0(%4)
+       ldq $5,8(%0)
+       ldq $6,8(%1)
+       ldq $7,8(%2)
+
+       ldq $16,8(%3)
+       ldq $17,8(%4)
+       ldq $18,16(%0)
+       ldq $19,16(%1)
+
+       ldq $20,16(%2)
+       xor $0,$1,$1            # 6 cycles from $1 load
+       ldq $21,16(%3)
+       xor $2,$3,$3            # 6 cycles from $3 load
+
+       ldq $0,16(%4)
+       xor $1,$3,$3
+       ldq $1,24(%0)
+       xor $3,$4,$4            # 7 cycles from $4 load
+
+       stq $4,0(%0)
+       xor $5,$6,$6            # 7 cycles from $6 load
+       xor $7,$16,$16          # 7 cycles from $16 load
+       xor $6,$17,$17          # 7 cycles from $17 load
+
+       ldq $2,24(%1)
+       xor $16,$17,$17
+       ldq $3,24(%2)
+       xor $18,$19,$19         # 8 cycles from $19 load
+
+       stq $17,8(%0)
+       xor $19,$20,$20         # 8 cycles from $20 load
+       ldq $4,24(%3)
+       xor $21,$0,$0           # 7 cycles from $0 load
+
+       ldq $5,24(%4)
+       xor $20,$0,$0
+       ldq $6,32(%0)
+       ldq $7,32(%1)
+
+       stq $0,16(%0)
+       xor $1,$2,$2            # 6 cycles from $2 load
+       ldq $16,32(%2)
+       xor $3,$4,$4            # 4 cycles from $4 load
+       
+       ldq $17,32(%3)
+       xor $2,$4,$4
+       ldq $18,32(%4)
+       ldq $19,40(%0)
+
+       ldq $20,40(%1)
+       ldq $21,40(%2)
+       ldq $0,40(%3)
+       xor $4,$5,$5            # 7 cycles from $5 load
+
+       stq $5,24(%0)
+       xor $6,$7,$7            # 7 cycles from $7 load
+       ldq $1,40(%4)
+       ldq $2,48(%0)
+
+       ldq $3,48(%1)
+       xor $7,$16,$16          # 7 cycles from $16 load
+       ldq $4,48(%2)
+       xor $17,$18,$18         # 6 cycles from $18 load
+
+       ldq $5,48(%3)
+       xor $16,$18,$18
+       ldq $6,48(%4)
+       xor $19,$20,$20         # 7 cycles from $20 load
+
+       stq $18,32(%0)
+       xor $20,$21,$21         # 8 cycles from $21 load
+       ldq $7,56(%0)
+       xor $0,$1,$1            # 6 cycles from $1 load
+
+       ldq $16,56(%1)
+       ldq $17,56(%2)
+       ldq $18,56(%3)
+       ldq $19,56(%4)
+
+       xor $21,$1,$1
+       xor $2,$3,$3            # 9 cycles from $3 load
+       xor $3,$4,$4            # 9 cycles from $4 load
+       xor $5,$6,$6            # 8 cycles from $6 load
+
+       unop
+       xor $4,$6,$6
+       xor $7,$16,$16          # 7 cycles from $16 load
+       xor $17,$18,$18         # 6 cycles from $18 load
+
+       stq $6,48(%0)
+       xor $16,$18,$18
+       subq %5,1,%5
+       xor $18,$19,$19         # 8 cycles from $19 load
+
+       stq $19,56(%0)
+       addq %4,64,%4
+       addq %3,64,%3
+       addq %2,64,%2
+
+       addq %1,64,%1
+       addq %0,64,%0
+       bgt %5,5b"
+       : "=&r"(d), "=&r"(s1), "=&r"(s2), "=&r"(s3), "=r"(s4), "=r"(lines)
+       /* ARG! We've run out of asm arguments!  We've got to reload
+          all those pointers we just loaded.  */
+       : "r"(bh_ptr), "i" (&((struct buffer_head *)0)->b_data), "5"(lines)
+       : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+         "$16", "$17", "$18", "$19", "$20", "$21");
+       return;
+}
+
+#define prefetch(base, ofs) \
+       asm("ldq $31,%2(%0)" : "=r"(base) : "0"(base), "i"(ofs))
+
+XORBLOCK_TEMPLATE(alpha_prefetch)
+{
+       long lines = bh_ptr[0]->b_size / sizeof (long) / 8;
+       long *d = (long *) bh_ptr[0]->b_data;
+       long *s1 = (long *) bh_ptr[1]->b_data;
+       long *s2, *s3, *s4;
+       long p;
+
+       p = count == 2;
+       prefetch(d, 0);
+       prefetch(s1, 0);
+       prefetch(d, 64);
+       prefetch(s1, 64);
+       prefetch(d, 128);
+       prefetch(s1, 128);
+       prefetch(d, 192);
+       prefetch(s1, 192);
+       if (p) goto two_blocks;
+
+       s2 = (long *) bh_ptr[2]->b_data;
+       p = count == 3;
+       prefetch(s2, 0);
+       prefetch(s2, 64);
+       prefetch(s2, 128);
+       prefetch(s2, 192);
+       if (p) goto three_blocks;
+
+       s3 = (long *) bh_ptr[3]->b_data;
+       p = count == 4;
+       prefetch(s3, 0);
+       prefetch(s3, 64);
+       prefetch(s3, 128);
+       prefetch(s3, 192);
+       if (p) goto four_blocks;
+
+       s4 = (long *) bh_ptr[4]->b_data;
+       prefetch(s4, 0);
+       prefetch(s4, 64);
+       prefetch(s4, 128);
+       prefetch(s4, 192);
+       goto five_blocks;
+
+two_blocks:
+asm volatile ("
+       .align 4
+2:
+       ldq $0,0(%0)
+       ldq $1,0(%1)
+       ldq $2,8(%0)
+       ldq $3,8(%1)
+
+       ldq $4,16(%0)
+       ldq $5,16(%1)
+       ldq $6,24(%0)
+       ldq $7,24(%1)
+
+       ldq $16,32(%0)
+       ldq $17,32(%1)
+       ldq $18,40(%0)
+       ldq $19,40(%1)
+
+       ldq $20,48(%0)
+       ldq $21,48(%1)
+       ldq $22,56(%0)
+       ldq $23,56(%1)
+
+       ldq $31,256(%0)
+       xor $0,$1,$0            # 8 cycles from $1 load
+       ldq $31,256(%1)
+       xor $2,$3,$2
+
+       stq $0,0(%0)
+       xor $4,$5,$4
+       stq $2,8(%0)
+       xor $6,$7,$6
+
+       stq $4,16(%0)
+       xor $16,$17,$16
+       stq $6,24(%0)
+       xor $18,$19,$18
+
+       stq $16,32(%0)
+       xor $20,$21,$20
+       stq $18,40(%0)
+       xor $22,$23,$22
+
+       stq $20,48(%0)
+       subq %2,1,%2
+       stq $22,56(%0)
+       addq %0,64,%0
+
+       addq %1,64,%1
+       bgt %2,2b"
+       : "=r"(d), "=r"(s1), "=r"(lines)
+       : "0"(d), "1"(s1), "2"(lines)
+       : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+         "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23");
+       return;
+
+three_blocks:
+asm volatile ("
+       .align 4
+3:
+       ldq $0,0(%0)
+       ldq $1,0(%1)
+       ldq $2,0(%2)
+       ldq $3,8(%0)
+
+       ldq $4,8(%1)
+       ldq $6,16(%0)
+       ldq $7,16(%1)
+       ldq $17,24(%0)
+
+       ldq $18,24(%1)
+       ldq $20,32(%0)
+       ldq $21,32(%1)
+       ldq $5,8(%2)
+
+       ldq $16,16(%2)
+       ldq $19,24(%2)
+       ldq $22,32(%2)
+       nop
+
+       xor $0,$1,$1            # 8 cycles from $0 load
+       xor $3,$4,$4            # 7 cycles from $4 load
+       xor $6,$7,$7            # 6 cycles from $7 load
+       xor $17,$18,$18         # 5 cycles from $18 load
+
+       xor $1,$2,$2            # 9 cycles from $2 load
+       xor $20,$21,$21         # 5 cycles from $21 load
+       stq $2,0(%0)
+       xor $4,$5,$5            # 6 cycles from $5 load
+
+       stq $5,8(%0)
+       xor $7,$16,$16          # 7 cycles from $16 load
+       stq $16,16(%0)
+       xor $18,$19,$19         # 7 cycles from $19 load
+
+       stq $19,24(%0)
+       xor $21,$22,$22         # 7 cycles from $22 load
+       stq $22,32(%0)
+       nop
+
+       ldq $0,40(%0)
+       ldq $1,40(%1)
+       ldq $3,48(%0)
+       ldq $4,48(%1)
+
+       ldq $6,56(%0)
+       ldq $7,56(%1)
+       ldq $2,40(%2)
+       ldq $5,48(%2)
+
+       ldq $16,56(%2)
+       ldq $31,256(%0)
+       ldq $31,256(%1)
+       ldq $31,256(%2)
+
+       xor $0,$1,$1            # 6 cycles from $1 load
+       xor $3,$4,$4            # 5 cycles from $4 load
+       xor $6,$7,$7            # 5 cycles from $7 load
+       xor $1,$2,$2            # 4 cycles from $2 load
+       
+       xor $4,$5,$5            # 5 cycles from $5 load
+       xor $7,$16,$16          # 4 cycles from $16 load
+       stq $2,40(%0)
+       subq %3,1,%3
+
+       stq $5,48(%0)
+       addq %2,64,%2
+       stq $16,56(%0)
+       addq %1,64,%1
+
+       addq %0,64,%0
+       bgt %3,3b"
+       : "=r"(d), "=r"(s1), "=r"(s2), "=r"(lines)
+       : "0"(d), "1"(s1), "2"(s2), "3"(lines)
+       : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+         "$16", "$17", "$18", "$19", "$20", "$21", "$22");
+       return;
+
+four_blocks:
+asm volatile ("
+       .align 4
+4:
+       ldq $0,0(%0)
+       ldq $1,0(%1)
+       ldq $2,0(%2)
+       ldq $3,0(%3)
+
+       ldq $4,8(%0)
+       ldq $5,8(%1)
+       ldq $6,8(%2)
+       ldq $7,8(%3)
+
+       ldq $16,16(%0)
+       ldq $17,16(%1)
+       ldq $18,16(%2)
+       ldq $19,16(%3)
+
+       ldq $20,24(%0)
+       xor $0,$1,$1            # 6 cycles from $1 load
+       ldq $21,24(%1)
+       xor $2,$3,$3            # 6 cycles from $3 load
+
+       ldq $0,24(%2)
+       xor $1,$3,$3
+       ldq $1,24(%3)
+       xor $4,$5,$5            # 7 cycles from $5 load
+
+       stq $3,0(%0)
+       xor $6,$7,$7
+       xor $16,$17,$17         # 7 cycles from $17 load
+       xor $5,$7,$7
+
+       stq $7,8(%0)
+       xor $18,$19,$19         # 7 cycles from $19 load
+       ldq $2,32(%0)
+       xor $17,$19,$19
+
+       ldq $3,32(%1)
+       ldq $4,32(%2)
+       ldq $5,32(%3)
+       xor $20,$21,$21         # 8 cycles from $21 load
+
+       ldq $6,40(%0)
+       ldq $7,40(%1)
+       ldq $16,40(%2)
+       ldq $17,40(%3)
+
+       stq $19,16(%0)
+       xor $0,$1,$1            # 9 cycles from $1 load
+       xor $2,$3,$3            # 5 cycles from $3 load
+       xor $21,$1,$1
+
+       ldq $18,48(%0)
+       xor $4,$5,$5            # 5 cycles from $5 load
+       ldq $19,48(%1)
+       xor $3,$5,$5
+
+       ldq $20,48(%2)
+       ldq $21,48(%3)
+       ldq $0,56(%0)
+       ldq $1,56(%1)
+
+       ldq $2,56(%2)
+       xor $6,$7,$7            # 8 cycles from $6 load
+       ldq $3,56(%3)
+       xor $16,$17,$17         # 8 cycles from $17 load
+
+       ldq $31,256(%0)
+       xor $7,$17,$17
+       ldq $31,256(%1)
+       xor $18,$19,$19         # 6 cycles from $19 load
+
+       ldq $31,256(%2)
+       xor $20,$21,$21         # 6 cycles from $21 load
+       ldq $31,256(%3)
+       xor $19,$21,$21
+
+       stq $1,24(%0)
+       xor $0,$1,$1            # 7 cycles from $1 load
+       stq $5,32(%0)
+       xor $2,$3,$3            # 6 cycles from $3 load
+
+       stq $17,40(%0)
+       xor $1,$3,$3
+       stq $21,48(%0)
+       subq %4,1,%4
+
+       stq $3,56(%0)
+       addq %3,64,%3
+       addq %2,64,%2
+       addq %1,64,%1
+
+       addq %0,64,%0
+       bgt %4,4b"
+       : "=r"(d), "=r"(s1), "=r"(s2), "=r"(s3), "=r"(lines)
+       : "0"(d), "1"(s1), "2"(s2), "3"(s3), "4"(lines)
+       : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+         "$16", "$17", "$18", "$19", "$20", "$21");
+       return;
+
+five_blocks:
+asm volatile ("
+       ldq %0,0(%6)
+       ldq %1,8(%6)
+       ldq %2,16(%6)
+       ldq %3,24(%6)
+       ldq %4,32(%6)
+       ldq %0,%7(%0)
+       ldq %1,%7(%1)
+       ldq %2,%7(%2)
+       ldq %3,%7(%3)
+       ldq %4,%7(%4)
+       .align 4
+5:
+       ldq $0,0(%0)
+       ldq $1,0(%1)
+       ldq $2,0(%2)
+       ldq $3,0(%3)
+
+       ldq $4,0(%4)
+       ldq $5,8(%0)
+       ldq $6,8(%1)
+       ldq $7,8(%2)
+
+       ldq $16,8(%3)
+       ldq $17,8(%4)
+       ldq $18,16(%0)
+       ldq $19,16(%1)
+
+       ldq $20,16(%2)
+       xor $0,$1,$1            # 6 cycles from $1 load
+       ldq $21,16(%3)
+       xor $2,$3,$3            # 6 cycles from $3 load
+
+       ldq $0,16(%4)
+       xor $1,$3,$3
+       ldq $1,24(%0)
+       xor $3,$4,$4            # 7 cycles from $4 load
+
+       stq $4,0(%0)
+       xor $5,$6,$6            # 7 cycles from $6 load
+       xor $7,$16,$16          # 7 cycles from $16 load
+       xor $6,$17,$17          # 7 cycles from $17 load
+
+       ldq $2,24(%1)
+       xor $16,$17,$17
+       ldq $3,24(%2)
+       xor $18,$19,$19         # 8 cycles from $19 load
+
+       stq $17,8(%0)
+       xor $19,$20,$20         # 8 cycles from $20 load
+       ldq $4,24(%3)
+       xor $21,$0,$0           # 7 cycles from $0 load
+
+       ldq $5,24(%4)
+       xor $20,$0,$0
+       ldq $6,32(%0)
+       ldq $7,32(%1)
+
+       stq $0,16(%0)
+       xor $1,$2,$2            # 6 cycles from $2 load
+       ldq $16,32(%2)
+       xor $3,$4,$4            # 4 cycles from $4 load
+       
+       ldq $17,32(%3)
+       xor $2,$4,$4
+       ldq $18,32(%4)
+       ldq $19,40(%0)
+
+       ldq $20,40(%1)
+       ldq $21,40(%2)
+       ldq $0,40(%3)
+       xor $4,$5,$5            # 7 cycles from $5 load
+
+       stq $5,24(%0)
+       xor $6,$7,$7            # 7 cycles from $7 load
+       ldq $1,40(%4)
+       ldq $2,48(%0)
+
+       ldq $3,48(%1)
+       xor $7,$16,$16          # 7 cycles from $16 load
+       ldq $4,48(%2)
+       xor $17,$18,$18         # 6 cycles from $18 load
+
+       ldq $5,48(%3)
+       xor $16,$18,$18
+       ldq $6,48(%4)
+       xor $19,$20,$20         # 7 cycles from $20 load
+
+       stq $18,32(%0)
+       xor $20,$21,$21         # 8 cycles from $21 load
+       ldq $7,56(%0)
+       xor $0,$1,$1            # 6 cycles from $1 load
+
+       ldq $16,56(%1)
+       ldq $17,56(%2)
+       ldq $18,56(%3)
+       ldq $19,56(%4)
+
+       ldq $31,256(%0)
+       xor $21,$1,$1
+       ldq $31,256(%1)
+       xor $2,$3,$3            # 9 cycles from $3 load
+
+       ldq $31,256(%2)
+       xor $3,$4,$4            # 9 cycles from $4 load
+       ldq $31,256(%3)
+       xor $5,$6,$6            # 8 cycles from $6 load
+
+       ldq $31,256(%4)
+       xor $4,$6,$6
+       xor $7,$16,$16          # 7 cycles from $16 load
+       xor $17,$18,$18         # 6 cycles from $18 load
+
+       stq $6,48(%0)
+       xor $16,$18,$18
+       subq %5,1,%5
+       xor $18,$19,$19         # 8 cycles from $19 load
+
+       stq $19,56(%0)
+       addq %4,64,%4
+       addq %3,64,%3
+       addq %2,64,%2
+
+       addq %1,64,%1
+       addq %0,64,%0
+       bgt %5,5b"
+       : "=&r"(d), "=&r"(s1), "=&r"(s2), "=&r"(s3), "=r"(s4), "=r"(lines)
+       /* ARG! We've run out of asm arguments!  We've got to reload
+          all those pointers we just loaded.  */
+       : "r"(bh_ptr), "i" (&((struct buffer_head *)0)->b_data), "5"(lines)
+       : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+         "$16", "$17", "$18", "$19", "$20", "$21");
+       return;
+}
+
+#undef prefetch
+
+#endif /* __alpha__ */
+
 #ifndef __sparc_v9__
 
 /*
@@ -1815,9+2627,22 @@ static inline void pick_fastest_function(void)
        }
 #ifdef CONFIG_X86_XMM 
        if (cpu_has_xmm) {
+               /* we force the use of the KNI xor block because it
+                       can write around l2.  we may also be able
+                       to load into the l1 only depending on how
+                       the cpu deals with a load to a line that is
+                       being prefetched.
+               */
                fastest = &t_xor_block_pIII_kni;
        }
 #endif
+#ifdef __alpha__
+       if (implver() == IMPLVER_EV6) {
+               /* Force the use of alpha_prefetch if EV6, as it
+                  is significantly faster in the cold cache case.  */
+               fastest = &t_xor_block_alpha_prefetch;
+       }
+#endif
        xor_block = fastest->xor_block;
        printk( "using fastest function: %s (%d.%03d MB/sec)\n", fastest->name,
                fastest->speed / 1000, fastest->speed % 1000);
@@ -1854,27+2679,23 @@ void calibrate_xor_block(void)
        if (cpu_has_xmm) {
                printk(KERN_INFO
                        "raid5: KNI detected, trying cache-avoiding KNI checksum routine\n");
-               /* we force the use of the KNI xor block because it
-                       can write around l2.  we may also be able
-                       to load into the l1 only depending on how
-                       the cpu deals with a load to a line that is
-                       being prefetched.
-               */
                xor_speed(&t_xor_block_pIII_kni,&b1,&b2);
        }
 #endif /* CONFIG_X86_XMM */
 
 #ifdef __i386__
-
        if (md_cpu_has_mmx()) {
                printk(KERN_INFO
                        "raid5: MMX detected, trying high-speed MMX checksum routines\n");
                xor_speed(&t_xor_block_pII_mmx,&b1,&b2);
                xor_speed(&t_xor_block_p5_mmx,&b1,&b2);
        }
-
 #endif /* __i386__ */
-       
+
+#ifdef __alpha__
+       xor_speed(&t_xor_block_alpha,&b1,&b2);
+       xor_speed(&t_xor_block_alpha_prefetch,&b1,&b2);
+#endif
        
        xor_speed(&t_xor_block_8regs,&b1,&b2);
        xor_speed(&t_xor_block_32regs,&b1,&b2);
index 4503bbf..f032a31 100644 (file)
@@ -292,10+292,10 @@ MODULE_PARM(check_media_type, "i");
 
 /* These are used to simplify getting data in from and back to user land */
 #define IOCTL_IN(arg, type, in)        \
-       copy_from_user_ret(&in, (type *) arg, sizeof in, -EFAULT)
+       copy_from_user(&in, (type *) arg, sizeof in)
 
 #define IOCTL_OUT(arg, type, out) \
-       copy_to_user_ret((type *) arg, &out, sizeof out, -EFAULT)
+       copy_to_user((type *) arg, &out, sizeof out)
 
 /* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in
    a lot of places. This macro makes the code more clear. */
@@ -1463,7+1463,8 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                cdinfo(CD_DO_IOCTL, "entering CDROMMULTISESSION\n"); 
                 if (!(cdo->capability & CDC_MULTI_SESSION))
                         return -ENOSYS;
-               IOCTL_IN(arg, struct cdrom_multisession, ms_info);
+               if (IOCTL_IN(arg, struct cdrom_multisession, ms_info))
+                       return -EFAULT;
                requested_format = ms_info.addr_format;
                if (!((requested_format == CDROM_MSF) ||
                        (requested_format == CDROM_LBA)))
@@ -1473,7+1474,8 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                        return ret;
                sanitize_format(&ms_info.addr, &ms_info.addr_format,
                                requested_format);
-               IOCTL_OUT(arg, struct cdrom_multisession, ms_info);
+               if (IOCTL_OUT(arg, struct cdrom_multisession, ms_info))
+                       return -EFAULT;
                cdinfo(CD_DO_IOCTL, "CDROMMULTISESSION successful\n"); 
                return 0;
                }
@@ -1632,7+1634,8 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                        return -ENOSYS;
                if ((ret=cdo->get_mcn(cdi, &mcn)))
                        return ret;
-               IOCTL_OUT(arg, struct cdrom_mcn, mcn);
+               if (IOCTL_OUT(arg, struct cdrom_mcn, mcn))
+                       return -EFAULT;
                cdinfo(CD_DO_IOCTL, "CDROM_GET_MCN successful\n"); 
                return 0;
                }
@@ -1717,7+1720,8 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                if (!CDROM_CAN(CDC_PLAY_AUDIO))
                        return -ENOSYS;
                /* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/ 
-               IOCTL_IN(arg, struct cdrom_subchnl, q);
+               if (IOCTL_IN(arg, struct cdrom_subchnl, q))
+                       return -EFAULT;
                requested = q.cdsc_format;
                if (!((requested == CDROM_MSF) ||
                      (requested == CDROM_LBA)))
@@ -1728,7+1732,8 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                back = q.cdsc_format; /* local copy */
                sanitize_format(&q.cdsc_absaddr, &back, requested);
                sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
-               IOCTL_OUT(arg, struct cdrom_subchnl, q);
+               if (IOCTL_OUT(arg, struct cdrom_subchnl, q))
+                       return -EFAULT;
                /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */ 
                return 0;
                }
@@ -1737,10+1742,12 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                if (!CDROM_CAN(CDC_PLAY_AUDIO))
                        return -ENOSYS;
                /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */ 
-               IOCTL_IN(arg, struct cdrom_tochdr, header);
+               if (IOCTL_IN(arg, struct cdrom_tochdr, header))
+                       return -EFAULT;
                if ((ret=cdo->audio_ioctl(cdi, cmd, &header)))
                        return ret;
-               IOCTL_OUT(arg, struct cdrom_tochdr, header);
+               if (IOCTL_OUT(arg, struct cdrom_tochdr, header))
+                       return -EFAULT;
                /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */ 
                return 0;
                }
@@ -1750,7+1757,8 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                if (!CDROM_CAN(CDC_PLAY_AUDIO))
                        return -ENOSYS;
                /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */ 
-               IOCTL_IN(arg, struct cdrom_tocentry, entry);
+               if (IOCTL_IN(arg, struct cdrom_tocentry, entry))
+                       return -EFAULT;
                requested_format = entry.cdte_format;
                if (!((requested_format == CDROM_MSF) || 
                        (requested_format == CDROM_LBA)))
@@ -1761,7+1769,8 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                        return ret;
                sanitize_format(&entry.cdte_addr,
                &entry.cdte_format, requested_format);
-               IOCTL_OUT(arg, struct cdrom_tocentry, entry);
+               if (IOCTL_OUT(arg, struct cdrom_tocentry, entry))
+                       return -EFAULT;
                /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */ 
                return 0;
                }
@@ -1770,7+1779,8 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                if (!CDROM_CAN(CDC_PLAY_AUDIO))
                        return -ENOSYS;
                cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n"); 
-               IOCTL_IN(arg, struct cdrom_msf, msf);
+               if (IOCTL_IN(arg, struct cdrom_msf, msf))
+                       return -EFAULT;
                return cdo->audio_ioctl(cdi, cmd, &msf);
                }
        case CDROMPLAYTRKIND: {
@@ -1778,7+1788,8 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                if (!CDROM_CAN(CDC_PLAY_AUDIO))
                        return -ENOSYS;
                cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n"); 
-               IOCTL_IN(arg, struct cdrom_ti, ti);
+               if (IOCTL_IN(arg, struct cdrom_ti, ti))
+                       return -EFAULT;
                CHECKAUDIO;
                return cdo->audio_ioctl(cdi, cmd, &ti);
                }
@@ -1787,7+1798,8 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                if (!CDROM_CAN(CDC_PLAY_AUDIO))
                        return -ENOSYS;
                cdinfo(CD_DO_IOCTL, "entering CDROMVOLCTRL\n"); 
-               IOCTL_IN(arg, struct cdrom_volctrl, volume);
+               if (IOCTL_IN(arg, struct cdrom_volctrl, volume))
+                       return -EFAULT;
                return cdo->audio_ioctl(cdi, cmd, &volume);
                }
        case CDROMVOLREAD: {
@@ -1797,7+1809,8 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                cdinfo(CD_DO_IOCTL, "entering CDROMVOLREAD\n"); 
                if ((ret=cdo->audio_ioctl(cdi, cmd, &volume)))
                        return ret;
-               IOCTL_OUT(arg, struct cdrom_volctrl, volume);
+               if (IOCTL_OUT(arg, struct cdrom_volctrl, volume))
+                       return -EFAULT;
                return 0;
                }
        case CDROMSTART:
@@ -1894,7+1907,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                        blocksize = CD_FRAMESIZE_RAW0;
                        break;
                }
-               IOCTL_IN(arg, struct cdrom_msf, msf);
+               if (IOCTL_IN(arg, struct cdrom_msf, msf))
+                       return -EFAULT;
                lba = msf_to_lba(msf.cdmsf_min0,msf.cdmsf_sec0,msf.cdmsf_frame0);
                /* FIXME: we need upper bound checking, too!! */
                if (lba < 0)
@@ -1933,7+1947,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                struct cdrom_read_audio ra;
                int lba, frames;
 
-               IOCTL_IN(arg, struct cdrom_read_audio, ra);
+               if (IOCTL_IN(arg, struct cdrom_read_audio, ra))
+                       return -EFAULT;
 
                if (ra.addr_format == CDROM_MSF)
                        lba = msf_to_lba(ra.addr.msf.minute,
@@ -1975,7+1990,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
        case CDROMSUBCHNL: {
                struct cdrom_subchnl q;
                u_char requested, back;
-               IOCTL_IN(arg, struct cdrom_subchnl, q);
+               if (IOCTL_IN(arg, struct cdrom_subchnl, q))
+                       return -EFAULT;
                requested = q.cdsc_format;
                if (!((requested == CDROM_MSF) ||
                      (requested == CDROM_LBA)))
@@ -1986,7+2002,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                back = q.cdsc_format; /* local copy */
                sanitize_format(&q.cdsc_absaddr, &back, requested);
                sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
-               IOCTL_OUT(arg, struct cdrom_subchnl, q);
+               if (IOCTL_OUT(arg, struct cdrom_subchnl, q))
+                       return -EFAULT;
                /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */ 
                return 0;
                }
@@ -1994,7+2011,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                struct cdrom_ti ti;
 
                cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
-               IOCTL_IN(arg, struct cdrom_ti, ti);
+               if (IOCTL_IN(arg, struct cdrom_ti, ti))
+                       return -EFAULT;
 
                cgc.cmd[0] = GPCMD_PLAY_AUDIO_TI;
                cgc.cmd[4] = ti.cdti_trk0;
@@ -2006,7+2024,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
        case CDROMPLAYMSF: {
                struct cdrom_msf msf;
                cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
-               IOCTL_IN(arg, struct cdrom_msf, msf);
+               if (IOCTL_IN(arg, struct cdrom_msf, msf))
+                       return -EFAULT;
                cgc.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
                cgc.cmd[3] = msf.cdmsf_min0;
                cgc.cmd[4] = msf.cdmsf_sec0;
@@ -2020,7+2039,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
        case CDROMPLAYBLK: {
                struct cdrom_blk blk;
                cdinfo(CD_DO_IOCTL, "entering CDROMPLAYBLK\n");
-               IOCTL_IN(arg, struct cdrom_blk, blk);
+               if (IOCTL_IN(arg, struct cdrom_blk, blk))
+                       return -EFAULT;
                cgc.cmd[0] = GPCMD_PLAY_AUDIO_10;
                cgc.cmd[2] = (blk.from >> 24) & 0xff;
                cgc.cmd[3] = (blk.from >> 16) & 0xff;
@@ -2038,7+2058,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                unsigned short offset;
                cdinfo(CD_DO_IOCTL, "entering CDROMVOLUME\n");
 
-               IOCTL_IN(arg, struct cdrom_volctrl, volctrl);
+               if (IOCTL_IN(arg, struct cdrom_volctrl, volctrl))
+                       return -EFAULT;
 
                cgc.buffer = buffer;
                cgc.buflen = 24;
@@ -2064,7+2085,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                        volctrl.channel1 = buffer[offset+11];
                        volctrl.channel2 = buffer[offset+13];
                        volctrl.channel3 = buffer[offset+15];
-                       IOCTL_OUT(arg, struct cdrom_volctrl, volctrl);
+                       if (IOCTL_OUT(arg, struct cdrom_volctrl, volctrl))
+                               return -EFAULT;
                        return 0;
                }
                
@@ -2130,10+2152,12 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                if (!CDROM_CAN(CDC_DVD))
                        return -ENOSYS;
                cdinfo(CD_DO_IOCTL, "entering DVD_AUTH\n"); 
-               IOCTL_IN(arg, dvd_authinfo, ai);
+               if (IOCTL_IN(arg, dvd_authinfo, ai))
+                       return -EFAULT;
                if ((ret = dvd_do_auth (cdi, &ai)))
                        return ret;
-               IOCTL_OUT(arg, dvd_authinfo, ai);
+               if (IOCTL_OUT(arg, dvd_authinfo, ai))
+                       return -EFAULT;
                return 0;
                }
 
@@ -2143,7+2167,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                if (!CDROM_CAN(CDC_GENERIC_PACKET))
                        return -ENOSYS;
                cdinfo(CD_DO_IOCTL, "entering CDROM_SEND_PACKET\n"); 
-               IOCTL_IN(arg, struct cdrom_generic_command, cgc);
+               if (IOCTL_IN(arg, struct cdrom_generic_command, cgc))
+                       return -EFAULT;
                copy = !!cgc.buflen;
                userbuf = cgc.buffer;
                cgc.buffer = NULL;
@@ -2190,7+2215,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                cdinfo(CD_DO_IOCTL, "entering CDROM_NEXT_WRITABLE\n"); 
                if ((ret = cdrom_get_next_writable(dev, &next)))
                        return ret;
-               IOCTL_OUT(arg, long, next);
+               if (IOCTL_OUT(arg, long, next))
+                       return -EFAULT;
                return 0;
                }
        case CDROM_LAST_WRITTEN: {
@@ -2198,7+2224,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                cdinfo(CD_DO_IOCTL, "entering CDROM_LAST_WRITTEN\n"); 
                if ((ret = cdrom_get_last_written(dev, &last)))
                        return ret;
-               IOCTL_OUT(arg, long, last);
+               if (IOCTL_OUT(arg, long, last))
+                       return -EFAULT;
                return 0;
                }
        } /* switch */
index 42a1bc2..24fd59c 100644 (file)
@@ -95,7+95,8 @@ int drm_agp_info(struct inode *inode, struct file *filp, unsigned int cmd,
        info.id_vendor         = kern->device->vendor;
        info.id_device         = kern->device->device;
 
-       copy_to_user_ret((drm_agp_info_t *)arg, &info, sizeof(info), -EFAULT);
+       if (copy_to_user((drm_agp_info_t *)arg, &info, sizeof(info)))
+               return -EFAULT;
        return 0;
 }
 
@@ -134,8+135,8 @@ int drm_agp_enable(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dev->agp->acquired || !drm_agp.enable) return -EINVAL;
 
-       copy_from_user_ret(&mode, (drm_agp_mode_t *)arg, sizeof(mode),
-                          -EFAULT);
+       if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode)))
+               return -EFAULT;
        
        dev->agp->mode    = mode.mode;
        (*drm_agp.enable)(mode.mode);
@@ -155,8+156,8 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
        unsigned long    pages;
        u32              type;
        if (!dev->agp->acquired) return -EINVAL;
-       copy_from_user_ret(&request, (drm_agp_buffer_t *)arg, sizeof(request),
-                          -EFAULT);
+       if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
+               return -EFAULT;
        if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
                return -ENOMEM;
    
@@ -212,8+213,8 @@ int drm_agp_unbind(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_agp_mem_t     *entry;
 
        if (!dev->agp->acquired) return -EINVAL;
-       copy_from_user_ret(&request, (drm_agp_binding_t *)arg, sizeof(request),
-                          -EFAULT);
+       if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
+               return -EFAULT;
        if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
                return -EINVAL;
        if (!entry->bound) return -EINVAL;
@@ -231,8+232,8 @@ int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd,
        int               page;
        
        if (!dev->agp->acquired || !drm_agp.bind_memory) return -EINVAL;
-       copy_from_user_ret(&request, (drm_agp_binding_t *)arg, sizeof(request),
-                          -EFAULT);
+       if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
+               return -EFAULT;
        if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
                return -EINVAL;
        if (entry->bound) return -EINVAL;
@@ -253,8+254,8 @@ int drm_agp_free(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_agp_mem_t    *entry;
        
        if (!dev->agp->acquired) return -EINVAL;
-       copy_from_user_ret(&request, (drm_agp_buffer_t *)arg, sizeof(request),
-                          -EFAULT);
+       if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
+               return -EFAULT;
        if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
                return -EINVAL;
        if (entry->bound) drm_unbind_agp(entry->memory);
index 4556bd9..80bb4b6 100644 (file)
@@ -137,7+137,8 @@ int drm_getmagic(struct inode *inode, struct file *filp, unsigned int cmd,
        }
        
        DRM_DEBUG("%u\n", auth.magic);
-       copy_to_user_ret((drm_auth_t *)arg, &auth, sizeof(auth), -EFAULT);
+       if (copy_to_user((drm_auth_t *)arg, &auth, sizeof(auth)))
+               return -EFAULT;
        return 0;
 }
 
@@ -149,7+150,8 @@ int drm_authmagic(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_auth_t         auth;
        drm_file_t         *file;
 
-       copy_from_user_ret(&auth, (drm_auth_t *)arg, sizeof(auth), -EFAULT);
+       if (copy_from_user(&auth, (drm_auth_t *)arg, sizeof(auth)))
+               return -EFAULT;
        DRM_DEBUG("%u\n", auth.magic);
        if ((file = drm_find_file(dev, auth.magic))) {
                file->authenticated = 1;
index c00f051..28e0eb5 100644 (file)
@@ -133,12+133,13 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
        dev->maplist[dev->map_count-1] = map;
        up(&dev->struct_sem);
 
-       copy_to_user_ret((drm_map_t *)arg, map, sizeof(*map), -EFAULT);
+       if (copy_to_user((drm_map_t *)arg, map, sizeof(*map)))
+               return -EFAULT;
        if (map->type != _DRM_SHM) {
-               copy_to_user_ret(&((drm_map_t *)arg)->handle,
+               if (copy_to_user(&((drm_map_t *)arg)->handle,
                                 &map->offset,
-                                sizeof(map->offset),
-                                -EFAULT);
+                                sizeof(map->offset)))
+                       return -EFAULT;
        }               
        return 0;
 }
@@ -166,10+167,10 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dma) return -EINVAL;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_desc_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        count      = request.count;
        order      = drm_order(request.size);
@@ -295,10+296,10 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
        request.count = entry->buf_count;
        request.size  = size;
 
-       copy_to_user_ret((drm_buf_desc_t *)arg,
+       if (copy_to_user((drm_buf_desc_t *)arg,
                         &request,
-                        sizeof(request),
-                        -EFAULT);
+                        sizeof(request)))
+               return -EFAULT;
        
        atomic_dec(&dev->buf_alloc);
        return 0;
@@ -324,10+325,10 @@ int drm_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
        ++dev->buf_use;         /* Can't allocate more after this call */
        spin_unlock(&dev->count_lock);
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_info_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
                if (dma->bufs[i].buf_count) ++count;
@@ -338,28+339,26 @@ int drm_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
        if (request.count >= count) {
                for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
                        if (dma->bufs[i].buf_count) {
-                               copy_to_user_ret(&request.list[count].count,
+                               if (copy_to_user(&request.list[count].count,
                                                 &dma->bufs[i].buf_count,
                                                 sizeof(dma->bufs[0]
-                                                       .buf_count),
-                                                -EFAULT);
-                               copy_to_user_ret(&request.list[count].size,
+                                                       .buf_count)) ||
+                                   copy_to_user(&request.list[count].size,
                                                 &dma->bufs[i].buf_size,
-                                                sizeof(dma->bufs[0].buf_size),
-                                                -EFAULT);
-                               copy_to_user_ret(&request.list[count].low_mark,
+                                                sizeof(dma->bufs[0].buf_size)) ||
+                                   copy_to_user(&request.list[count].low_mark,
                                                 &dma->bufs[i]
                                                 .freelist.low_mark,
                                                 sizeof(dma->bufs[0]
-                                                       .freelist.low_mark),
-                                                -EFAULT);
-                               copy_to_user_ret(&request.list[count]
+                                                       .freelist.low_mark)) ||
+                                   copy_to_user(&request.list[count]
                                                 .high_mark,
                                                 &dma->bufs[i]
                                                 .freelist.high_mark,
                                                 sizeof(dma->bufs[0]
-                                                       .freelist.high_mark),
-                                                -EFAULT);
+                                                       .freelist.high_mark)))
+                                       return -EFAULT;
+
                                DRM_DEBUG("%d %d %d %d %d\n",
                                          i,
                                          dma->bufs[i].buf_count,
@@ -372,10+371,10 @@ int drm_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
        }
        request.count = count;
 
-       copy_to_user_ret((drm_buf_info_t *)arg,
+       if (copy_to_user((drm_buf_info_t *)arg,
                         &request,
-                        sizeof(request),
-                        -EFAULT);
+                        sizeof(request)))
+               return -EFAULT;
        
        return 0;
 }
@@ -392,10+391,10 @@ int drm_markbufs(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dma) return -EINVAL;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_desc_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        DRM_DEBUG("%d, %d, %d\n",
                  request.size, request.low_mark, request.high_mark);
@@ -427,17+426,17 @@ int drm_freebufs(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dma) return -EINVAL;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_free_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        DRM_DEBUG("%d\n", request.count);
        for (i = 0; i < request.count; i++) {
-               copy_from_user_ret(&idx,
+               if (copy_from_user(&idx,
                                   &request.list[i],
-                                  sizeof(idx),
-                                  -EFAULT);
+                                  sizeof(idx)))
+                       return -EFAULT;
                if (idx < 0 || idx >= dma->buf_count) {
                        DRM_ERROR("Index %d (of %d max)\n",
                                  idx, dma->buf_count - 1);
@@ -480,10+479,10 @@ int drm_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
        ++dev->buf_use;         /* Can't allocate more after this call */
        spin_unlock(&dev->count_lock);
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_map_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        if (request.count >= dma->buf_count) {
                down(&current->mm->mmap_sem);
@@ -529,10+528,10 @@ done:
        request.count = dma->buf_count;
        DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
 
-       copy_to_user_ret((drm_buf_map_t *)arg,
+       if (copy_to_user((drm_buf_map_t *)arg,
                         &request,
-                        sizeof(request),
-                        -EFAULT);
+                        sizeof(request)))
+               return -EFAULT;
 
        return retcode;
 }
index ca49109..933fd0c 100644 (file)
@@ -129,19+129,21 @@ int drm_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
        int             i;
 
        DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
-       copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
+       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
+               return -EFAULT;
        if (res.count >= DRM_RESERVED_CONTEXTS) {
                memset(&ctx, 0, sizeof(ctx));
                for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
                        ctx.handle = i;
-                       copy_to_user_ret(&res.contexts[i],
+                       if (copy_to_user(&res.contexts[i],
                                         &i,
-                                        sizeof(i),
-                                        -EFAULT);
+                                        sizeof(i)))
+                               return -EFAULT;
                }
        }
        res.count = DRM_RESERVED_CONTEXTS;
-       copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT);
+       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
+               return -EFAULT;
        return 0;
 }
 
@@ -153,7+155,8 @@ int drm_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        if ((ctx.handle = drm_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
                                /* Init kernel's context and get a new one. */
                drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx);
@@ -161,7+164,8 @@ int drm_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
        }
        drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx);
        DRM_DEBUG("%d\n", ctx.handle);
-       copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
+       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
        return 0;
 }
 
@@ -173,7+177,8 @@ int drm_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_ctx_t       ctx;
        drm_queue_t     *q;
                
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        
        DRM_DEBUG("%d\n", ctx.handle);
        
@@ -206,7+211,8 @@ int drm_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_ctx_t       ctx;
        drm_queue_t     *q;
                
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        
        DRM_DEBUG("%d\n", ctx.handle);
        
@@ -223,7+229,8 @@ int drm_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
        ctx.flags = q->flags;
        atomic_dec(&q->use_count);
        
-       copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
+       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
        
        return 0;
 }
@@ -235,7+242,8 @@ int drm_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        return drm_context_switch(dev, dev->last_context, ctx.handle);
 }
@@ -247,7+255,8 @@ int drm_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        drm_context_switch_complete(dev, ctx.handle);
 
@@ -263,7+272,8 @@ int drm_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_queue_t     *q;
        drm_buf_t       *buf;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        
        if (ctx.handle >= dev->queue_count) return -EINVAL;
index ac2d1bc..6234017 100644 (file)
@@ -486,14+486,16 @@ static int drm_dma_get_buffers_of_order(drm_device_t *dev, drm_dma_t *d,
                                  buf->pending);
                }
                buf->pid     = current->pid;
-               copy_to_user_ret(&d->request_indices[i],
+               if (copy_to_user(&d->request_indices[i],
                                 &buf->idx,
-                                sizeof(buf->idx),
-                                -EFAULT);
-               copy_to_user_ret(&d->request_sizes[i],
+                                sizeof(buf->idx)))
+                       return -EFAULT;
+
+               if (copy_to_user(&d->request_sizes[i],
                                 &buf->total,
-                                sizeof(buf->total),
-                                -EFAULT);
+                                sizeof(buf->total)))
+                       return -EFAULT;
+
                ++d->granted_count;
        }
        return 0;
index 03839f5..1328054 100644 (file)
@@ -39,7+39,8 @@ int drm_adddraw(struct inode *inode, struct file *filp, unsigned int cmd,
 
        draw.handle = 0;        /* NOOP */
        DRM_DEBUG("%d\n", draw.handle);
-       copy_to_user_ret((drm_draw_t *)arg, &draw, sizeof(draw), -EFAULT);
+       if (copy_to_user((drm_draw_t *)arg, &draw, sizeof(draw)))
+               return -EFAULT;
        return 0;
 }
 
index e8ec9bd..d6de193 100644 (file)
 #include <linux/types.h>
 #include <linux/agp_backend.h>
 #endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
+#if LINUX_VERSION_CODE >= 0x020100 /* KERNEL_VERSION(2,1,0) */
 #include <linux/tqueue.h>
 #include <linux/poll.h>
 #endif
+#if LINUX_VERSION_CODE < 0x020400
+#include "compat-pre24.h"
+#endif
 #include "drm.h"
 
 #define DRM_DEBUG_CODE 2         /* Include debugging code (if > 1, then
@@ -140,11+143,6 @@ typedef struct wait_queue *wait_queue_head_t;
 #define module_exit(x)  void cleanup_module(void) { x(); }
 #endif
 
-                               /* virt_to_page added in 2.4.0-test6 */
-#if LINUX_VERSION_CODE < 0x020400
-#define virt_to_page(kaddr) (mem_map + MAP_NR(kaddr))
-#endif
-
                                /* Generic cmpxchg added in 2.3.x */
 #ifndef __HAVE_ARCH_CMPXCHG
                                /* Include this here so that driver can be
index a10b598..4e8b29b 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: ffb_context.c,v 1.3 2000/06/09 03:46:53 davem Exp $
+/* $Id: ffb_context.c,v 1.4 2000/08/29 07:01:55 davem Exp $
  * ffb_context.c: Creator/Creator3D DRI/DRM context switching.
  *
  * Copyright (C) 2000 David S. Miller (davem@redhat.com)
@@ -389,19+389,21 @@ int ffb_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
        int             i;
 
        DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
-       copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
+       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
+               return -EFAULT;
        if (res.count >= DRM_RESERVED_CONTEXTS) {
                memset(&ctx, 0, sizeof(ctx));
                for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
                        ctx.handle = i;
-                       copy_to_user_ret(&res.contexts[i],
+                       if (copy_to_user(&res.contexts[i],
                                         &i,
-                                        sizeof(i),
-                                        -EFAULT);
+                                        sizeof(i)))
+                               return -EFAULT;
                }
        }
        res.count = DRM_RESERVED_CONTEXTS;
-       copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT);
+       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
+               return -EFAULT;
        return 0;
 }
 
@@ -414,14+416,16 @@ int ffb_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_ctx_t       ctx;
        int idx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        idx = ffb_alloc_queue(dev, (ctx.flags & _DRM_CONTEXT_2DONLY));
        if (idx < 0)
                return -ENFILE;
 
        DRM_DEBUG("%d\n", ctx.handle);
        ctx.handle = idx;
-       copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
+       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
        return 0;
 }
 
@@ -435,7+439,8 @@ int ffb_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_ctx_t ctx;
        int idx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
+               return -EFAULT;
 
        idx = ctx.handle;
        if (idx <= 0 || idx >= FFB_MAX_CTXS)
@@ -463,7+468,8 @@ int ffb_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_ctx_t ctx;
        int idx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
+               return -EFAULT;
 
        idx = ctx.handle;
        if (idx <= 0 || idx >= FFB_MAX_CTXS)
@@ -478,7+484,8 @@ int ffb_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
        else
                ctx.flags = 0;
 
-       copy_to_user_ret((drm_ctx_t*)arg, &ctx, sizeof(ctx), -EFAULT);
+       if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
 
        return 0;
 }
@@ -490,7+497,8 @@ int ffb_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        return ffb_context_switch(dev, dev->last_context, ctx.handle);
 }
@@ -500,7+508,8 @@ int ffb_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
 {
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
 
        return 0;
@@ -515,7+524,8 @@ int ffb_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
        ffb_dev_priv_t  *fpriv  = (ffb_dev_priv_t *) (dev + 1);
        int idx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
 
        idx = ctx.handle - 1;
index f3966d9..8e373e5 100644 (file)
@@ -176,7+176,8 @@ ssize_t drm_read(struct file *filp, char *buf, size_t count, loff_t *off)
                } else {
                        cur = DRM_MIN(send, dev->buf_end - dev->buf_rp);
                }
-               copy_to_user_ret(buf, dev->buf_rp, cur, -EINVAL);
+               if (copy_to_user(buf, dev->buf_rp, cur))
+                       return -EFAULT;
                dev->buf_rp += cur;
                if (dev->buf_rp == dev->buf_end) dev->buf_rp = dev->buf;
                send -= cur;
index a99f24c..7943338 100644 (file)
@@ -586,7+586,8 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd,
        int               retcode   = 0;
        drm_dma_t         d;
 
-       copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT);
+       if (copy_from_user(&d, (drm_dma_t *)arg, sizeof(d)))
+               return -EFAULT;
        DRM_DEBUG("%d %d: %d send, %d req\n",
                  current->pid, d.context, d.send_count, d.request_count);
 
@@ -621,7+622,8 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd,
 
        DRM_DEBUG("%d returning, granted = %d\n",
                  current->pid, d.granted_count);
-       copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT);
+       if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d)))
+               return -EFAULT;
 
        return retcode;
 }
@@ -710,7+712,8 @@ int gamma_control(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_control_t   ctl;
        int             retcode;
        
-       copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT);
+       if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))
+               return -EFAULT;
        
        switch (ctl.func) {
        case DRM_INST_HANDLER:
@@ -742,7+745,8 @@ int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd,
        dev->lck_start = start = get_cycles();
 #endif
 
-       copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
 
        if (lock.context == DRM_KERNEL_CONTEXT) {
                DRM_ERROR("Process %d using kernel context %d\n",
@@ -804,6+808,15 @@ int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_flush_unblock(dev, lock.context, lock.flags); /* cleanup phase */
        
        if (!ret) {
+               sigemptyset(&dev->sigmask);
+               sigaddset(&dev->sigmask, SIGSTOP);
+               sigaddset(&dev->sigmask, SIGTSTP);
+               sigaddset(&dev->sigmask, SIGTTIN);
+               sigaddset(&dev->sigmask, SIGTTOU);
+               dev->sigdata.context = lock.context;
+               dev->sigdata.lock    = dev->lock.hw_lock;
+               block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
+
                if (lock.flags & _DRM_LOCK_READY)
                        gamma_dma_ready(dev);
                if (lock.flags & _DRM_LOCK_QUIESCENT) {
index 13d37c2..030122f 100644 (file)
@@ -405,17+405,18 @@ int gamma_version(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_version_t version;
        int           len;
 
-       copy_from_user_ret(&version,
+       if (copy_from_user(&version,
                           (drm_version_t *)arg,
-                          sizeof(version),
-                          -EFAULT);
+                          sizeof(version)))
+               return -EFAULT;
 
 #define DRM_COPY(name,value)                                \
        len = strlen(value);                                 \
        if (len > name##_len) len = name##_len;              \
        name##_len = strlen(value);                          \
        if (len && name) {                                   \
-               copy_to_user_ret(name, value, len, -EFAULT); \
+               if (copy_to_user(name, value, len))          \
+                       return -EFAULT;                      \
        }
 
        version.version_major      = GAMMA_MAJOR;
@@ -426,10+427,10 @@ int gamma_version(struct inode *inode, struct file *filp, unsigned int cmd,
        DRM_COPY(version.date, GAMMA_DATE);
        DRM_COPY(version.desc, GAMMA_DESC);
 
-       copy_to_user_ret((drm_version_t *)arg,
+       if (copy_to_user((drm_version_t *)arg,
                         &version,
-                        sizeof(version),
-                        -EFAULT);
+                        sizeof(version)))
+               return -EFAULT;
        return 0;
 }
 
@@ -537,7+538,8 @@ int gamma_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t      *dev    = priv->dev;
        drm_lock_t        lock;
 
-       copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
        
        if (lock.context == DRM_KERNEL_CONTEXT) {
                DRM_ERROR("Process %d using kernel context %d\n",
@@ -564,5+566,6 @@ int gamma_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
                                                       - dev->lck_start)]);
 #endif
        
+       unblock_all_signals();
        return 0;
 }
index fa1f84d..a999e96 100644 (file)
@@ -56,10+56,10 @@ int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dma) return -EINVAL;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_desc_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        count = request.count;
        order = drm_order(request.size);
@@ -155,10+155,10 @@ int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
        request.count = entry->buf_count;
        request.size  = size;
    
-       copy_to_user_ret((drm_buf_desc_t *)arg,
+       if (copy_to_user((drm_buf_desc_t *)arg,
                         &request,
-                        sizeof(request),
-                        -EFAULT);
+                        sizeof(request)))
+               return -EFAULT;
    
        atomic_dec(&dev->buf_alloc);
        dma->flags = _DRM_DMA_USE_AGP;
@@ -170,10+170,10 @@ int i810_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
 {
        drm_buf_desc_t   request;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_desc_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        if(request.flags & _DRM_AGP_BUFFER)
                return i810_addbufs_agp(inode, filp, cmd, arg);
@@ -201,10+201,10 @@ int i810_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
        ++dev->buf_use;         /* Can't allocate more after this call */
        spin_unlock(&dev->count_lock);
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_info_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
                if (dma->bufs[i].buf_count) ++count;
@@ -215,28+215,26 @@ int i810_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
        if (request.count >= count) {
                for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
                        if (dma->bufs[i].buf_count) {
-                               copy_to_user_ret(&request.list[count].count,
+                               if (copy_to_user(&request.list[count].count,
                                                 &dma->bufs[i].buf_count,
                                                 sizeof(dma->bufs[0]
-                                                       .buf_count),
-                                                -EFAULT);
-                               copy_to_user_ret(&request.list[count].size,
+                                                       .buf_count)) ||
+                                   copy_to_user(&request.list[count].size,
                                                 &dma->bufs[i].buf_size,
-                                                sizeof(dma->bufs[0].buf_size),
-                                                -EFAULT);
-                               copy_to_user_ret(&request.list[count].low_mark,
+                                                sizeof(dma->bufs[0].buf_size)) ||
+                                   copy_to_user(&request.list[count].low_mark,
                                                 &dma->bufs[i]
                                                 .freelist.low_mark,
                                                 sizeof(dma->bufs[0]
-                                                       .freelist.low_mark),
-                                                -EFAULT);
-                               copy_to_user_ret(&request.list[count]
+                                                       .freelist.low_mark)) ||
+                                   copy_to_user(&request.list[count]
                                                 .high_mark,
                                                 &dma->bufs[i]
                                                 .freelist.high_mark,
                                                 sizeof(dma->bufs[0]
-                                                       .freelist.high_mark),
-                                                -EFAULT);
+                                                       .freelist.high_mark)))
+                                       return -EFAULT;
+
                                DRM_DEBUG("%d %d %d %d %d\n",
                                          i,
                                          dma->bufs[i].buf_count,
@@ -249,10+247,10 @@ int i810_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
        }
        request.count = count;
 
-       copy_to_user_ret((drm_buf_info_t *)arg,
+       if (copy_to_user((drm_buf_info_t *)arg,
                         &request,
-                        sizeof(request),
-                        -EFAULT);
+                        sizeof(request)))
+               return -EFAULT;
        
        return 0;
 }
@@ -269,10+267,10 @@ int i810_markbufs(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dma) return -EINVAL;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_desc_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        DRM_DEBUG("%d, %d, %d\n",
                  request.size, request.low_mark, request.high_mark);
@@ -304,17+302,17 @@ int i810_freebufs(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dma) return -EINVAL;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_free_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        DRM_DEBUG("%d\n", request.count);
        for (i = 0; i < request.count; i++) {
-               copy_from_user_ret(&idx,
+               if (copy_from_user(&idx,
                                   &request.list[i],
-                                  sizeof(idx),
-                                  -EFAULT);
+                                  sizeof(idx)))
+                       return -EFAULT;
                if (idx < 0 || idx >= dma->buf_count) {
                        DRM_ERROR("Index %d (of %d max)\n",
                                  idx, dma->buf_count - 1);
index 85c0877..c331bee 100644 (file)
@@ -103,19+103,21 @@ int i810_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
        int             i;
 
        DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
-       copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
+       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
+               return -EFAULT;
        if (res.count >= DRM_RESERVED_CONTEXTS) {
                memset(&ctx, 0, sizeof(ctx));
                for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
                        ctx.handle = i;
-                       copy_to_user_ret(&res.contexts[i],
+                       if (copy_to_user(&res.contexts[i],
                                         &i,
-                                        sizeof(i),
-                                        -EFAULT);
+                                        sizeof(i)))
+                               return -EFAULT;
                }
        }
        res.count = DRM_RESERVED_CONTEXTS;
-       copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT);
+       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
+               return -EFAULT;
        return 0;
 }
 
@@ -126,7+128,8 @@ int i810_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        if ((ctx.handle = i810_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
                                /* Skip kernel's context and get a new one. */
                ctx.handle = i810_alloc_queue(dev);
@@ -137,7+140,8 @@ int i810_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
                return -ENOMEM;
        }
        DRM_DEBUG("%d\n", ctx.handle);
-       copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
+       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
        return 0;
 }
 
@@ -153,10+157,12 @@ int i810_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
 {
        drm_ctx_t ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
+               return -EFAULT;
        /* This is 0, because we don't hanlde any context flags */
        ctx.flags = 0;
-       copy_to_user_ret((drm_ctx_t*)arg, &ctx, sizeof(ctx), -EFAULT);
+       if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
        return 0;
 }
 
@@ -167,7+173,8 @@ int i810_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        return i810_context_switch(dev, dev->last_context, ctx.handle);
 }
@@ -179,7+186,8 @@ int i810_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        i810_context_switch_complete(dev, ctx.handle);
 
@@ -193,7+201,8 @@ int i810_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        if(ctx.handle != DRM_KERNEL_CONTEXT) {
                drm_ctxbitmap_free(dev, ctx.handle);
index 19b7bd9..e2a8660 100644 (file)
@@ -490,8+490,8 @@ int i810_dma_init(struct inode *inode, struct file *filp,
        drm_i810_init_t init;
        int retcode = 0;
        
-       copy_from_user_ret(&init, (drm_i810_init_t *)arg, 
-                          sizeof(init), -EFAULT);
+       if (copy_from_user(&init, (drm_i810_init_t *)arg, sizeof(init)))
+               return -EFAULT;
        
        switch(init.func) {
                case I810_INIT_DMA:
@@ -1005,7+1005,8 @@ int i810_control(struct inode *inode, struct file *filp, unsigned int cmd,
    
        DRM_DEBUG(  "i810_control\n");
 
-       copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT);
+       if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))
+               return -EFAULT;
        
        switch (ctl.func) {
        case DRM_INST_HANDLER:
@@ -1178,7+1179,8 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
        int               ret   = 0;
        drm_lock_t        lock;
 
-       copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
 
        if (lock.context == DRM_KERNEL_CONTEXT) {
                DRM_ERROR("Process %d using kernel context %d\n",
@@ -1227,6+1229,15 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
        }
        
        if (!ret) {
+               sigemptyset(&dev->sigmask);
+               sigaddset(&dev->sigmask, SIGSTOP);
+               sigaddset(&dev->sigmask, SIGTSTP);
+               sigaddset(&dev->sigmask, SIGTTIN);
+               sigaddset(&dev->sigmask, SIGTTOU);
+               dev->sigdata.context = lock.context;
+               dev->sigdata.lock    = dev->lock.hw_lock;
+               block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
+
                if (lock.flags & _DRM_LOCK_QUIESCENT) {
                   DRM_DEBUG("_DRM_LOCK_QUIESCENT\n");
                   DRM_DEBUG("fred\n");
@@ -1266,8+1277,8 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
                                        dev_priv->sarea_priv; 
        drm_i810_vertex_t vertex;
 
-       copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex),
-                          -EFAULT);
+       if (copy_from_user(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex)))
+               return -EFAULT;
 
        if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
                DRM_ERROR("i810_dma_vertex called without lock held\n");
@@ -1298,8+1309,8 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
        drm_device_t *dev = priv->dev;
        drm_i810_clear_t clear;
 
-       copy_from_user_ret(&clear, (drm_i810_clear_t *)arg, sizeof(clear), 
-                          -EFAULT);
+       if (copy_from_user(&clear, (drm_i810_clear_t *)arg, sizeof(clear)))
+               return -EFAULT;
    
        if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
                DRM_ERROR("i810_clear_bufs called without lock held\n");
@@ -1356,7+1367,8 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
                                        dev_priv->sarea_priv; 
 
        DRM_DEBUG("getbuf\n");
-       copy_from_user_ret(&d, (drm_i810_dma_t *)arg, sizeof(d), -EFAULT);
+       if (copy_from_user(&d, (drm_i810_dma_t *)arg, sizeof(d)))
+               return -EFAULT;
    
        if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
                DRM_ERROR("i810_dma called without lock held\n");
@@ -1370,7+1382,8 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
        DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
                  current->pid, retcode, d.granted);
 
-       copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT);   
+       if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d)))
+               return -EFAULT;
        sarea_priv->last_dispatch = (int) hw_status[5];
 
        return retcode;
@@ -1395,14+1408,16 @@ int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd,
                return -EINVAL;
        }
    
-       copy_from_user_ret(&d, (drm_i810_copy_t *)arg, sizeof(d), -EFAULT);
+       if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d)))
+               return -EFAULT;
 
        if(d.idx > dma->buf_count) return -EINVAL;
        buf = dma->buflist[ d.idx ];
        buf_priv = buf->dev_private;
        if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM;
 
-       copy_from_user_ret(buf_priv->virtual, d.address, d.used, -EFAULT);
+       if (copy_from_user(buf_priv->virtual, d.address, d.used))
+               return -EFAULT;
 
        sarea_priv->last_dispatch = (int) hw_status[5];
 
index 275663a..6bef56a 100644 (file)
@@ -428,17+428,18 @@ int i810_version(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_version_t version;
        int           len;
 
-       copy_from_user_ret(&version,
+       if (copy_from_user(&version,
                           (drm_version_t *)arg,
-                          sizeof(version),
-                          -EFAULT);
+                          sizeof(version)))
+               return -EFAULT;
 
 #define DRM_COPY(name,value)                                \
        len = strlen(value);                                 \
        if (len > name##_len) len = name##_len;              \
        name##_len = strlen(value);                          \
        if (len && name) {                                   \
-               copy_to_user_ret(name, value, len, -EFAULT); \
+               if (copy_to_user(name, value, len, -EFAULT)) \
+                       return -EFAULT;                      \
        }
 
        version.version_major      = I810_MAJOR;
@@ -449,10+450,10 @@ int i810_version(struct inode *inode, struct file *filp, unsigned int cmd,
        DRM_COPY(version.date, I810_DATE);
        DRM_COPY(version.desc, I810_DESC);
 
-       copy_to_user_ret((drm_version_t *)arg,
+       if (copy_to_user((drm_version_t *)arg,
                         &version,
-                        sizeof(version),
-                        -EFAULT);
+                        sizeof(version)))
+               return -EFAULT;
        return 0;
 }
 
@@ -616,7+617,8 @@ int i810_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t      *dev    = priv->dev;
        drm_lock_t        lock;
 
-       copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
        
        if (lock.context == DRM_KERNEL_CONTEXT) {
                DRM_ERROR("Process %d using kernel context %d\n",
@@ -642,5+644,6 @@ int i810_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
                                                       - dev->lck_start)]);
 #endif
        
+       unblock_all_signals();
        return 0;
 }
index b246f76..2f4286b 100644 (file)
@@ -38,13+38,15 @@ int drm_irq_busid(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_irq_busid_t p;
        struct pci_dev  *dev;
 
-       copy_from_user_ret(&p, (drm_irq_busid_t *)arg, sizeof(p), -EFAULT);
+       if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p)))
+               return -EFAULT;
        dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum));
        if (dev) p.irq = dev->irq;
        else     p.irq = 0;
        DRM_DEBUG("%d:%d:%d => IRQ %d\n",
                  p.busnum, p.devnum, p.funcnum, p.irq);
-       copy_to_user_ret((drm_irq_busid_t *)arg, &p, sizeof(p), -EFAULT);
+       if (copy_to_user((drm_irq_busid_t *)arg, &p, sizeof(p)))
+               return -EFAULT;
        return 0;
 }
 
@@ -55,13+57,15 @@ int drm_getunique(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t     *dev    = priv->dev;
        drm_unique_t     u;
 
-       copy_from_user_ret(&u, (drm_unique_t *)arg, sizeof(u), -EFAULT);
+       if (copy_from_user(&u, (drm_unique_t *)arg, sizeof(u)))
+               return -EFAULT;
        if (u.unique_len >= dev->unique_len) {
-               copy_to_user_ret(u.unique, dev->unique, dev->unique_len,
-                                -EFAULT);
+               if (copy_to_user(u.unique, dev->unique, dev->unique_len))
+                       return -EFAULT;
        }
        u.unique_len = dev->unique_len;
-       copy_to_user_ret((drm_unique_t *)arg, &u, sizeof(u), -EFAULT);
+       if (copy_to_user((drm_unique_t *)arg, &u, sizeof(u)))
+               return -EFAULT;
        return 0;
 }
 
@@ -72,15+76,19 @@ int drm_setunique(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t     *dev    = priv->dev;
        drm_unique_t     u;
 
-       if (dev->unique_len || dev->unique) return -EBUSY;
+       if (dev->unique_len || dev->unique)
+               return -EBUSY;
 
-       copy_from_user_ret(&u, (drm_unique_t *)arg, sizeof(u), -EFAULT);
-       if (!u.unique_len) return -EINVAL;
+       if (copy_from_user(&u, (drm_unique_t *)arg, sizeof(u)))
+               return -EFAULT;
+
+       if (!u.unique_len)
+               return -EINVAL;
        
        dev->unique_len = u.unique_len;
        dev->unique     = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
-       copy_from_user_ret(dev->unique, u.unique, dev->unique_len,
-                          -EFAULT);
+       if (copy_from_user(dev->unique, u.unique, dev->unique_len))
+               return -EFAULT;
        dev->unique[dev->unique_len] = '\0';
 
        dev->devname = drm_alloc(strlen(dev->name) + strlen(dev->unique) + 2,
index 33b2cc0..e5fd435 100644 (file)
@@ -218,7+218,8 @@ int drm_finish(struct inode *inode, struct file *filp, unsigned int cmd,
 
        DRM_DEBUG("\n");
 
-       copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
        ret = drm_flush_block_and_flush(dev, lock.context, lock.flags);
        drm_flush_unblock(dev, lock.context, lock.flags);
        return ret;
index b97eb49..3ec28a7 100644 (file)
@@ -57,10+57,10 @@ int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dma) return -EINVAL;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_desc_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        count = request.count;
        order = drm_order(request.size);
@@ -173,10+173,10 @@ int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
        request.count = entry->buf_count;
        request.size  = size;
    
-       copy_to_user_ret((drm_buf_desc_t *)arg,
+       if (copy_to_user((drm_buf_desc_t *)arg,
                         &request,
-                        sizeof(request),
-                        -EFAULT);
+                        sizeof(request)))
+               return -EFAULT;
    
        atomic_dec(&dev->buf_alloc);
 
@@ -219,10+219,10 @@ int mga_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dma) return -EINVAL;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_desc_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        count      = request.count;
        order      = drm_order(request.size);
@@ -348,10+348,10 @@ int mga_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd,
        request.count = entry->buf_count;
        request.size  = size;
 
-       copy_to_user_ret((drm_buf_desc_t *)arg,
+       if (copy_to_user((drm_buf_desc_t *)arg,
                         &request,
-                        sizeof(request),
-                        -EFAULT);
+                        sizeof(request)))
+               return -EFAULT;
        
        atomic_dec(&dev->buf_alloc);
        return 0;
@@ -362,10+362,10 @@ int mga_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
 {
        drm_buf_desc_t   request;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_desc_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        if(request.flags & _DRM_AGP_BUFFER)
                return mga_addbufs_agp(inode, filp, cmd, arg);
@@ -393,10+393,10 @@ int mga_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
        ++dev->buf_use;         /* Can't allocate more after this call */
        spin_unlock(&dev->count_lock);
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_info_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
                if (dma->bufs[i].buf_count) ++count;
@@ -407,28+407,26 @@ int mga_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
        if (request.count >= count) {
                for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
                        if (dma->bufs[i].buf_count) {
-                               copy_to_user_ret(&request.list[count].count,
+                               if (copy_to_user(&request.list[count].count,
                                                 &dma->bufs[i].buf_count,
                                                 sizeof(dma->bufs[0]
-                                                       .buf_count),
-                                                -EFAULT);
-                               copy_to_user_ret(&request.list[count].size,
+                                                       .buf_count)) ||
+                                   copy_to_user(&request.list[count].size,
                                                 &dma->bufs[i].buf_size,
-                                                sizeof(dma->bufs[0].buf_size),
-                                                -EFAULT);
-                               copy_to_user_ret(&request.list[count].low_mark,
+                                                sizeof(dma->bufs[0].buf_size)) ||
+                                   copy_to_user(&request.list[count].low_mark,
                                                 &dma->bufs[i]
                                                 .freelist.low_mark,
                                                 sizeof(dma->bufs[0]
-                                                       .freelist.low_mark),
-                                                -EFAULT);
-                               copy_to_user_ret(&request.list[count]
+                                                       .freelist.low_mark)) ||
+                                   copy_to_user(&request.list[count]
                                                 .high_mark,
                                                 &dma->bufs[i]
                                                 .freelist.high_mark,
                                                 sizeof(dma->bufs[0]
-                                                       .freelist.high_mark),
-                                                -EFAULT);
+                                                       .freelist.high_mark)))
+                                       return -EFAULT;
+
                                DRM_DEBUG("%d %d %d %d %d\n",
                                          i,
                                          dma->bufs[i].buf_count,
@@ -441,10+439,10 @@ int mga_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
        }
        request.count = count;
 
-       copy_to_user_ret((drm_buf_info_t *)arg,
+       if (copy_to_user((drm_buf_info_t *)arg,
                         &request,
-                        sizeof(request),
-                        -EFAULT);
+                        sizeof(request)))
+               return -EFAULT;
        
        return 0;
 }
@@ -461,10+459,10 @@ int mga_markbufs(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dma) return -EINVAL;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_desc_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        DRM_DEBUG("%d, %d, %d\n",
                  request.size, request.low_mark, request.high_mark);
@@ -496,17+494,17 @@ int mga_freebufs(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dma) return -EINVAL;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_free_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        DRM_DEBUG("%d\n", request.count);
        for (i = 0; i < request.count; i++) {
-               copy_from_user_ret(&idx,
+               if (copy_from_user(&idx,
                                   &request.list[i],
-                                  sizeof(idx),
-                                  -EFAULT);
+                                  sizeof(idx)))
+                       return -EFAULT;
                if (idx < 0 || idx >= dma->buf_count) {
                        DRM_ERROR("Index %d (of %d max)\n",
                                  idx, dma->buf_count - 1);
@@ -550,10+548,10 @@ int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
        ++dev->buf_use;         /* Can't allocate more after this call */
        spin_unlock(&dev->count_lock);
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_map_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        DRM_DEBUG("mga_mapbufs\n");
        DRM_DEBUG("dma->flags : %x\n", dma->flags);
@@ -628,10+626,10 @@ int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
        request.count = dma->buf_count;
        DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
    
-       copy_to_user_ret((drm_buf_map_t *)arg,
+       if (copy_to_user((drm_buf_map_t *)arg,
                         &request,
-                        sizeof(request),
-                        -EFAULT);
+                        sizeof(request)))
+               return -EFAULT;
 
        DRM_DEBUG("retcode : %d\n", retcode);
 
index 9a73e6c..43733c1 100644 (file)
@@ -103,19+103,21 @@ int mga_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
        int             i;
 
        DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
-       copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
+       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
+               return -EFAULT;
        if (res.count >= DRM_RESERVED_CONTEXTS) {
                memset(&ctx, 0, sizeof(ctx));
                for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
                        ctx.handle = i;
-                       copy_to_user_ret(&res.contexts[i],
+                       if (copy_to_user(&res.contexts[i],
                                         &i,
-                                        sizeof(i),
-                                        -EFAULT);
+                                        sizeof(i)))
+                               return -EFAULT;
                }
        }
        res.count = DRM_RESERVED_CONTEXTS;
-       copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT);
+       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
+               return -EFAULT;
        return 0;
 }
 
@@ -126,7+128,8 @@ int mga_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        if ((ctx.handle = mga_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
                                /* Skip kernel's context and get a new one. */
                ctx.handle = mga_alloc_queue(dev);
@@ -137,7+140,8 @@ int mga_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
                return -ENOMEM;
        }
        DRM_DEBUG("%d\n", ctx.handle);
-       copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
+       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
        return 0;
 }
 
@@ -153,10+157,12 @@ int mga_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
 {
        drm_ctx_t ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
+               return -EFAULT;
        /* This is 0, because we don't hanlde any context flags */
        ctx.flags = 0;
-       copy_to_user_ret((drm_ctx_t*)arg, &ctx, sizeof(ctx), -EFAULT);
+       if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
        return 0;
 }
 
@@ -167,7+173,8 @@ int mga_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        return mga_context_switch(dev, dev->last_context, ctx.handle);
 }
@@ -179,7+186,8 @@ int mga_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        mga_context_switch_complete(dev, ctx.handle);
 
@@ -193,7+201,8 @@ int mga_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        if(ctx.handle != DRM_KERNEL_CONTEXT) {
                drm_ctxbitmap_free(dev, ctx.handle);
index 0df0906..67ec072 100644 (file)
@@ -82,6+82,7 @@ static void mga_delay(void)
        return;
 }
 
+#ifdef __i386__
 void mga_flush_write_combine(void)
 {
        int xchangeDummy;
@@ -92,6+93,11 @@ void mga_flush_write_combine(void)
                         " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;"
                         " pop %%eax" : /* no outputs */ :  /* no inputs */ );
 }
+#else
+void mga_flush_write_combine(void)
+{
+}
+#endif
 
 /* These are two age tags that will never be sent to
  * the hardware */
@@ -850,7+856,8 @@ int mga_dma_init(struct inode *inode, struct file *filp,
    
        DRM_DEBUG("%s\n", __FUNCTION__);
 
-       copy_from_user_ret(&init, (drm_mga_init_t *)arg, sizeof(init), -EFAULT);
+       if (copy_from_user(&init, (drm_mga_init_t *)arg, sizeof(init)))
+               return -EFAULT;
    
        switch(init.func) {
        case MGA_INIT_DMA:
@@ -932,7+939,8 @@ int mga_control(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_control_t   ctl;
    
-       copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT);
+       if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))
+               return -EFAULT;
 
        DRM_DEBUG("%s\n", __FUNCTION__);
 
@@ -1019,7+1027,8 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_lock_t        lock;
 
        DRM_DEBUG("%s\n", __FUNCTION__);
-       copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
 
        if (lock.context == DRM_KERNEL_CONTEXT) {
                DRM_ERROR("Process %d using kernel context %d\n",
@@ -1068,6+1077,15 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
        }
        
        if (!ret) {
+               sigemptyset(&dev->sigmask);
+               sigaddset(&dev->sigmask, SIGSTOP);
+               sigaddset(&dev->sigmask, SIGTSTP);
+               sigaddset(&dev->sigmask, SIGTTIN);
+               sigaddset(&dev->sigmask, SIGTTOU);
+               dev->sigdata.context = lock.context;
+               dev->sigdata.lock    = dev->lock.hw_lock;
+               block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
+
                if (lock.flags & _DRM_LOCK_QUIESCENT) {
                   DRM_DEBUG("_DRM_LOCK_QUIESCENT\n");
                   mga_flush_queue(dev);
@@ -1088,7+1106,8 @@ int mga_flush_ioctl(struct inode *inode, struct file *filp,
        drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
 
        DRM_DEBUG("%s\n", __FUNCTION__);
-       copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
 
        if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
                DRM_ERROR("mga_flush_ioctl called without lock held\n");
index acc42b8..d4b8cd2 100644 (file)
@@ -444,17+444,18 @@ int mga_version(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_version_t version;
        int           len;
 
-       copy_from_user_ret(&version,
+       if (copy_from_user(&version,
                           (drm_version_t *)arg,
-                          sizeof(version),
-                          -EFAULT);
+                          sizeof(version)))
+               return -EFAULT;
 
 #define DRM_COPY(name,value)                                \
        len = strlen(value);                                 \
        if (len > name##_len) len = name##_len;              \
        name##_len = strlen(value);                          \
        if (len && name) {                                   \
-               copy_to_user_ret(name, value, len, -EFAULT); \
+               if (copy_to_user(name, value, len))          \
+                       return -EFAULT;                      \
        }
 
        version.version_major      = MGA_MAJOR;
@@ -465,10+466,10 @@ int mga_version(struct inode *inode, struct file *filp, unsigned int cmd,
        DRM_COPY(version.date, MGA_DATE);
        DRM_COPY(version.desc, MGA_DESC);
 
-       copy_to_user_ret((drm_version_t *)arg,
+       if (copy_to_user((drm_version_t *)arg,
                         &version,
-                        sizeof(version),
-                        -EFAULT);
+                        sizeof(version)))
+               return -EFAULT;
        return 0;
 }
 
@@ -633,7+634,8 @@ int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t      *dev    = priv->dev;
        drm_lock_t        lock;
 
-       copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
        
        if (lock.context == DRM_KERNEL_CONTEXT) {
                DRM_ERROR("Process %d using kernel context %d\n",
@@ -655,5+657,6 @@ int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
           DRM_ERROR("\n");
        }
 
+       unblock_all_signals();
        return 0;
 }
index fe9e3db..f49bd0f 100644 (file)
 
 typedef struct {
        u32 buffer_status;
-       unsigned int num_dwords;
-       unsigned int max_dwords;
+       int num_dwords;
+       int max_dwords;
        u32 *current_dma_ptr;
        u32 *head;
        u32 phys_head;
@@ -209,19+209,27 @@ typedef struct {
 #define PRIMLOCALS     u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \
                        int outcount, num_dwords
 
-#define PRIM_OVERFLOW(dev, dev_priv, length) do {                      \
-       drm_mga_prim_buf_t *tmp_buf =                                   \
-               dev_priv->prim_bufs[dev_priv->current_prim_idx];        \
-       if( test_bit(MGA_BUF_NEEDS_OVERFLOW,                            \
-                 &tmp_buf->buffer_status)) {                           \
-               mga_advance_primary(dev);                               \
-               mga_dma_schedule(dev, 1);                               \
-       } else if( tmp_buf->max_dwords - tmp_buf->num_dwords < length ||\
-           tmp_buf->sec_used > MGA_DMA_BUF_NR/2) {                     \
-               set_bit(MGA_BUF_FORCE_FIRE, &tmp_buf->buffer_status);   \
-               mga_advance_primary(dev);                               \
-               mga_dma_schedule(dev, 1);                               \
-       }                                                               \
+#define PRIM_OVERFLOW(dev, dev_priv, length) do {                         \
+       drm_mga_prim_buf_t *tmp_buf =                                      \
+               dev_priv->prim_bufs[dev_priv->current_prim_idx];           \
+       if( test_bit(MGA_BUF_NEEDS_OVERFLOW,                               \
+                 &tmp_buf->buffer_status)) {                              \
+               mga_advance_primary(dev);                                  \
+               mga_dma_schedule(dev, 1);                                  \
+               tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
+       } else if( tmp_buf->max_dwords - tmp_buf->num_dwords < length ||   \
+           tmp_buf->sec_used > MGA_DMA_BUF_NR/2) {                        \
+               set_bit(MGA_BUF_FORCE_FIRE, &tmp_buf->buffer_status);      \
+               mga_advance_primary(dev);                                  \
+               mga_dma_schedule(dev, 1);                                  \
+               tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
+       }                                                                  \
+       if(MGA_VERBOSE)                                                    \
+               DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__);             \
+       dma_ptr = tmp_buf->current_dma_ptr;                                \
+       num_dwords = tmp_buf->num_dwords;                                  \
+       phys_head = tmp_buf->phys_head;                                    \
+       outcount = 0;                                                      \
 } while(0)
 
 #define PRIMGETPTR(dev_priv) do {                                      \
index 723ccc5..345abb1 100644 (file)
 #include "mga_drv.h"
 #include "drm.h"
 
+/* If you change the functions to set state, PLEASE
+ * change these values
+ */
+
+#define MGAEMITCLIP_SIZE 10
+#define MGAEMITCTX_SIZE 15
+#define MGAG200EMITTEX_SIZE 20
+#define MGAG400EMITTEX0_SIZE 30
+#define MGAG400EMITTEX1_SIZE 25
+#define MGAG400EMITPIPE_SIZE 50
+#define MGAG200EMITPIPE_SIZE 15
+
+#define MAX_STATE_SIZE ((MGAEMITCLIP_SIZE * MGA_NR_SAREA_CLIPRECTS) + \
+                       MGAEMITCTX_SIZE + MGAG400EMITTEX0_SIZE + \
+                       MGAG400EMITTEX1_SIZE + MGAG400EMITPIPE_SIZE)
+
 static void mgaEmitClipRect(drm_mga_private_t * dev_priv,
                            drm_clip_rect_t * box)
 {
@@ -60,8+76,8 @@ static void mgaEmitClipRect(drm_mga_private_t * dev_priv,
 
        PRIMOUTREG(MGAREG_DMAPAD, 0);
        PRIMOUTREG(MGAREG_CXBNDRY, ((box->x2) << 16) | (box->x1));
-       PRIMOUTREG(MGAREG_YTOP, box->y1 * dev_priv->stride / 2);
-       PRIMOUTREG(MGAREG_YBOT, box->y2 * dev_priv->stride / 2);
+       PRIMOUTREG(MGAREG_YTOP, box->y1 * dev_priv->stride / dev_priv->cpp);
+       PRIMOUTREG(MGAREG_YBOT, box->y2 * dev_priv->stride / dev_priv->cpp);
 
        PRIMADVANCE(dev_priv);
 }
@@ -224,7+240,6 @@ static void mgaG400EmitTex1(drm_mga_private_t * dev_priv)
        PRIMADVANCE(dev_priv);
 }
 
-#define EMIT_PIPE 50
 static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -492,7+507,6 @@ static void mga_dma_dispatch_tex_blit(drm_device_t * dev,
        y2 = length / 64;
 
        PRIM_OVERFLOW(dev, dev_priv, 30);
-       PRIMGETPTR(dev_priv);
 
        PRIMOUTREG(MGAREG_DSTORG, destOrg);
        PRIMOUTREG(MGAREG_MACCESS, 0x00000000);
@@ -526,7+540,6 @@ static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf)
        int length = buf->used;
        int use_agp = PDEA_pagpxfer_enable;
        int i = 0;
-       int primary_needed;
        PRIMLOCALS;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
@@ -542,9+555,8 @@ static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf)
                 * these numbers (Overestimating this doesn't hurt).  
                 */
                buf_priv->dispatched = 1;
-               primary_needed = (50 + 15 + 15 + 30 + 25 +
-                                 10 + 15 * MGA_NR_SAREA_CLIPRECTS);
-               PRIM_OVERFLOW(dev, dev_priv, primary_needed);
+               PRIM_OVERFLOW(dev, dev_priv,
+                             (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));
                mgaEmitState(dev_priv);
                do {
                        if (i < sarea_priv->nbox) {
@@ -592,7+604,6 @@ static void mga_dma_dispatch_indices(drm_device_t * dev,
        unsigned int address = (unsigned int) buf->bus_address;
        int use_agp = PDEA_pagpxfer_enable;
        int i = 0;
-       int primary_needed;
        PRIMLOCALS;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
@@ -606,9+617,8 @@ static void mga_dma_dispatch_indices(drm_device_t * dev,
                 * these numbers (Overestimating this doesn't hurt).  
                 */
                buf_priv->dispatched = 1;
-               primary_needed = (50 + 15 + 15 + 30 + 25 +
-                                 10 + 15 * MGA_NR_SAREA_CLIPRECTS);
-               PRIM_OVERFLOW(dev, dev_priv, primary_needed);
+               PRIM_OVERFLOW(dev, dev_priv,
+                             (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));
                mgaEmitState(dev_priv);
 
                do {
@@ -657,7+667,6 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
        drm_clip_rect_t *pbox = sarea_priv->boxes;
        unsigned int cmd;
        int i;
-       int primary_needed;
        PRIMLOCALS;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
@@ -666,11+675,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
        else
                cmd = MGA_CLEAR_CMD | DC_atype_rstr;
 
-       primary_needed = nbox * 70;
-       if (primary_needed == 0)
-               primary_needed = 70;
-       PRIM_OVERFLOW(dev, dev_priv, primary_needed);
-       PRIMGETPTR(dev_priv);
+       PRIM_OVERFLOW(dev, dev_priv, 35 * MGA_NR_SAREA_CLIPRECTS);
 
        for (i = 0; i < nbox; i++) {
                unsigned int height = pbox[i].y2 - pbox[i].y1;
@@ -741,14+746,12 @@ static void mga_dma_dispatch_swap(drm_device_t * dev)
        int nbox = sarea_priv->nbox;
        drm_clip_rect_t *pbox = sarea_priv->boxes;
        int i;
-       int primary_needed;
+       int pixel_stride = dev_priv->stride / dev_priv->cpp;
+
        PRIMLOCALS;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
-       primary_needed = nbox * 5;
-       primary_needed += 65;
-       PRIM_OVERFLOW(dev, dev_priv, primary_needed);
-       PRIMGETPTR(dev_priv);
+       PRIM_OVERFLOW(dev, dev_priv, (MGA_NR_SAREA_CLIPRECTS * 5) + 20);
 
        PRIMOUTREG(MGAREG_DMAPAD, 0);
        PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -758,7+761,7 @@ static void mga_dma_dispatch_swap(drm_device_t * dev)
        PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
        PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
        PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset);
-       PRIMOUTREG(MGAREG_AR5, dev_priv->stride / 2);
+       PRIMOUTREG(MGAREG_AR5, pixel_stride);
 
        PRIMOUTREG(MGAREG_DMAPAD, 0);
        PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -767,7+770,7 @@ static void mga_dma_dispatch_swap(drm_device_t * dev)
 
        for (i = 0; i < nbox; i++) {
                unsigned int h = pbox[i].y2 - pbox[i].y1;
-               unsigned int start = pbox[i].y1 * dev_priv->stride / 2;
+               unsigned int start = pbox[i].y1 * pixel_stride;
 
                DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
                          pbox[i].x1, pbox[i].y1, pbox[i].x2, pbox[i].y2);
@@ -799,8+802,8 @@ int mga_clear_bufs(struct inode *inode, struct file *filp,
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_mga_clear_t clear;
 
-       copy_from_user_ret(&clear, (drm_mga_clear_t *) arg, sizeof(clear),
-                          -EFAULT);
+       if (copy_from_user(&clear, (drm_mga_clear_t *) arg, sizeof(clear)))
+               return -EFAULT;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
        if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
@@ -868,8+871,8 @@ int mga_iload(struct inode *inode, struct file *filp,
        DRM_DEBUG("%s\n", __FUNCTION__);
 
        DRM_DEBUG("Starting Iload\n");
-       copy_from_user_ret(&iload, (drm_mga_iload_t *) arg, sizeof(iload),
-                          -EFAULT);
+       if (copy_from_user(&iload, (drm_mga_iload_t *) arg, sizeof(iload)))
+               return -EFAULT;
 
        if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
                DRM_ERROR("mga_iload called without lock held\n");
@@ -913,8+916,8 @@ int mga_vertex(struct inode *inode, struct file *filp,
        drm_mga_vertex_t vertex;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
-       copy_from_user_ret(&vertex, (drm_mga_vertex_t *) arg,
-                          sizeof(vertex), -EFAULT);
+       if (copy_from_user(&vertex, (drm_mga_vertex_t *) arg, sizeof(vertex)))
+               return -EFAULT;
 
        if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
                DRM_ERROR("mga_vertex called without lock held\n");
@@ -962,8+965,8 @@ int mga_indices(struct inode *inode, struct file *filp,
        drm_mga_indices_t indices;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
-       copy_from_user_ret(&indices, (drm_mga_indices_t *) arg,
-                          sizeof(indices), -EFAULT);
+       if (copy_from_user(&indices, (drm_mga_indices_t *) arg, sizeof(indices)))
+               return -EFAULT;
 
        if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
                DRM_ERROR("mga_indices called without lock held\n");
@@ -1008,10+1011,11 @@ static int mga_dma_get_buffers(drm_device_t * dev, drm_dma_t * d)
                if (!buf)
                        break;
                buf->pid = current->pid;
-               copy_to_user_ret(&d->request_indices[i],
-                                &buf->idx, sizeof(buf->idx), -EFAULT);
-               copy_to_user_ret(&d->request_sizes[i],
-                                &buf->total, sizeof(buf->total), -EFAULT);
+               if (copy_to_user(&d->request_indices[i],
+                                &buf->idx, sizeof(buf->idx)) ||
+                   copy_to_user(&d->request_sizes[i],
+                                &buf->total, sizeof(buf->total)))
+                       return -EFAULT;
                ++d->granted_count;
        }
        return 0;
@@ -1027,7+1031,8 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_dma_t d;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
-       copy_from_user_ret(&d, (drm_dma_t *) arg, sizeof(d), -EFAULT);
+       if (copy_from_user(&d, (drm_dma_t *) arg, sizeof(d)))
+               return -EFAULT;
        DRM_DEBUG("%d %d: %d send, %d req\n",
                  current->pid, d.context, d.send_count, d.request_count);
 
@@ -1062,6+1067,7 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
 
        DRM_DEBUG("%d returning, granted = %d\n",
                  current->pid, d.granted_count);
-       copy_to_user_ret((drm_dma_t *) arg, &d, sizeof(d), -EFAULT);
+       if (copy_to_user((drm_dma_t *) arg, &d, sizeof(d)))
+               return -EFAULT;
        return retcode;
 }
index bd81dcd..7e76441 100644 (file)
@@ -60,10+60,10 @@ int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dma) return -EINVAL;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_desc_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        count      = request.count;
        order      = drm_order(request.size);
@@ -173,10+173,10 @@ int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
        request.count = entry->buf_count;
        request.size  = size;
 
-       copy_to_user_ret((drm_buf_desc_t *)arg,
+       if (copy_to_user((drm_buf_desc_t *)arg,
                         &request,
-                        sizeof(request),
-                        -EFAULT);
+                        sizeof(request)))
+               return -EFAULT;
 
        dma->flags = _DRM_DMA_USE_AGP;
 
@@ -195,10+195,10 @@ int r128_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (!dev_priv || dev_priv->is_pci) return -EINVAL;
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_desc_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
 #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
        if (request.flags & _DRM_AGP_BUFFER)
@@ -234,10+234,10 @@ int r128_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
        ++dev->buf_use;         /* Can't allocate more after this call */
        spin_unlock(&dev->count_lock);
 
-       copy_from_user_ret(&request,
+       if (copy_from_user(&request,
                           (drm_buf_map_t *)arg,
-                          sizeof(request),
-                          -EFAULT);
+                          sizeof(request)))
+               return -EFAULT;
 
        if (request.count >= dma->buf_count) {
                if (dma->flags & _DRM_DMA_USE_AGP) {
@@ -300,10+300,10 @@ int r128_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
        request.count = dma->buf_count;
        DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
 
-       copy_to_user_ret((drm_buf_map_t *)arg,
+       if (copy_to_user((drm_buf_map_t *)arg,
                         &request,
-                        sizeof(request),
-                        -EFAULT);
+                        sizeof(request)))
+               return -EFAULT;
 
        return retcode;
 }
index 2dd716d..9cadadb 100644 (file)
@@ -103,19+103,21 @@ int r128_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
        int             i;
 
        DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
-       copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
+       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
+               return -EFAULT;
        if (res.count >= DRM_RESERVED_CONTEXTS) {
                memset(&ctx, 0, sizeof(ctx));
                for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
                        ctx.handle = i;
-                       copy_to_user_ret(&res.contexts[i],
+                       if (copy_to_user(&res.contexts[i],
                                         &i,
-                                        sizeof(i),
-                                        -EFAULT);
+                                        sizeof(i)))
+                               return -EFAULT;
                }
        }
        res.count = DRM_RESERVED_CONTEXTS;
-       copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT);
+       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
+               return -EFAULT;
        return 0;
 }
 
@@ -127,7+129,8 @@ int r128_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        if ((ctx.handle = r128_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
                                /* Skip kernel's context and get a new one. */
                ctx.handle = r128_alloc_queue(dev);
@@ -139,7+142,8 @@ int r128_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
                return -ENOMEM;
        }
 
-       copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
+       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
        return 0;
 }
 
@@ -148,7+152,8 @@ int r128_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
 {
        drm_ctx_t ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
+               return -EFAULT;
        if (ctx.flags==_DRM_CONTEXT_PRESERVED)
                r128_res_ctx.handle=ctx.handle;
        return 0;
@@ -159,10+164,12 @@ int r128_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
 {
        drm_ctx_t ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
+               return -EFAULT;
        /* This is 0, because we don't hanlde any context flags */
        ctx.flags = 0;
-       copy_to_user_ret((drm_ctx_t*)arg, &ctx, sizeof(ctx), -EFAULT);
+       if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
        return 0;
 }
 
@@ -173,7+180,8 @@ int r128_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        return r128_context_switch(dev, dev->last_context, ctx.handle);
 }
@@ -185,7+193,8 @@ int r128_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        r128_context_switch_complete(dev, ctx.handle);
 
@@ -199,7+208,8 @@ int r128_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        drm_ctxbitmap_free(dev, ctx.handle);
 
index 16f79c1..61e9cb2 100644 (file)
@@ -68,6+68,7 @@ int R128_READ_PLL(drm_device_t *dev, int addr)
        return R128_READ(R128_CLOCK_CNTL_DATA);
 }
 
+#ifdef __i386__
 static void r128_flush_write_combine(void)
 {
        int xchangeDummy;
@@ -86,6+87,11 @@ static void r128_flush_write_combine(void)
                         "pop %%ebx ;"
                         "pop %%eax" : /* no outputs */ :  /* no inputs */ );
 }
+#else
+static void r128_flush_write_combine(void)
+{
+}
+#endif
 
 static void r128_status(drm_device_t *dev)
 {
@@ -211,8+217,8 @@ int r128_init_cce(struct inode *inode, struct file *filp,
         drm_device_t      *dev    = priv->dev;
        drm_r128_init_t    init;
 
-       copy_from_user_ret(&init, (drm_r128_init_t *)arg, sizeof(init),
-                          -EFAULT);
+       if (copy_from_user(&init, (drm_r128_init_t *)arg, sizeof(init)))
+               return -EFAULT;
 
        switch (init.func) {
        case R128_INIT_CCE:
@@ -680,8+686,8 @@ int r128_submit_pkt(struct inode *inode, struct file *filp,
                return -EINVAL;
        }
 
-       copy_from_user_ret(&packet, (drm_r128_packet_t *)arg, sizeof(packet),
-                          -EFAULT);
+       if (copy_from_user(&packet, (drm_r128_packet_t *)arg, sizeof(packet)))
+               return -EFAULT;
 
        c    = packet.count;
        size = c * sizeof(*buffer);
@@ -696,7+702,8 @@ int r128_submit_pkt(struct inode *inode, struct file *filp,
                }
 
                if ((buffer = kmalloc(size, 0)) == NULL) return -ENOMEM;
-               copy_from_user_ret(buffer, packet.buffer, size, -EFAULT);
+               if (copy_from_user(buffer, packet.buffer, size))
+                       return -EFAULT;
 
                if (dev_priv->cce_secure)
                        ret = r128_submit_packets_ring_secure(dev, buffer, &c);
@@ -706,7+713,8 @@ int r128_submit_pkt(struct inode *inode, struct file *filp,
                c += left;
        } else {
                if ((buffer = kmalloc(size, 0)) == NULL) return -ENOMEM;
-               copy_from_user_ret(buffer, packet.buffer, size, -EFAULT);
+               if (copy_from_user(buffer, packet.buffer, size))
+                       return -EFAULT;
 
                if (dev_priv->cce_secure)
                        ret = r128_submit_packets_pio_secure(dev, buffer, &c);
@@ -717,8+725,8 @@ int r128_submit_pkt(struct inode *inode, struct file *filp,
        kfree(buffer);
 
        packet.count = c;
-       copy_to_user_ret((drm_r128_packet_t *)arg, &packet, sizeof(packet),
-                        -EFAULT);
+       if (copy_to_user((drm_r128_packet_t *)arg, &packet, sizeof(packet)))
+               return -EFAULT;
 
        if (ret)        return ret;
        else if (c > 0) return -EAGAIN;
@@ -855,14+863,13 @@ static int r128_get_vertbufs(drm_device_t *dev, drm_r128_vertex_t *v)
                buf = r128_freelist_get(dev);
                if (!buf) break;
                buf->pid = current->pid;
-               copy_to_user_ret(&v->request_indices[i],
+               if (copy_to_user(&v->request_indices[i],
                                 &buf->idx,
-                                sizeof(buf->idx),
-                                -EFAULT);
-               copy_to_user_ret(&v->request_sizes[i],
+                                sizeof(buf->idx)) ||
+                   copy_to_user(&v->request_sizes[i],
                                 &buf->total,
-                                sizeof(buf->total),
-                                -EFAULT);
+                                sizeof(buf->total)))
+                       return -EFAULT;
                ++v->granted_count;
        }
        return 0;
@@ -889,7+896,8 @@ int r128_vertex_buf(struct inode *inode, struct file *filp, unsigned int cmd,
                return -EINVAL;
        }
 
-       copy_from_user_ret(&v, (drm_r128_vertex_t *)arg, sizeof(v), -EFAULT);
+       if (copy_from_user(&v, (drm_r128_vertex_t *)arg, sizeof(v)))
+               return -EFAULT;
        DRM_DEBUG("%d: %d send, %d req\n",
                  current->pid, v.send_count, v.request_count);
 
@@ -916,7+924,8 @@ int r128_vertex_buf(struct inode *inode, struct file *filp, unsigned int cmd,
 
        DRM_DEBUG("%d returning, granted = %d\n",
                  current->pid, v.granted_count);
-       copy_to_user_ret((drm_r128_vertex_t *)arg, &v, sizeof(v), -EFAULT);
+       if (copy_to_user((drm_r128_vertex_t *)arg, &v, sizeof(v)))
+               return -EFAULT;
 
        return retcode;
 }
index e0080e5..c42c86b 100644 (file)
@@ -420,17+420,18 @@ int r128_version(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_version_t version;
        int           len;
 
-       copy_from_user_ret(&version,
+       if (copy_from_user(&version,
                           (drm_version_t *)arg,
-                          sizeof(version),
-                          -EFAULT);
+                          sizeof(version)))
+               return -EFAULT;
 
 #define DRM_COPY(name,value)                                \
        len = strlen(value);                                 \
        if (len > name##_len) len = name##_len;              \
        name##_len = strlen(value);                          \
        if (len && name) {                                   \
-               copy_to_user_ret(name, value, len, -EFAULT); \
+               if (copy_to_user(name, value, len))          \
+                       return -EFAULT;                      \
        }
 
        version.version_major      = R128_MAJOR;
@@ -441,10+442,10 @@ int r128_version(struct inode *inode, struct file *filp, unsigned int cmd,
        DRM_COPY(version.date, R128_DATE);
        DRM_COPY(version.desc, R128_DESC);
 
-       copy_to_user_ret((drm_version_t *)arg,
+       if (copy_to_user((drm_version_t *)arg,
                         &version,
-                        sizeof(version),
-                        -EFAULT);
+                        sizeof(version)))
+               return -EFAULT;
        return 0;
 }
 
@@ -559,7+560,8 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd,
         dev->lck_start = start = get_cycles();
 #endif
 
-        copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+        if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
 
         if (lock.context == DRM_KERNEL_CONTEXT) {
                 DRM_ERROR("Process %d using kernel context %d\n",
@@ -698,7+700,8 @@ int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t      *dev    = priv->dev;
        drm_lock_t        lock;
 
-       copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
 
        if (lock.context == DRM_KERNEL_CONTEXT) {
                DRM_ERROR("Process %d using kernel context %d\n",
index d6903c0..1fd7331 100644 (file)
@@ -105,19+105,21 @@ int tdfx_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
        int             i;
 
        DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
-       copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
+       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
+               return -EFAULT;
        if (res.count >= DRM_RESERVED_CONTEXTS) {
                memset(&ctx, 0, sizeof(ctx));
                for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
                        ctx.handle = i;
-                       copy_to_user_ret(&res.contexts[i],
+                       if (copy_to_user(&res.contexts[i],
                                         &i,
-                                        sizeof(i),
-                                        -EFAULT);
+                                        sizeof(i)))
+                               return -EFAULT;
                }
        }
        res.count = DRM_RESERVED_CONTEXTS;
-       copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT);
+       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
+               return -EFAULT;
        return 0;
 }
 
@@ -129,7+131,8 @@ int tdfx_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        if ((ctx.handle = tdfx_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
                                /* Skip kernel's context and get a new one. */
                ctx.handle = tdfx_alloc_queue(dev);
@@ -141,7+144,8 @@ int tdfx_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
                return -ENOMEM;
        }
    
-       copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
+       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
        return 0;
 }
 
@@ -150,7+154,8 @@ int tdfx_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
 {
        drm_ctx_t ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
+               return -EFAULT;
        if (ctx.flags==_DRM_CONTEXT_PRESERVED)
                tdfx_res_ctx.handle=ctx.handle;
        return 0;
@@ -161,10+166,12 @@ int tdfx_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
 {
        drm_ctx_t ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
-       /* This is 0, because we don't hanlde any context flags */
+       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
+               return -EFAULT;
+       /* This is 0, because we don't handle any context flags */
        ctx.flags = 0;
-       copy_to_user_ret((drm_ctx_t*)arg, &ctx, sizeof(ctx), -EFAULT);
+       if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
        return 0;
 }
 
@@ -175,7+182,8 @@ int tdfx_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        return tdfx_context_switch(dev, dev->last_context, ctx.handle);
 }
@@ -187,7+195,8 @@ int tdfx_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        tdfx_context_switch_complete(dev, ctx.handle);
 
@@ -201,7+210,8 @@ int tdfx_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t    *dev    = priv->dev;
        drm_ctx_t       ctx;
 
-       copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
        drm_ctxbitmap_free(dev, ctx.handle);
 
index 59f1019..b372004 100644 (file)
@@ -379,17+379,18 @@ int tdfx_version(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_version_t version;
        int           len;
 
-       copy_from_user_ret(&version,
+       if (copy_from_user(&version,
                           (drm_version_t *)arg,
-                          sizeof(version),
-                          -EFAULT);
+                          sizeof(version)))
+               return -EFAULT;
 
 #define DRM_COPY(name,value)                                \
        len = strlen(value);                                 \
        if (len > name##_len) len = name##_len;              \
        name##_len = strlen(value);                          \
        if (len && name) {                                   \
-               copy_to_user_ret(name, value, len, -EFAULT); \
+               if (copy_to_user(name, value, len))          \
+                       return -EFAULT;                      \
        }
 
        version.version_major      = TDFX_MAJOR;
@@ -400,10+401,10 @@ int tdfx_version(struct inode *inode, struct file *filp, unsigned int cmd,
        DRM_COPY(version.date, TDFX_DATE);
        DRM_COPY(version.desc, TDFX_DESC);
 
-       copy_to_user_ret((drm_version_t *)arg,
+       if (copy_to_user((drm_version_t *)arg,
                         &version,
-                        sizeof(version),
-                        -EFAULT);
+                        sizeof(version)))
+               return -EFAULT;
        return 0;
 }
 
@@ -518,7+519,8 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd,
         dev->lck_start = start = get_cycles();
 #endif
 
-        copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+        if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
 
         if (lock.context == DRM_KERNEL_CONTEXT) {
                 DRM_ERROR("Process %d using kernel context %d\n",
@@ -615,6+617,15 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd,
 #endif
 
         if (!ret) {
+               sigemptyset(&dev->sigmask);
+               sigaddset(&dev->sigmask, SIGSTOP);
+               sigaddset(&dev->sigmask, SIGTSTP);
+               sigaddset(&dev->sigmask, SIGTTIN);
+               sigaddset(&dev->sigmask, SIGTTOU);
+               dev->sigdata.context = lock.context;
+               dev->sigdata.lock    = dev->lock.hw_lock;
+               block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
+
                 if (lock.flags & _DRM_LOCK_READY) {
                                /* Wait for space in DMA/FIFO */
                }
@@ -649,7+660,8 @@ int tdfx_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t      *dev    = priv->dev;
        drm_lock_t        lock;
 
-       copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
        
        if (lock.context == DRM_KERNEL_CONTEXT) {
                DRM_ERROR("Process %d using kernel context %d\n",
@@ -679,5+691,6 @@ int tdfx_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
        }
 #endif
        
+       unblock_all_signals();
        return 0;
 }
index 86bb70f..f959b9c 100644 (file)
@@ -2,7+2,7 @@
 
     A driver for CardBus serial devices
 
-    serial_cb.c 1.15 1999/11/24 02:52:06
+    serial_cb.c 1.20 2000/08/07 19:02:03
 
     Copyright 1998, 1999 by Donald Becker and David Hinds
     
     Donald Becker may be reached as becker@CESDIS.edu, or C/O
     USRA Center of Excellence in Space Data and Information Sciences
     Code 930.5, NASA Goddard Space Flight Center, Greenbelt MD 20771
-    David Hinds may be reached at dhinds@pcmcia.sourceforge.org
+    David Hinds may be reached at dahinds@users.sourceforge.net
     
 ======================================================================*/
 
@@ -39,7+39,7 @@ static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"serial_cb.c 1.15 1999/11/24 02:52:06 (David Hinds)";
+"serial_cb.c 1.20 2000/08/07 19:02:03 (David Hinds)";
 #else
 #define DEBUG(n, args...)
 #endif
@@ -134,7+134,7 @@ err_out:
 
 static void serial_detach(dev_node_t *node)
 {
-    DEBUG(0, "serial_detach(tty%02d)\n", node->minor - 0x40);
+    DEBUG(0, "serial_detach(ttyS%02d)\n", node->minor - 0x40);
     unregister_serial(node->minor - 0x40);
     kfree(node);
     MOD_DEC_USE_COUNT;
index 55442dd..af25aa9 100644 (file)
@@ -2,7+2,7 @@
 
     A driver for PCMCIA serial devices
 
-    serial_cs.c 1.118 2000/05/04 01:29:47
+    serial_cs.c 1.123 2000/08/24 18:46:38
 
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     rights and limitations under the License.
 
     The initial developer of the original code is David A. Hinds
-    <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
@@ -58,7+58,7 @@ static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"serial_cs.c 1.118 2000/05/04 01:29:47 (David Hinds)";
+"serial_cs.c 1.123 2000/08/24 18:46:38 (David Hinds)";
 #else
 #define DEBUG(n, args...)
 #endif
@@ -242,12+242,11 @@ static int setup_serial(serial_info_t *info, ioaddr_t port, int irq)
     memset(&serial, 0, sizeof(serial));
     serial.port = port;
     serial.irq = irq;
-    serial.flags = ASYNC_SKIP_TEST;
-    serial.flags |= (info->multi || info->slave) ? ASYNC_SHARE_IRQ : 0;
+    serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
     line = register_serial(&serial);
     if (line < 0) {
-       printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04x, "
-              "irq %d failed\n", serial.port, serial.irq);
+       printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
+              " irq %d failed\n", (u_long)serial.port, serial.irq);
        return -1;
     }
     
@@ -290,7+289,7 @@ static int simple_config(dev_link_t *link)
     cisparse_t parse;
     cistpl_cftable_entry_t *cf = &parse.cftable_entry;
     config_info_t config;
-    int i, j;
+    int i, j, try;
 
     /* If the card is already configured, look up the port and irq */
     i = CardServices(GetConfigurationInfo, handle, &config);
@@ -315,22+314,26 @@ static int simple_config(dev_link_t *link)
     tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
     tuple.Attributes = 0;
     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-    i = first_tuple(handle, &tuple, &parse);
-    while (i != CS_NO_MORE_ITEMS) {
-       if (i != CS_SUCCESS) goto next_entry;
-       if (cf->vpp1.present & (1<<CISTPL_POWER_VNOM))
-           link->conf.Vpp1 = link->conf.Vpp2 =
-               cf->vpp1.param[CISTPL_POWER_VNOM]/10000;
-       if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
-           (cf->io.win[0].base != 0)) {
-           link->conf.ConfigIndex = cf->index;
-           link->io.BasePort1 = cf->io.win[0].base;
-           link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
-           i = CardServices(RequestIO, link->handle, &link->io);
-           if (i == CS_SUCCESS) goto found_port;
+    /* Two tries: without IO aliases, then with aliases */
+    for (try = 0; try < 2; try++) {
+       i = first_tuple(handle, &tuple, &parse);
+       while (i != CS_NO_MORE_ITEMS) {
+           if (i != CS_SUCCESS) goto next_entry;
+           if (cf->vpp1.present & (1<<CISTPL_POWER_VNOM))
+               link->conf.Vpp1 = link->conf.Vpp2 =
+                   cf->vpp1.param[CISTPL_POWER_VNOM]/10000;
+           if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
+               (cf->io.win[0].base != 0)) {
+               link->conf.ConfigIndex = cf->index;
+               link->io.BasePort1 = cf->io.win[0].base;
+               link->io.IOAddrLines = (try == 0) ?
+                   16 : cf->io.flags & CISTPL_IO_LINES_MASK;
+               i = CardServices(RequestIO, link->handle, &link->io);
+               if (i == CS_SUCCESS) goto found_port;
+           }
+       next_entry:
+           i = next_tuple(handle, &tuple, &parse);
        }
-    next_entry:
-       i = next_tuple(handle, &tuple, &parse);
     }
     
     /* Second pass: try to find an entry that isn't picky about
@@ -448,6+451,9 @@ static int multi_config(dev_link_t *link)
     }
     
     setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
+    /* The Nokia cards are not really multiport cards */
+    if (info->manfid == MANFID_NOKIA)
+       return 0;
     for (i = 0; i < info->multi-1; i++)
        setup_serial(info, base2+(8*i), link->irq.AssignedIRQ);
     
@@ -518,11+524,13 @@ void serial_config(dev_link_t *link)
         (parse.funcid.func == CISTPL_FUNCID_MULTI) ||
         (parse.funcid.func == CISTPL_FUNCID_SERIAL))) {
        tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       if ((first_tuple(handle, &tuple, &parse) == CS_SUCCESS) &&
-           (((cf->io.nwin == 1) && (cf->io.win[0].len == 16)) ||
-            ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
-             (cf->io.win[1].len == 8))))
-           info->multi = 2;
+       if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
+           if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
+               info->multi = cf->io.win[0].len >> 3;
+           if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
+               (cf->io.win[1].len == 8))
+               info->multi = 2;
+       }
     }
     
     if (info->multi > 1)
index 7629e24..582503e 100644 (file)
  *
  * This Driver is currently maintained by Christoph Lameter (christoph@lameter.com)
  *
- * Please contact digi for support issues at digilnux@dgii.com. Some
- * information (mostly of historical interest) can be found at
+ * Please contact digi for support issues at digilnux@dgii.com.
+ * Some more information can be found at
  * http://lameter.com/digi.
  *
  *  1.5.2 Fall 1995 Bug fixes by David Nugent
  *              and Xeve also.
  *  1.6.2 August, 7, 2000: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  *             get rid of panics, release previously allocated resources
+ *  1.6.3 August, 23, 2000: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *             cleaned up wrt verify_area.
+ *              Christoph Lameter: Update documentation, email addresses
+ *              and URLs. Remove some obsolete code.
  *
  */
 
-#undef SPEED_HACK
-/* If you define SPEED_HACK then you get the following Baudrate translation
-   19200 = 57600
-   38400 = 115K
-   The driver supports the native 57.6K and 115K Baudrates under Linux, but
-   some distributions like Slackware 3.0 don't like these high baudrates.
-*/
-
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <asm/bitops.h>
 #include <asm/semaphore.h>
 
-#define VERSION        "1.6.2"
+#define VERSION        "1.6.3"
 
 #include "digi.h"
 #include "fep.h"
@@ -713,11+709,10 @@ static int pcxe_write(struct tty_struct * tty, int from_user, const unsigned cha
                tail &= (size - 1);
                stlen = (head >= tail) ? (size - (head - tail) - 1) : (tail - head - 1);
                count = MIN(stlen, count);
-               if (count) {
-                       if (verify_area(VERIFY_READ, (char*)buf, count))
-                               count=0;
-                       else copy_from_user(ch->tmp_buf, buf, count);
-               }
+               if (count)
+                       if (copy_from_user(ch->tmp_buf, buf, count))
+                               count = 0;
+
                buf = ch->tmp_buf;
                memoff(ch);
                restore_flags(flags);
@@ -1896,11+1891,6 @@ fepcmd(struct channel *ch, int cmd, int word_or_byte, int byte2, int ncmds,
 static unsigned termios2digi_c(struct channel *ch, unsigned cflag)
 {
        unsigned res = 0;
-#ifdef SPEED_HACK
-       /* CL: HACK to force 115200 at 38400 and 57600 at 19200 Baud */
-       if ((cflag & CBAUD)== B38400) cflag=cflag - B38400 + B115200;
-       if ((cflag & CBAUD)== B19200) cflag=cflag - B19200 + B57600;
-#endif
        if (cflag & CBAUDEX)
        {
                ch->digiext.digi_flags |= DIGI_FAST;
@@ -2124,7+2114,6 @@ static void receive_data(struct channel *ch)
 static int pcxe_ioctl(struct tty_struct *tty, struct file * file,
                    unsigned int cmd, unsigned long arg)
 {
-       int error;
        struct channel *ch = (struct channel *) tty->driver_data;
        volatile struct board_chan *bc;
        int retval;
@@ -2163,15+2152,13 @@ static int pcxe_ioctl(struct tty_struct *tty, struct file * file,
                        return 0;
 
                case TIOCGSOFTCAR:
-                       return put_user(C_CLOCAL(tty) ? 1 : 0,
-                           (unsigned int *) arg);
+                       return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned int *)arg);
 
                case TIOCSSOFTCAR:
                        {
                            unsigned int value;
-                           error = get_user( value, (unsigned int *) arg);
-                           if (error)
-                               return error;
+                           if (get_user(value, (unsigned int *) arg))
+                                   return -EFAULT;
                            tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (value ? CLOCAL : 0));
                        }
                        return 0;
@@ -2199,18+2186,16 @@ static int pcxe_ioctl(struct tty_struct *tty, struct file * file,
                        if(mstat & ch->dcd)
                                mflag |= TIOCM_CD;
 
-                       error = put_user(mflag, (unsigned int *) arg);
-                       if(error)
-                               return error;
+                       if (put_user(mflag, (unsigned int *) arg))
+                               return -EFAULT;
                        break;
 
                case TIOCMBIS:
                case TIOCMBIC:
                case TIOCMODS:
                case TIOCMSET:
-                       error = get_user(mstat, (unsigned int *) arg);
-                       if(error)
-                               return error;
+                       if (get_user(mstat, (unsigned int *) arg))
+                               return -EFAULT;
 
                        mflag = 0;
                        if(mstat & TIOCM_DTR)
@@ -2262,10+2247,8 @@ static int pcxe_ioctl(struct tty_struct *tty, struct file * file,
                        break;
 
                case DIGI_GETA:
-                       if((error=verify_area(VERIFY_WRITE, (char*)arg, sizeof(digi_t))))
-                               return(error);
-
-                       copy_to_user((char*)arg, &ch->digiext, sizeof(digi_t));
+                       if (copy_to_user((char*)arg, &ch->digiext, sizeof(digi_t)))
+                               return -EFAULT;
                        break;
 
                case DIGI_SETAW:
@@ -2282,10+2265,8 @@ static int pcxe_ioctl(struct tty_struct *tty, struct file * file,
                        /* Fall Thru */
 
                case DIGI_SETA:
-                       if((error=verify_area(VERIFY_READ, (char*)arg,sizeof(digi_t))))
-                               return(error);
-
-                       copy_from_user(&ch->digiext, (char*)arg, sizeof(digi_t));
+                       if (copy_from_user(&ch->digiext, (char*)arg, sizeof(digi_t)))
+                               return -EFAULT;
 #ifdef DEBUG_IOCTL
                        printk("ioctl(DIGI_SETA): flags = %x\n", ch->digiext.digi_flags);
 #endif
@@ -2319,10+2300,8 @@ static int pcxe_ioctl(struct tty_struct *tty, struct file * file,
                        memoff(ch);
                        restore_flags(flags);
 
-                       if((error=verify_area(VERIFY_WRITE, (char*)arg,sizeof(dflow))))
-                               return(error);
-
-                       copy_to_user((char*)arg, &dflow, sizeof(dflow));
+                       if (copy_to_user((char*)arg, &dflow, sizeof(dflow)))
+                               return -EFAULT;
                        break;
 
                case DIGI_SETAFLOW:
@@ -2335,10+2314,8 @@ static int pcxe_ioctl(struct tty_struct *tty, struct file * file,
                                stopc = ch->stopca;
                        }
 
-                       if((error=verify_area(VERIFY_READ, (char*)arg,sizeof(dflow))))
-                               return(error);
-
-                       copy_from_user(&dflow, (char*)arg, sizeof(dflow));
+                       if (copy_from_user(&dflow, (char*)arg, sizeof(dflow)))
+                               return -EFAULT;
 
                        if(dflow.startc != startc || dflow.stopc != stopc) {
                                cli();
index cec43ae..0981a96 100644 (file)
@@ -220,10+220,10 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
                                     sizeof(unsigned long)))?-EFAULT:0;
 
         case I2C_RDWR:
-               copy_from_user_ret(&rdwr_arg, 
-                       (struct i2c_rdwr_ioctl_data *)arg, 
-                       sizeof(rdwr_arg),
-                       -EFAULT);
+               if (copy_from_user(&rdwr_arg, 
+                                  (struct i2c_rdwr_ioctl_data *)arg, 
+                                  sizeof(rdwr_arg)))
+                       return -EFAULT;
 
                rdwr_pa = (struct i2c_msg *)
                        kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), 
@@ -280,10+280,10 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
                return res;
 
        case I2C_SMBUS:
-               copy_from_user_ret(&data_arg,
+               if (copy_from_user(&data_arg,
                                   (struct i2c_smbus_ioctl_data *) arg,
-                                  sizeof(struct i2c_smbus_ioctl_data),
-                                  -EFAULT);
+                                  sizeof(struct i2c_smbus_ioctl_data)))
+                       return -EFAULT;
                if ((data_arg.size != I2C_SMBUS_BYTE) && 
                    (data_arg.size != I2C_SMBUS_QUICK) &&
                    (data_arg.size != I2C_SMBUS_BYTE_DATA) && 
@@ -336,15+336,18 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
                        datasize = sizeof(data_arg.data->block);
 
                if ((data_arg.size == I2C_SMBUS_PROC_CALL) || 
-                   (data_arg.read_write == I2C_SMBUS_WRITE))
-                       copy_from_user_ret(&temp,data_arg.data,datasize,
-                                          -EFAULT);
+                   (data_arg.read_write == I2C_SMBUS_WRITE)) {
+                       if (copy_from_user(&temp, data_arg.data, datasize))
+                               return -EFAULT;
+               }
                res = i2c_smbus_xfer(client->adapter,client->addr,client->flags,
                      data_arg.read_write,
                      data_arg.command,data_arg.size,&temp);
                if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || 
-                  (data_arg.read_write == I2C_SMBUS_READ)))
-                       copy_to_user_ret(data_arg.data,&temp,datasize,-EFAULT);
+                             (data_arg.read_write == I2C_SMBUS_READ))) {
+                       if (copy_to_user(data_arg.data, &temp, datasize))
+                               return -EFAULT;
+               }
                return res;
 
        default:
index 6e86002..b4ef205 100644 (file)
@@ -1242,7+1242,8 @@ int zoran_ioctl(struct video_device* dev, unsigned int cmd, void *arg)
         case VIDIOCCAPTURE:
         {
                int v;
-               get_user_ret(v,(int*)arg, -EFAULT);
+               if (get_user(v, (int *)arg))
+                       return -EFAULT;
                DEBUG(printk(CARD_DEBUG "VIDIOCCAPTURE(%d)\n",CARD,v));
 
                if (v==0) {
@@ -1314,7+1315,8 @@ int zoran_ioctl(struct video_device* dev, unsigned int cmd, void *arg)
         case VIDIOCSYNC:
         {
                int i;
-               get_user_ret(i,(int*)arg, -EFAULT);
+               if (get_user(i, (int *) arg))
+                       return -EFAULT;
                DEBUG(printk(CARD_DEBUG "VIDEOCSYNC(%d)\n",CARD,i));
                if (i<0 || i>ZORAN_MAX_FBUFFERS)
                        return -EINVAL;
index 7a5775a..7f3f76e 100644 (file)
@@ -2,7+2,7 @@
 
        Written 1993-1998 by
        Donald Becker, becker@cesdis.gsfc.nasa.gov, (driver core) and
-       David Hinds, dhinds@pcmcia.sourceforge.org (from his PC card code).
+       David Hinds, dahinds@users.sourceforge.net (from his PC card code).
 
        This software may be used and distributed according to the terms of
        the GNU Public License, incorporated herein by reference.
@@ -327,7+327,7 @@ static dev_link_t *tc574_attach(void)
        dev->stop = &el3_close;
        dev->tx_timeout = el3_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
-       
+
        /* Register with Card Services */
        link->next = dev_list;
        dev_list = link;
index 9f4a54f..3cbba20 100644 (file)
@@ -2,9+2,9 @@
 
     A PCMCIA ethernet driver for the 3com 3c589 card.
     
-    Copyright (C) 1999 David A. Hinds -- dhinds@pcmcia.sourceforge.org
+    Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net
 
-    3c589_cs.c 1.151 2000/05/08 22:03:18
+    3c589_cs.c 1.153 2000/06/12 21:27:25
 
     The network driver code is based on Donald Becker's 3c589 code:
     
@@ -117,7+117,7 @@ static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"3c589_cs.c 1.151 2000/05/08 22:03:18 (David Hinds)";
+"3c589_cs.c 1.153 2000/06/12 21:27:25 (David Hinds)";
 #else
 #define DEBUG(n, args...)
 #endif
index a17ac13..04c0c0e 100644 (file)
@@ -6,7+6,7 @@
  * Status:        Experimental.
  * Authors:       John Markus Bjørndalen <johnm@cs.uit.no>
  *                Dag Brattli <dagb@cs.uit.no>
- *                David Hinds <dhinds@pcmcia.sourceforge.org>
+ *                David Hinds <dahinds@users.sourceforge.net>
  * Created at:    A long time ago!
  * Modified at:   Mon Nov 10 11:54:37 1997
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
 
 #ifdef CONFIG_NET_PCMCIA_RADIO
 #include <linux/wireless.h>
-#endif /* CONFIG_NET_PCMCIA_RADIO */
+#endif
 
 #include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #define NETWAVE_ASR_RXRDY   0x80
 #define NETWAVE_ASR_TXBA    0x01
 
-#define TX_TIMEOUT  20
-#define WATCHDOG_JIFFIES 32
+#define TX_TIMEOUT             ((32*HZ)/100)
 
 static const unsigned int imrConfRFU1 = 0x10; /* RFU interrupt mask, keep high */
 static const unsigned int imrConfIENA = 0x02; /* Interrupt enable */
@@ -151,8+150,6 @@ static const unsigned int txConfEUD    = 0x10; /* Enable Uni-Data packets */
 static const unsigned int txConfKey    = 0x02; /* Scramble data packets */
 static const unsigned int txConfLoop   = 0x01; /* Loopback mode */
 
-static int netwave_debug = 0;
-
 /*
    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
    you do not define PCMCIA_DEBUG at all, all the debug code will be
@@ -223,7+220,6 @@ static void netwave_reset(struct net_device *dev);
 static int netwave_open(struct net_device *dev);  /* Open the device */
 static int netwave_close(struct net_device *dev); /* Close the device */
 static int netwave_config(struct net_device *dev, struct ifmap *map);
-static void netwave_tx_timeout (struct net_device *dev);
 
 /* Packet transmission and Packet reception */
 static int netwave_start_xmit( struct sk_buff *skb, struct net_device *dev);
@@ -231,7+227,7 @@ static int netwave_rx( struct net_device *dev);
 
 /* Interrupt routines */
 static void netwave_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void netwave_watchdog(u_long);  /* Transmission watchdog */
+static void netwave_watchdog(struct net_device *);
 
 /* Statistics */
 static void update_stats(struct net_device *dev);
@@ -309,7+305,6 @@ typedef struct netwave_private {
     u_char     *ramBase;
     int        timeoutCounter;
     int        lastExec;
-    spinlock_t lock;
     struct timer_list      watchdog;   /* To avoid blocking state */
     struct site_survey     nss;
     struct net_device_stats stats;
@@ -417,18+412,6 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
 #endif
 
 /*
- * Function netwave_init (dev)
- *
- *    We never need to do anything when a device is "initialized"
- *    by the net software, because we only register already-found cards.
- */
-int netwave_init(struct net_device *dev)
-{
-    /* We do all the initialization of this in netwave_attach instead */
-    return 0;
-}
-
-/*
  * Function netwave_attach (void)
  *
  *     Creates an "instance" of the driver, allocating local data 
@@ -456,7+439,6 @@ static dev_link_t *netwave_attach(void)
     priv = kmalloc(sizeof(*priv), GFP_KERNEL);
     if (!priv) return NULL;
     memset(priv, 0, sizeof(*priv));
-    priv->lock = SPIN_LOCK_UNLOCKED;
     link = &priv->link; dev = &priv->dev;
     link->priv = dev->priv = priv;
     link->release.function = &netwave_release;
@@ -486,10+468,6 @@ static dev_link_t *netwave_attach(void)
     link->conf.ConfigIndex = 1;
     link->conf.Present = PRESENT_OPTION;
 
-    /* Set the watchdog timer */
-    priv->watchdog.function = &netwave_watchdog;
-    priv->watchdog.data = (unsigned long) dev;
-
     /* Netwave specific entries in the device structure */
     dev->hard_start_xmit = &netwave_start_xmit;
     dev->set_config = &netwave_config;
@@ -501,14+479,12 @@ static dev_link_t *netwave_attach(void)
 #endif
     dev->do_ioctl = &netwave_ioctl;
 
+    dev->tx_timeout = &netwave_watchdog;
+    dev->watchdog_timeo = TX_TIMEOUT;
+
     ether_setup(dev);
-    strcpy(dev->name, priv->node.dev_name);
-    dev->init = &netwave_init;
     dev->open = &netwave_open;
     dev->stop = &netwave_close;
-    dev->tx_timeout = netwave_tx_timeout;
-    dev->watchdog_timeo = TX_TIMEOUT;
-    netif_start_queue (dev);
     link->irq.Instance = dev;
     
     /* Register with Card Services */
@@ -545,30+521,21 @@ static void netwave_detach(dev_link_t *link)
 {
     netwave_private *priv = link->priv;
     dev_link_t **linkp;
-    long flags;
 
     DEBUG(0, "netwave_detach(0x%p)\n", link);
   
-    save_flags(flags);
-    if (link->state & DEV_RELEASE_PENDING) {
-       del_timer(&link->release);
-       link->state &= ~DEV_RELEASE_PENDING;
-    }
-    cli();
-    restore_flags(flags);
-
     /*
          If the device is currently configured and active, we won't
          actually delete it yet.  Instead, it is marked so that when
          the release() function is called, that will trigger a proper
          detach().
        */
+    del_timer(&link->release);
     if (link->state & DEV_CONFIG) {
        netwave_release((u_long) link);
        if (link->state & DEV_STALE_CONFIG) {
            DEBUG(1, "netwave_cs: detach postponed, '%s' still "
                  "locked\n", link->dev->dev_name);
-           
            link->state |= DEV_STALE_LINK;
            return;
        }
@@ -641,7+608,7 @@ static int netwave_ioctl(struct net_device *dev, /* ioctl device */
     struct iwreq *wrq = (struct iwreq *) rq;
 #endif
        
-    DEBUG( 0, "%s: ->netwave_ioctl(cmd=0x%X)\n", dev->name, cmd);
+    DEBUG(0, "%s: ->netwave_ioctl(cmd=0x%X)\n", dev->name, cmd);
        
     /* Disable interrupts & save flags */
     save_flags(flags);
@@ -840,7+807,7 @@ static void netwave_pcmcia_config(dev_link_t *link) {
     struct net_device *dev = &priv->dev;
     tuple_t tuple;
     cisparse_t parse;
-    int i=0, j, last_ret, last_fn;
+    int i, j, last_ret, last_fn;
     u_char buf[64];
     win_req_t req;
     memreq_t mem;
@@ -862,16+829,16 @@ static void netwave_pcmcia_config(dev_link_t *link) {
     CS_CHECK(ParseTuple, handle, &tuple, &parse);
     link->conf.ConfigBase = parse.config.base;
     link->conf.Present = parse.config.rmask[0];
-    
+
     /* Configure card */
     link->state |= DEV_CONFIG;
-       
+
     /*
      *  Try allocating IO ports.  This tries a few fixed addresses.
      *  If you want, you can also read the card's config table to
      *  pick addresses -- see the serial driver for an example.
      */
-    for (j = 0x0; j < 0x400; j += 0x20) {
+    for (i = j = 0x0; j < 0x400; j += 0x20) {
        link->io.BasePort1 = j ^ 0x300;
        i = CardServices(RequestIO, link->handle, &link->io);
        if (i == CS_SUCCESS) break;
@@ -880,19+847,19 @@ static void netwave_pcmcia_config(dev_link_t *link) {
        cs_error(link->handle, RequestIO, i);
        goto failed;
     }
-               
+
     /*
      *  Now allocate an interrupt line.  Note that this does not
      *  actually assign a handler to the interrupt.
      */
     CS_CHECK(RequestIRQ, handle, &link->irq);
-       
+
     /*
      *  This actually configures the PCMCIA socket -- setting up
      *  the I/O windows and the interrupt mapping.
      */
     CS_CHECK(RequestConfiguration, handle, &link->conf);
-    
+
     /*
      *  Allocate a 32K memory window.  Note that the dev_link_t
      *  structure provides space for one window handle -- if your
@@ -900,7+867,7 @@ static void netwave_pcmcia_config(dev_link_t *link) {
      *  the handles in your private data structure, link->priv.
      */
     DEBUG(1, "Setting mem speed of %d\n", mem_speed);
-    
+
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
     req.Base = 0; req.Size = 0x8000;
     req.AccessSpeed = mem_speed;
@@ -908,26+875,25 @@ static void netwave_pcmcia_config(dev_link_t *link) {
     CS_CHECK(RequestWindow, &link->win, &req);
     mem.CardOffset = 0x20000; mem.Page = 0; 
     CS_CHECK(MapMemPage, link->win, &mem);
-    
+
     /* Store base address of the common window frame */
     ramBase = ioremap(req.Base, 0x8000);
     ((netwave_private*)dev->priv)->ramBase = ramBase;
-    
+
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
-    netif_start_queue (dev);
     if (register_netdev(dev) != 0) {
        printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
        goto failed;
     }
-       
+
+    strcpy(priv->node.dev_name, dev->name);
+    link->dev = &priv->node;
     link->state &= ~DEV_CONFIG_PENDING;
-       
-    link->dev = &((netwave_private *)dev->priv)->node;
 
     /* Reset card before reading physical address */
     netwave_doreset(dev->base_addr, ramBase);
-    
+
     /* Read the ethernet address and fill in the Netwave registers. */
     for (i = 0; i < 6; i++) 
        dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i);
@@ -949,7+915,6 @@ cs_failed:
     cs_error(link->handle, last_fn, last_ret);
 failed:
     netwave_release((u_long)link);
-    return;
 } /* netwave_pcmcia_config */
 
 /*
@@ -975,7+940,7 @@ static void netwave_release(u_long arg) {
        link->state |= DEV_STALE_CONFIG;
        return;
     }
-       
+
     /* Don't bother checking to see if these succeed or not */
     if (link->win) {
        iounmap(priv->ramBase);
@@ -984,9+949,9 @@ static void netwave_release(u_long arg) {
     CardServices(ReleaseConfiguration, link->handle);
     CardServices(ReleaseIO, link->handle, &link->io);
     CardServices(ReleaseIRQ, link->handle, &link->irq);
-    link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING | DEV_STALE_CONFIG);
-    
+
+    link->state &= ~(DEV_CONFIG | DEV_STALE_CONFIG);
+
 } /* netwave_release */
 
 /*
@@ -1020,8+985,7 @@ static int netwave_event(event_t event, int priority,
        link->state &= ~DEV_PRESENT;
        if (link->state & DEV_CONFIG) {
            netif_device_detach(dev);
-           link->release.expires = jiffies + 5;
-           add_timer(&link->release);
+           mod_timer(&link->release, jiffies + HZ/20);
        }
        break;
     case CS_EVENT_CARD_INSERTION:
@@ -1035,7+999,6 @@ static int netwave_event(event_t event, int priority,
        if (link->state & DEV_CONFIG) {
            if (link->open)
                netif_device_detach(dev);
-
            CardServices(ReleaseConfiguration, link->handle);
        }
        break;
@@ -1082,10+1045,7 @@ static void netwave_reset(struct net_device *dev) {
     DEBUG(0, "netwave_reset: Done with hardware reset\n");
 
     priv->timeoutCounter = 0;
-       
-    /* If watchdog was activated, kill it ! */
-    del_timer(&priv->watchdog);
-       
+
     /* Reset card */
     netwave_doreset(iobase, ramBase);
     printk(KERN_DEBUG "netwave_reset: Done with hardware reset\n");
@@ -1172,7+1132,7 @@ static int netwave_hw_xmit(unsigned char* data, int len,
     netwave_private *priv = (netwave_private *) dev->priv;
     u_char* ramBase = priv->ramBase;
     ioaddr_t iobase = dev->base_addr;
-       
+
     /* Disable interrupts & save flags */
     save_flags(flags);
     cli();
@@ -1183,9+1143,10 @@ static int netwave_hw_xmit(unsigned char* data, int len,
        /* No buffers available */
        printk(KERN_DEBUG "netwave_hw_xmit: %s - no xmit buffers available.\n",
               dev->name);
+       restore_flags(flags);
        return 1;
     }
-       
+
     priv->stats.tx_bytes += len;
 
     DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
@@ -1222,29+1183,11 @@ static int netwave_hw_xmit(unsigned char* data, int len,
     writeb(len & 0xff, ramBase + NETWAVE_EREG_CB + 1);
     writeb((len>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
     writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
-       
-    /* If watchdog not already active, activate it... */
-    if (!timer_pending(&priv->watchdog)) {
-       /* set timer to expire in WATCHDOG_JIFFIES */
-       priv->watchdog.expires = jiffies + WATCHDOG_JIFFIES;
-       add_timer(&priv->watchdog);
-    }
+
     restore_flags( flags);
     return 0;
 }
 
-
-static void netwave_tx_timeout (struct net_device *dev)
-{
-       if (netwave_debug > 0)
-               printk (KERN_DEBUG "%s timed out.\n", dev->name);
-       netwave_reset (dev);
-       dev->trans_start = jiffies;
-       netif_start_queue (dev);
-}
-
-
-
 static int netwave_start_xmit(struct sk_buff *skb, struct net_device *dev) {
        /* This flag indicate that the hardware can't perform a transmission.
         * Theoritically, NET3 check it before sending a packet to the driver,
@@ -1252,23+1195,15 @@ static int netwave_start_xmit(struct sk_buff *skb, struct net_device *dev) {
         * As the watchdog will abort too long transmissions, we are quite safe...
         */
 
-    /* Sending a NULL skb means some higher layer thinks we've missed an
-     * tx-done interrupt. Caution: dev_tint() handles the cli()/sti()
-     * itself. 
-     */
+    netif_stop_queue(dev);
 
-    /* Block a timer-based transmit from overlapping. This could 
-     * better be done with atomic_swap(1, dev->tbusy, but set_bit()
-     * works as well 
-     */
-    netif_stop_queue (dev);
-    if (1) {
+    {
        short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
        unsigned char* buf = skb->data;
        
        if (netwave_hw_xmit( buf, length, dev) == 1) {
            /* Some error, let's make them call us another time? */
-           netif_start_queue (dev);
+           netif_start_queue(dev);
        }
        dev->trans_start = jiffies;
     }
@@ -1295,11+1230,9 @@ static void netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs) {
     dev_link_t *link = &priv->link;
     int i;
     
-    if ((dev == NULL) || !netif_device_present(dev))
+    if (!netif_device_present(dev))
        return;
     
-    spin_lock (&priv->lock);
-    
     iobase = dev->base_addr;
     ramBase = priv->ramBase;
        
@@ -1313,9+1246,9 @@ static void netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs) {
        
         status = inb(iobase + NETWAVE_REG_ASR);
                
-       if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) {
-           DEBUG( 1, "netwave_interupt: Interrupt with status 0x%x "
-                  "from removed or suspended card!\n", status);
+       if (!DEV_OK(link)) {
+           DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x "
+                 "from removed or suspended card!\n", status);
            break;
        }
                
@@ -1393,21+1326,15 @@ static void netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs) {
            DEBUG(3, "New status is TSER %x ASR %x\n",
                  readb(ramBase + NETWAVE_EREG_TSER),
                  inb(iobase + NETWAVE_REG_ASR));
-                       
-           /* If watchdog was activated, kill it ! */
-           del_timer(&priv->watchdog);
 
-           netif_wake_queue (dev);
+           netif_wake_queue(dev);
        }
        /* TxBA, this would trigger on all error packets received */
        /* if (status & 0x01) {
-          if (netwave_debug > 3) 
-          printk(KERN_DEBUG "Transmit buffers available, %x\n", status); 
-          } 
+          DEBUG(4, "Transmit buffers available, %x\n", status);
+          }
           */
     }
-    /* done.. */
-    spin_unlock (&priv->lock);
 } /* netwave_interrupt */
 
 /*
@@ -1418,20+1345,12 @@ static void netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs) {
  *    it expire, we reset the card.
  *
  */
-static void netwave_watchdog(u_long a) {
-    struct net_device *dev;
-    ioaddr_t iobase;
-       
-    dev = (struct net_device *) a;
-    iobase = dev->base_addr;
-    
-    DEBUG( 1, "%s: netwave_watchdog: watchdog timer expired\n", dev->name);
-       
-    netwave_reset(dev); 
-       
-    /* We are not waiting anymore... */
-    netif_start_queue (dev);
-       
+static void netwave_watchdog(struct net_device *dev) {
+
+    DEBUG(1, "%s: netwave_watchdog: watchdog timer expired\n", dev->name);
+    netwave_reset(dev);
+    dev->trans_start = jiffies;
+    netif_start_queue(dev);
 } /* netwave_watchdog */
 
 static struct net_device_stats *netwave_get_stats(struct net_device *dev) {
@@ -1569,8+1488,8 @@ static int netwave_open(struct net_device *dev) {
 
     link->open++;
     MOD_INC_USE_COUNT;
-       
-    netif_start_queue (dev);
+
+    netif_start_queue(dev);
     netwave_reset(dev);
        
     return 0;
@@ -1582,17+1501,10 @@ static int netwave_close(struct net_device *dev) {
 
     DEBUG(1, "netwave_close: finishing.\n");
 
-    netif_stop_queue (dev);
-
-    /* If watchdog was activated, kill it ! */
-    del_timer(&priv->watchdog);
-       
     link->open--;
-    if (link->state & DEV_STALE_CONFIG) {
-       link->release.expires = jiffies + 5;
-       link->state |= DEV_RELEASE_PENDING;
-       add_timer(&link->release);
-    }  
+    netif_stop_queue(dev);
+    if (link->state & DEV_STALE_CONFIG)
+       mod_timer(&link->release, jiffies + HZ/20);
        
     MOD_DEC_USE_COUNT;
     return 0;
index 9084bfd..0dccc39 100644 (file)
@@ -28,7+28,7 @@ References
   Dean Siasoyco, New Media Corporation
   Ken Lesniak, Silicon Graphics, Inc. <lesniak@boston.sgi.com>
   Donald Becker <becker@cesdis1.gsfc.nasa.gov>
-  David Hinds <dhinds@pcmcia.sourceforge.org>
+  David Hinds <dahinds@users.sourceforge.net>
 
   The Linux client driver is based on the 3c589_cs.c client driver by
   David Hinds.
index 9eff09a..0f95529 100644 (file)
@@ -9,9+9,9 @@
     Conrad ethernet card, and the Kingston KNE-PCM/x in shared-memory
     mode.  It will also handle the Socket EA card in either mode.
 
-    Copyright (C) 1999 David A. Hinds -- dhinds@pcmcia.sourceforge.org
+    Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net
 
-    pcnet_cs.c 1.117 2000/05/04 01:29:47
+    pcnet_cs.c 1.124 2000/07/21 19:47:31
     
     The network driver code is based on Donald Becker's NE2000 code:
 
@@ -72,7+72,7 @@ static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"pcnet_cs.c 1.117 2000/05/04 01:29:47 (David Hinds)";
+"pcnet_cs.c 1.124 2000/07/21 19:47:31 (David Hinds)";
 #else
 #define DEBUG(n, args...)
 #endif
@@ -153,7+153,8 @@ typedef struct hw_info_t {
 #define USE_BIG_BUF    0x04
 #define HAS_IBM_MISC   0x08
 #define IS_DL10019     0x10
-#define IS_AX88190     0x20
+#define IS_DL10022     0x20
+#define IS_AX88190     0x40
 #define USE_SHMEM      0x80    /* autodetected */
 
 static hw_info_t hw_info[] = {
@@ -219,10+220,9 @@ static hw_info_t hw_info[] = {
 
 #define NR_INFO                (sizeof(hw_info)/sizeof(hw_info_t))
 
-static hw_info_t default_info =
-{ /* Unknown NE2000 Clone */ 0x00, 0x00, 0x00, 0x00, 0 };
-static hw_info_t dl10019_info =
-{ /* D-Link DL10019 chipset */ 0x00, 0x00, 0x00, 0x00, IS_DL10019 };
+static hw_info_t default_info = { 0, 0, 0, 0, 0 };
+static hw_info_t dl10019_info = { 0, 0, 0, 0, IS_DL10019 };
+static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10019|IS_DL10022 };
 
 typedef struct pcnet_dev_t {
     struct net_device  dev;    /* so &dev == &pcnet_dev_t */
@@ -232,7+232,7 @@ typedef struct pcnet_dev_t {
     caddr_t            base;
     struct timer_list  watchdog;
     int                        stale, fast_poll;
-    u_char             link_status;
+    u_short            link_status;
 } pcnet_dev_t;
 
 /*======================================================================
@@ -504,7+504,8 @@ static hw_info_t *get_dl10019(dev_link_t *link)
        return NULL;
     for (i = 0; i < 6; i++)
        dev->dev_addr[i] = inb_p(dev->base_addr + 0x14 + i);
-    return &dl10019_info;
+    i = inb(dev->base_addr + 0x1f);
+    return ((i == 0x91)||(i == 0x99)) ? &dl10022_info : &dl10019_info;
 }
 
 /*======================================================================
@@ -723,14+724,18 @@ static void pcnet_config(dev_link_t *link)
        hw_info = get_hwired(link);
     
     if (hw_info == NULL) {
-       printk(KERN_NOTICE "pcnet_cs: unable to read hardware net address\n");
-       goto config_undo;
+       printk(KERN_NOTICE "pcnet_cs: unable to read hardware net"
+              " address for io base %#3lx\n", dev->base_addr);
+       unregister_netdev(dev);
+       goto failed;
     }
 
     info->flags = hw_info->flags;
     /* Check for user overrides */
     info->flags |= (delay_output) ? DELAY_OUTPUT : 0;
-    if ((manfid == MANFID_SOCKET) && (prodid == PRODID_SOCKET_LPE))
+    if ((manfid == MANFID_SOCKET) &&
+       ((prodid == PRODID_SOCKET_LPE) ||
+        (prodid == PRODID_SOCKET_EIO)))
        info->flags &= ~USE_BIG_BUF;
     if (!use_big_buf)
        info->flags &= ~USE_BIG_BUF;
@@ -760,8+765,9 @@ static void pcnet_config(dev_link_t *link)
 
     if (info->flags & IS_DL10019) {
        dev->do_ioctl = &do_ioctl;
-       printk(KERN_INFO "%s: NE2000 (DL10019 rev %02x): ",
-              dev->name, inb(dev->base_addr + 0x1a));
+       printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ",
+              dev->name, ((info->flags & IS_DL10022) ? 22 : 19),
+              inb(dev->base_addr + 0x1a));
     } else if (info->flags & IS_AX88190) {
        printk(KERN_INFO "%s: NE2000 (AX88190): ", dev->name);
     } else
@@ -776,9+782,6 @@ static void pcnet_config(dev_link_t *link)
        printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
     return;
 
-config_undo:
-    unregister_netdev(dev);
-    goto failed;
 cs_failed:
     cs_error(link->handle, last_fn, last_ret);
 failed:
@@ -876,6+879,79 @@ static int pcnet_event(event_t event, int priority,
     return 0;
 } /* pcnet_event */
 
+/*======================================================================
+
+    MII interface support for DL10019 and DL10022 based cards
+
+    On the DL10019, the MII IO direction bit is 0x10; on  the DL10022
+    it is 0x20.  Setting both bits seems to work on both card types.
+
+======================================================================*/
+
+#define DLINK_GPIO             0x1c
+#define DLINK_DIAG             0x1d
+#define MDIO_SHIFT_CLK         0x80
+#define MDIO_DATA_OUT          0x40
+#define MDIO_DIR_WRITE         0x30
+#define MDIO_DATA_WRITE0       (MDIO_DIR_WRITE)
+#define MDIO_DATA_WRITE1       (MDIO_DIR_WRITE | MDIO_DATA_OUT)
+#define MDIO_DATA_READ         0x10
+#define MDIO_MASK              0x0f
+
+static void mdio_sync(ioaddr_t addr)
+{
+    int bits, mask = inb(addr) & MDIO_MASK;
+    for (bits = 0; bits < 32; bits++) {
+       outb(mask | MDIO_DATA_WRITE1, addr);
+       outb(mask | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, addr);
+    }
+}
+
+static int mdio_read(ioaddr_t addr, int phy_id, int loc)
+{
+    u_int cmd = (0x06<<10)|(phy_id<<5)|loc;
+    int i, retval = 0, mask = inb(addr) & MDIO_MASK;
+
+    mdio_sync(addr);
+    for (i = 13; i >= 0; i--) {
+       int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
+       outb(mask | dat, addr);
+       outb(mask | dat | MDIO_SHIFT_CLK, addr);
+    }
+    for (i = 19; i > 0; i--) {
+       outb(mask, addr);
+       retval = (retval << 1) | ((inb(addr) & MDIO_DATA_READ) != 0);
+       outb(mask | MDIO_SHIFT_CLK, addr);
+    }
+    return (retval>>1) & 0xffff;
+}
+
+static void mdio_write(ioaddr_t addr, int phy_id, int loc, int value)
+{
+    u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
+    int i, mask = inb(addr) & MDIO_MASK;
+
+    mdio_sync(addr);
+    for (i = 31; i >= 0; i--) {
+       int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
+       outb(mask | dat, addr);
+       outb(mask | dat | MDIO_SHIFT_CLK, addr);
+    }
+    for (i = 1; i >= 0; i--) {
+       outb(mask, addr);
+       outb(mask | MDIO_SHIFT_CLK, addr);
+    }
+}
+
+static void mdio_reset(ioaddr_t addr, int phy_id)
+{
+    outb_p(0x08, addr);
+    outb_p(0x0c, addr);
+    outb_p(0x08, addr);
+    outb_p(0x0c, addr);
+    outb_p(0x00, addr);
+}
+
 /*====================================================================*/
 
 static void set_misc_reg(struct net_device *dev)
@@ -894,6+970,12 @@ static void set_misc_reg(struct net_device *dev)
            tmp |= 8;
        outb_p(tmp, nic_base + PCNET_MISC);
     }
+    if (info->flags & IS_DL10022) {
+       mdio_reset(nic_base + DLINK_GPIO, 0);
+       /* Restart MII autonegotiation */
+       mdio_write(nic_base + DLINK_GPIO, 0, 0, 0x0000);
+       mdio_write(nic_base + DLINK_GPIO, 0, 0, 0x1200);
+    }
 }
 
 /*====================================================================*/
@@ -914,8+996,7 @@ static int pcnet_open(struct net_device *dev)
     set_misc_reg(dev);
     request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev);
 
-    /* Start by assuming the link is bad */
-    info->link_status = 1;
+    info->link_status = 0x00;
     info->watchdog.function = &ei_watchdog;
     info->watchdog.data = (u_long)info;
     info->watchdog.expires = jiffies + HZ;
@@ -1008,13+1089,14 @@ static void ei_watchdog(u_long arg)
     pcnet_dev_t *info = (pcnet_dev_t *)(arg);
     struct net_device *dev = &info->dev;
     ioaddr_t nic_base = dev->base_addr;
+    u_short link;
 
     if (!netif_device_present(dev)) goto reschedule;
 
     /* Check for pending interrupt with expired latency timer: with
        this, we can limp along even if the interrupt is blocked */
     outb_p(E8390_NODMA+E8390_PAGE0, nic_base + E8390_CMD);
-    if (info->stale++ && inb_p(nic_base + EN0_ISR)) {
+    if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) {
        if (!info->fast_poll)
            printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
        ei_irq_wrapper(dev->irq, dev, NULL);
@@ -1027,15+1109,30 @@ static void ei_watchdog(u_long arg)
        return;
     }
 
-    if (info->flags & IS_DL10019) {
-       u_char link = inb(dev->base_addr+0x1c) & 0x01;
-       if (link != info->link_status) {
-           printk(KERN_INFO "%s: %s link beat\n", dev->name,
-                  (link) ? "lost" : "found");
-           if (!link)
-               NS8390_init(dev, 1);
-           info->link_status = link;
+    if (!(info->flags & IS_DL10019))
+       goto reschedule;
+
+    link = mdio_read(dev->base_addr + DLINK_GPIO, 0, 1) & 0x0004;
+    if (link != info->link_status) {
+       u_short p = mdio_read(dev->base_addr + DLINK_GPIO, 0, 5);
+       printk(KERN_INFO "%s: %s link beat\n", dev->name,
+              (link) ? "found" : "lost");
+       if (link && (info->flags & IS_DL10022)) {
+           /* Disable collision detection on full duplex links */
+           outb((p & 0x0140) ? 4 : 0, dev->base_addr + DLINK_DIAG);
+       }
+       if (link) {
+           if (p)
+               printk(KERN_INFO "%s: autonegotiation complete: "
+                      "%sbaseT-%cD selected\n", dev->name,
+                      ((p & 0x0180) ? "100" : "10"),
+                      ((p & 0x0140) ? 'F' : 'H'));
+           else
+               printk(KERN_INFO "%s: link partner did not autonegotiate\n",
+                      dev->name);
+           NS8390_init(dev, 1);
        }
+       info->link_status = link;
     }
 
 reschedule:
@@ -1043,83+1140,22 @@ reschedule:
     add_timer(&info->watchdog);
 }
 
-/*======================================================================
-
-    MII interface support for DL10019 based cards
-
-    There are two types of DL10019 based cards.  Some have the MII IO
-    direction bit as 0x10, others as 0x20; setting both bits seems to
-    work on all cards.
-
-======================================================================*/
-
-#define MDIO_SHIFT_CLK         0x80
-#define MDIO_DATA_OUT          0x40
-#define MDIO_DIR_WRITE         0x30
-#define MDIO_DATA_WRITE0       (MDIO_DIR_WRITE)
-#define MDIO_DATA_WRITE1       (MDIO_DIR_WRITE | MDIO_DATA_OUT)
-#define MDIO_DATA_READ         0x10
-#define MDIO_MASK              0x0f
-
-static void mdio_sync(ioaddr_t addr)
-{
-    int bits, mask = inb(addr) & MDIO_MASK;
-    for (bits = 0; bits < 32; bits++) {
-       outb(mask | MDIO_DATA_WRITE1, addr);
-       outb(mask | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, addr);
-    }
-}
-
-static int mdio_read(ioaddr_t addr, int phy_id, int loc)
-{
-    u_int cmd = (0x06<<10)|(phy_id<<5)|loc;
-    int i, retval = 0, mask = inb(addr) & MDIO_MASK;
-
-    mdio_sync(addr);
-    for (i = 13; i >= 0; i--) {
-       int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
-       outb(mask | dat, addr);
-       outb(mask | dat | MDIO_SHIFT_CLK, addr);
-    }
-    for (i = 19; i > 0; i--) {
-       outb(mask, addr);
-       retval = (retval << 1) | ((inb(addr) & MDIO_DATA_READ) != 0);
-       outb(mask | MDIO_SHIFT_CLK, addr);
-    }
-    return (retval>>1) & 0xffff;
-}
-
-static void mdio_write(ioaddr_t addr, int phy_id, int loc, int value)
-{
-    u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
-    int i, mask = inb(addr) & MDIO_MASK;
-
-    mdio_sync(addr);
-    for (i = 31; i >= 0; i--) {
-       int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
-       outb(mask | dat, addr);
-       outb(mask | dat | MDIO_SHIFT_CLK, addr);
-    }
-    for (i = 1; i >= 0; i--) {
-       outb(mask, addr);
-       outb(mask | MDIO_SHIFT_CLK, addr);
-    }
-}
+/*====================================================================*/
 
 static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
     u16 *data = (u16 *)&rq->ifr_data;
-    ioaddr_t addr = dev->base_addr + 0x1c;
+    ioaddr_t addr = dev->base_addr + DLINK_GPIO;
     switch (cmd) {
     case SIOCDEVPRIVATE:
        data[0] = 0;
     case SIOCDEVPRIVATE+1:
-       data[3] = mdio_read(addr, 0, data[1] & 0x1f);
+       data[3] = mdio_read(addr, data[0], data[1] & 0x1f);
        return 0;
     case SIOCDEVPRIVATE+2:
        if (!capable(CAP_NET_ADMIN))
            return -EPERM;
-       mdio_write(addr, 0, data[1] & 0x1f, data[2]);
+       mdio_write(addr, data[0], data[1] & 0x1f, data[2]);
        return 0;
     }
     return -EOPNOTSUPP;
index 4415239..0612ff8 100644 (file)
@@ -318,6+318,23 @@ static void cs_error(client_handle_t handle, int func, int ret)
     error_info_t err = { func, ret };
     pcmcia_report_error(handle, &err);
 }
+/*======================================================================
+
+    This bit of code is used to avoid unregistering network devices
+    at inappropriate times.  2.2 and later kernels are fairly picky
+    about when this can happen.
+    
+======================================================================*/
+
+static void flush_stale_links(void)
+{
+    dev_link_t *link, *next;
+    for (link = dev_list; link; link = next) {
+       next = link->next;
+       if (link->state & DEV_STALE_LINK)
+           ray_detach(link);
+    }
+}
 
 /*=============================================================================
     ray_attach() creates an "instance" of the driver, allocating
@@ -336,6+353,7 @@ static dev_link_t *ray_attach(void)
     struct net_device *dev;
     
     DEBUG(1, "ray_attach()\n");
+    flush_stale_links();
 
     /* Initialize the dev_link_t structure */
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
@@ -384,7+402,6 @@ static dev_link_t *ray_attach(void)
     
     dev->priv = local;
     local->finder = link;
-    link->dev = &local->node;
     local->card_status = CARD_INSERTED;
     local->authentication_state = UNAUTHENTICATED;
     local->num_multi = 0;
@@ -451,8+468,6 @@ fail_alloc_dev:
 static void ray_detach(dev_link_t *link)
 {
     dev_link_t **linkp;
-    struct net_device *dev;
-    long flags;
 
     DEBUG(1, "ray_detach(0x%p)\n", link);
     
@@ -462,19+477,12 @@ static void ray_detach(dev_link_t *link)
     if (*linkp == NULL)
         return;
 
-    save_flags(flags);
-    cli();
-    if (link->state & DEV_RELEASE_PENDING) {
-        del_timer(&link->release);
-        link->state &= ~DEV_RELEASE_PENDING;
-    }
-    restore_flags(flags);
-
     /* If the device is currently configured and active, we won't
       actually delete it yet.  Instead, it is marked so that when
       the release() function is called, that will trigger a proper
       detach().
     */
+    del_timer(&link->release);
     if (link->state & DEV_CONFIG) {
         ray_release((u_long)link);
         if(link->state & DEV_STALE_CONFIG) {
@@ -490,10+498,10 @@ static void ray_detach(dev_link_t *link)
     /* Unlink device structure, free pieces */
     *linkp = link->next;
     if (link->priv) {
-        dev = link->priv;
+        struct net_device *dev = link->priv;
+       if (link->dev) unregister_netdev(dev);
         if (dev->priv)
             kfree(dev->priv);
-
         kfree(link->priv);
     }
     kfree(link);
@@ -606,6+614,7 @@ static void ray_config(dev_link_t *link)
     }
 
     strcpy(local->node.dev_name, dev->name);
+    link->dev = &local->node;
 
     link->state &= ~DEV_CONFIG_PENDING;
     printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
@@ -907,9+916,7 @@ static void ray_release(u_long arg)
         return;
     }
     del_timer(&local->timer);
-    if (link->dev != '\0') unregister_netdev(dev);
-    /* Unlink the device chain */
-    link->dev = NULL;
+    link->state &= ~DEV_CONFIG;
 
     iounmap(local->sram);
     iounmap(local->rmem);
@@ -926,8+933,6 @@ static void ray_release(u_long arg)
     i = pcmcia_release_irq(link->handle, &link->irq);
     if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i);
 
-    link->state &= ~DEV_CONFIG;
-    if (link->state & DEV_STALE_LINK) ray_detach(link);
     DEBUG(2,"ray_release ending\n");
 } /* ray_release */
 /*=============================================================================
@@ -954,8+959,7 @@ static int ray_event(event_t event, int priority,
         link->state &= ~DEV_PRESENT;
         netif_device_detach(dev);
         if (link->state & DEV_CONFIG) {
-            link->release.expires = jiffies + HZ/20;
-            add_timer(&link->release);
+            mod_timer(&link->release, jiffies + HZ/20);
             del_timer(&local->timer);
         }
         break;
@@ -1006,7+1010,7 @@ int ray_dev_init(struct net_device *dev)
     if ( (i = dl_startup_params(dev)) < 0)
     {
         printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
-           "returns 0x%x/n",i);
+           "returns 0x%x\n",i);
         return -1;
     }
     
@@ -1554,11+1558,8 @@ static int ray_dev_close(struct net_device *dev)
 
     link->open--;
     netif_stop_queue(dev);
-    if (link->state & DEV_STALE_CONFIG) {
-        link->release.expires = jiffies + HZ/20;
-        link->state |= DEV_RELEASE_PENDING;
-        add_timer(&link->release);
-    }
+    if (link->state & DEV_STALE_CONFIG)
+       mod_timer(&link->release, jiffies + HZ/20);
 
     MOD_DEC_USE_COUNT;
 
@@ -2773,10+2774,9 @@ static void __exit exit_ray_cs(void)
 #endif
 
     unregister_pcmcia_driver(&dev_info);
-    while (dev_list != NULL) {
-        if (dev_list->state & DEV_CONFIG) ray_release((u_long)dev_list);
+    while (dev_list != NULL)
         ray_detach(dev_list);
-    }
+
 #ifdef CONFIG_PROC_FS
     remove_proc_entry("driver/ray_cs/ray_cs", NULL);
     remove_proc_entry("driver/ray_cs/essid", NULL);
index be17da0..76e9ff2 100644 (file)
     Megahertz, Motorola, Ositech, and Psion Dacom ethernet/modem
     multifunction cards.
 
-    Copyright (C) 1999 David A. Hinds -- dhinds@pcmcia.sourceforge.org
+    Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net
 
-    smc91c92_cs.c 1.96 2000/05/09 02:35:58
+    smc91c92_cs.c 1.104 2000/08/31 21:25:13
     
     This driver contains code written by Donald Becker
     (becker@cesdis.gsfc.nasa.gov), Rowan Hughes (x-csrdh@jcu.edu.au),
-    David Hinds (dhinds@pcmcia.sourceforge.org), and Erik Stahlman
+    David Hinds (dahinds@users.sourceforge.net), and Erik Stahlman
     (erik@vt.edu).  Donald wrote the SMC 91c92 code using parts of
     Erik's SMC 91c94 driver.  Rowan wrote a similar driver, and I've
     incorporated some parts of his driver here.  I (Dave) wrote most
@@ -635,11+635,12 @@ static void mot_config(dev_link_t *link)
     mdelay(100);
 }
 
-static int mot_setup(dev_link_t *link) {
+static int mot_setup(dev_link_t *link)
+{
     struct smc_private *smc = link->priv;
     struct net_device *dev = &smc->dev;
     ioaddr_t ioaddr = dev->base_addr;
-    int i, wait=0, loop;
+    int i, wait, loop;
     u_int addr;
 
     /* Read Ethernet address from Serial EEPROM */
@@ -650,7+651,7 @@ static int mot_setup(dev_link_t *link) {
        SMC_SELECT_BANK(1);
        outw((CTL_RELOAD | CTL_EE_SELECT), ioaddr + CONTROL);
 
-       for (loop = 0; loop < 200; loop++) {
+       for (loop = wait = 0; loop < 200; loop++) {
            udelay(10);
            wait = ((CTL_RELOAD | CTL_STORE) & inw(ioaddr + CONTROL));
            if (wait == 0) break;
@@ -751,7+752,7 @@ static int osi_config(dev_link_t *link)
     struct smc_private *smc = link->priv;
     struct net_device *dev = &smc->dev;
     static ioaddr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
-    int i=0, j;
+    int i, j;
     
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
@@ -765,7+766,7 @@ static int osi_config(dev_link_t *link)
     /* Enable Hard Decode, LAN, Modem */
     link->conf.ConfigIndex = 0x23;
     
-    for (j = 0; j < 4; j++) {
+    for (i = j = 0; j < 4; j++) {
        link->io.BasePort2 = com[j];
        i = CardServices(RequestIO, link->handle, &link->io);
        if (i == CS_SUCCESS) break;
@@ -808,15+809,16 @@ static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid)
     for (i = 0; i < 6; i++)
        dev->dev_addr[i] = buf[i+2];
 
-    if (manfid != MANFID_OSITECH) return 0;
-
-    if (cardid == PRODID_OSITECH_SEVEN) {
+    if (((manfid == MANFID_OSITECH) &&
+        (cardid == PRODID_OSITECH_SEVEN)) ||
+       ((manfid == MANFID_PSION) &&
+        (cardid == PRODID_PSION_NET100))) {
        /* Download the Seven of Diamonds firmware */
        for (i = 0; i < sizeof(__Xilinx7OD); i++) {
            outb(__Xilinx7OD[i], link->io.BasePort1+2);
            udelay(50);
        }
-    } else {
+    } else if (manfid == MANFID_OSITECH) {
        /* Make sure both functions are powered up */
        set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
        /* Now, turn on the interrupt for both card functions */
@@ -927,7+929,8 @@ static void smc91c92_config(dev_link_t *link)
     /* Configure card */
     link->state |= DEV_CONFIG;
 
-    if (smc->manfid == MANFID_OSITECH) {
+    if ((smc->manfid == MANFID_OSITECH) &&
+       (smc->cardid != PRODID_OSITECH_SEVEN)) {
        i = osi_config(link);
     } else if ((smc->manfid == MANFID_MOTOROLA) ||
               ((smc->manfid == MANFID_MEGAHERTZ) &&
@@ -1001,7+1004,7 @@ static void smc91c92_config(dev_link_t *link)
     for (i = 0; i < 6; i++)
        printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
     if (rev > 0) {
-       u_long mir, mcr, mii;
+       u_long mir, mcr;
        ioaddr_t ioaddr = dev->base_addr;
        SMC_SELECT_BANK(0);
        mir = inw(ioaddr + MEMINFO) & 0xff;
@@ -1014,8+1017,14 @@ static void smc91c92_config(dev_link_t *link)
        else
            printk(KERN_INFO "  %lu kb", mir>>10);
        SMC_SELECT_BANK(1);
-       mii = inw(ioaddr + CONFIG) & CFG_MII_SELECT;
-       printk(" buffer, %s xcvr\n", mii ? "MII" : if_names[dev->if_port]);
+       smc->cfg = inw(ioaddr + CONFIG) & ~CFG_AUI_SELECT;
+       smc->cfg |= CFG_NO_WAIT | CFG_16BIT | CFG_STATIC;
+       if (smc->manfid == MANFID_OSITECH)
+           smc->cfg |= CFG_IRQ_SEL_1 | CFG_IRQ_SEL_0;
+       if ((rev >> 4) >= 7)
+           smc->cfg |= CFG_MII_SELECT;
+       printk(" buffer, %s xcvr\n", (smc->cfg & CFG_MII_SELECT) ?
+              "MII" : if_names[dev->if_port]);
     }
     
     return;
@@ -1321,7+1330,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
     DEBUG(2, "%s: smc91c92_start_xmit(length = %d) called,"
          " status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2));
-
+    
     if (smc->saved_skb) {
        /* THIS SHOULD NEVER HAPPEN. */
        smc->stats.tx_aborted_errors++;
@@ -1808,9+1817,6 @@ static void smc_reset(struct net_device *dev)
        Accept link errors, counter and Tx error interrupts. */
     outw(CTL_AUTO_RELEASE | CTL_TE_ENABLE | CTL_CR_ENABLE,
         ioaddr + CONTROL);
-    smc->cfg = inw(ioaddr + CONFIG) & ~CFG_AUI_SELECT;
-    smc->cfg |= CFG_NO_WAIT | CFG_16BIT | CFG_STATIC |
-       (smc->manfid == MANFID_OSITECH ? (CFG_IRQ_SEL_1 | CFG_IRQ_SEL_0) : 0);
     smc_set_xcvr(dev, dev->if_port);
     if ((smc->manfid == MANFID_OSITECH) &&
        (smc->cardid != PRODID_OSITECH_SEVEN))
index 289d1bc..cf98d74 100644 (file)
  * Xircom CreditCard Ethernet Adapter IIps driver
  * Xircom Realport 10/100 (RE-100) driver 
  *
- * This driver originally was made by Werner Koch. Since the driver was left
- * unmaintained for some time, there have been some improvements and changes
- * since. These include supporting some of the "Realport" cards and develop-
- * ing enhancements to support the new ones.
- * It is made for CE2, CEM28, CEM33, CE33 and 
- * CEM56 cards. The CEM56 cards work both with their modem and ethernet
- * interface. The RealPort 10/100 Modem and similar cards are supported but
- * with some bugs which are being corrected as they are detected. 
+ * This driver supports various Xircom CreditCard Ethernet adapters
+ * including the CE2, CE IIps, RE-10, CEM28, CEM33, CE33, CEM56,
+ * CE3-100, CE3B, RE-100, REM10BT, and REM56G-100.
  * 
- * Code revised and maintained by Allan Baker Ortegon
- * al527261@prodigy.net.mx
  * Written originally by Werner Koch based on David Hinds' skeleton of the
- * PCMCIA driver. The code has been modified as to make the newer cards
- * available.
+ * PCMCIA driver.
  *
- * The latest code for the driver, information on the development project
- * for the Xircom RealPort and CE cards for the PCMCIA driver, and other
- * related material, can be found at the following URL, which is underway:
- * 
- * "http://xirc2ps.linuxbox.com/index.html"
- *
- * Any bugs regarding this driver, please send them to:
- * alanyuu@linuxbox.com
- *
- * The driver is still evolving and there are many cards which will benefit
- * from having alpha testers. If you have a particular card and would like
- * to be involved in this ongoing effort, please send mail to the maintainer.
- * 
- * Special thanks to David Hinds, to Xircom for the specifications and their
- * software development kit, and all others who may have colaborated in the
- * development of the driver: Koen Van Herck (Koen.Van.Herck@xircom.com),
- * 4PC GmbH Duesseldorf, David Luger, et al.
- * 
- *
- ************************************************************************
  * Copyright (c) 1997,1998 Werner Koch (dd9jn)
- * Copyright (c) 1999 Allan Baker Ortegon 
  *
  * This driver is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* Enable the bug fix for CEM56 to use modem and ethernet simultaneously */
-#define CEM56_FIX
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ciscode.h>
 
-#ifndef MANFID_XIRCOM
-  #define MANFID_XIRCOM           0x0105
-#endif
 #ifndef MANFID_COMPAQ
   #define MANFID_COMPAQ           0x0138
   #define MANFID_COMPAQ2          0x0183  /* is this correct? */
 #endif
-#ifndef MANFID_INTEL
-  #define MANFID_INTEL            0x0089
-#endif
 
 #include <pcmcia/ds.h>
 
@@ -936,26+898,26 @@ xirc2ps_config(dev_link_t * link)
     switch(parse.manfid.manf) {
       case MANFID_XIRCOM:
        local->manf_str = "Xircom";
-       DEBUG(0, "found xircom card\n");
        break;
       case MANFID_ACCTON:
        local->manf_str = "Accton";
-       DEBUG(0, "found Accton card\n");
        break;
       case MANFID_COMPAQ:
       case MANFID_COMPAQ2:
        local->manf_str = "Compaq";
-       DEBUG(0, "found Compaq card\n");
        break;
       case MANFID_INTEL:
        local->manf_str = "Intel";
-       DEBUG(0, "found Intel card\n");
+       break;
+      case MANFID_TOSHIBA:
+       local->manf_str = "Toshiba";
        break;
       default:
        printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",
               (unsigned)parse.manfid.manf);
        goto failure;
     }
+    DEBUG(0, "found %s card\n", local->manf_str);
 
     if (!set_card_type(link, buf)) {
        printk(KNOT_XIRC "this card is not supported\n");
@@ -1120,13+1082,10 @@ xirc2ps_config(dev_link_t * link)
     }
 
     if (local->dingo) {
-      #ifdef CEM56_FIX
        conf_reg_t reg;
-      #endif
        win_req_t req;
        memreq_t mem;
 
-      #ifdef CEM56_FIX
        /* Reset the modem's BAR to the correct value
         * This is necessary because in the RequestConfiguration call,
         * the base address of the ethernet port (BasePort1) is written
@@ -1148,7+1107,6 @@ xirc2ps_config(dev_link_t * link)
            cs_error(link->handle, AccessConfigurationRegister, err);
            goto config_error;
        }
-     #endif
 
        /* There is no config entry for the Ethernet part which
         * is at 0x0800. So we allocate a window into the attribute
@@ -1227,9+1185,9 @@ xirc2ps_config(dev_link_t * link)
        goto config_error;
     }
 
-    link->state &= ~DEV_CONFIG_PENDING;
     strcpy(local->node.dev_name, dev->name);
     link->dev = &local->node;
+    link->state &= ~DEV_CONFIG_PENDING;
 
     if (local->dingo)
        do_reset(dev, 1); /* a kludge to make the cem56 work */
index be015f1..130f6b2 100644 (file)
@@ -1043,9+1043,10 @@ static inline int cosa_download(struct cosa_data *cosa, struct cosa_download *d)
                return -EPERM;
        }
 
-       get_user_ret(addr, &(d->addr), -EFAULT);
-       get_user_ret(len, &(d->len), -EFAULT);
-       get_user_ret(code, &(d->code), -EFAULT);
+       if (get_user(addr, &(d->addr)) ||
+           __get_user(len, &(d->len)) ||
+           __get_user(code, &(d->code)))
+               return -EFAULT;
 
        if (d->addr < 0 || d->addr > COSA_MAX_FIRMWARE_SIZE)
                return -EINVAL;
@@ -1083,9+1084,10 @@ static inline int cosa_readmem(struct cosa_data *cosa, struct cosa_download *d)
                return -EPERM;
        }
 
-       get_user_ret(addr, &(d->addr), -EFAULT);
-       get_user_ret(len, &(d->len), -EFAULT);
-       get_user_ret(code, &(d->code), -EFAULT);
+       if (get_user(addr, &(d->addr)) ||
+           __get_user(len, &(d->len)) ||
+           __get_user(code, &(d->code)))
+               return -EFAULT;
 
        /* If something fails, force the user to reset the card */
        cosa->firmware_status &= ~COSA_FW_RESET;
@@ -1133,7+1135,8 @@ static inline int cosa_start(struct cosa_data *cosa, int address)
 static inline int cosa_getidstr(struct cosa_data *cosa, char *string)
 {
        int l = strlen(cosa->id_string)+1;
-       copy_to_user_ret(string, cosa->id_string, l, -EFAULT);
+       if (copy_to_user(string, cosa->id_string, l))
+               return -EFAULT;
        return l;
 }
 
@@ -1141,7+1144,8 @@ static inline int cosa_getidstr(struct cosa_data *cosa, char *string)
 static inline int cosa_gettype(struct cosa_data *cosa, char *string)
 {
        int l = strlen(cosa->type)+1;
-       copy_to_user_ret(string, cosa->type, l, -EFAULT);
+       if (copy_to_user(string, cosa->type, l))
+               return -EFAULT;
        return l;
 }
 
@@ -1429,7+1433,8 @@ static int download(struct cosa_data *cosa, char *microcode, int length, int add
        while (length--) {
                char c;
 #ifndef SRP_DOWNLOAD_AT_BOOT
-               get_user_ret(c,microcode, -23);
+               if (get_user(c, microcode))
+                       return -23; /* ??? */
 #else
                c = *microcode;
 #endif
@@ -1507,7+1512,8 @@ static int readmem(struct cosa_data *cosa, char *microcode, int length, int addr
                }
                c=i;
 #if 1
-               put_user_ret(c,microcode, -23);
+               if (put_user(c, microcode))
+                       return -23; /* ??? */
 #else
                *microcode = c;
 #endif
index 43e47c7..e20918a 100644 (file)
@@ -2,7+2,7 @@
 
     PCMCIA Bulk Memory Services
 
-    bulkmem.c 1.34 1999/11/17 01:37:55
+    bulkmem.c 1.37 2000/06/12 21:29:35
 
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     rights and limitations under the License.
 
     The initial developer of the original code is David A. Hinds
-    <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
 static int do_mtd_request(memory_handle_t handle, mtd_request_t *req,
                          caddr_t buf)
 {
-    int ret=0, tries;
+    int ret, tries;
     client_t *mtd;
     socket_info_t *s;
     
@@ -70,7+70,7 @@ static int do_mtd_request(memory_handle_t handle, mtd_request_t *req,
     if (mtd == NULL)
        return CS_GENERAL_FAILURE;
     s = SOCKET(mtd);
-    for (tries = 0; tries < 100; tries++) {
+    for (ret = tries = 0; tries < 100; tries++) {
        mtd->event_callback_args.mtdrequest = req;
        mtd->event_callback_args.buffer = buf;
        ret = EVENT(mtd, CS_EVENT_MTD_REQUEST, CS_EVENT_PRI_LOW);
index 92ecb49..0216ed2 100644 (file)
@@ -232,21+232,6 @@ fail:
     
 =====================================================================*/
 
-static int cb_assign_irq(u32 mask)
-{
-       int irq, try;
-
-       for (try = 0; try < 2; try++) {
-               for (irq = 1; irq < 32; irq++) {
-                       if ((mask >> irq) & 1) {
-                               if (try_irq(IRQ_TYPE_EXCLUSIVE, irq, try) == 0)
-                                       return irq;
-                       }
-               }
-       }
-       return 0;
-}
-
 int cb_alloc(socket_info_t * s)
 {
        struct pci_bus *bus;
@@ -310,8+295,6 @@ int cb_alloc(socket_info_t * s)
                /* Does this function have an interrupt at all? */
                pci_readb(dev, PCI_INTERRUPT_PIN, &irq_pin);
                if (irq_pin) {
-                       if (!irq)
-                               irq = cb_assign_irq(s->cap.irq_mask);
                        dev->irq = irq;
                        pci_writeb(dev, PCI_INTERRUPT_LINE, irq);
                }
@@ -369,14+352,7 @@ int cb_config(socket_info_t * s)
 
 void cb_release(socket_info_t * s)
 {
-       cb_config_t *c = s->cb_config;
-
        DEBUG(0, "cs: cb_release(bus %d)\n", s->cap.cb_dev->subordinate->number);
-
-#ifdef CONFIG_ISA
-       if ((c[0].dev.irq != 0) && (c[0].dev.irq != s->cap.pci_irq))
-               undo_irq(IRQ_TYPE_EXCLUSIVE, c[0].dev.irq);
-#endif
 }
 
 /*=====================================================================
index 0e5ddeb..a4d81a6 100644 (file)
@@ -2,7+2,7 @@
 
     CardBus device enabler
 
-    cb_enabler.c 1.28 1999/12/09 20:57:37
+    cb_enabler.c 1.31 2000/06/12 21:29:36
 
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     rights and limitations under the License.
 
     The initial developer of the original code is David A. Hinds
-    <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
@@ -58,12+58,12 @@ static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"cb_enabler.c 1.28 1999/12/09 20:57:37 (David Hinds)";
+"cb_enabler.c 1.31 2000/06/12 21:29:36 (David Hinds)";
 #else
 #define DEBUG(n, args...) do { } while (0)
 #endif
 
-MODULE_AUTHOR("David Hinds <dhinds@pcmcia.sourceforge.org>");
+MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("CardBus stub enabler module");
 
 /*====================================================================*/
@@ -168,9+168,9 @@ static void cb_detach(dev_link_t *link)
     driver_info_t *dev = link->priv;
     dev_link_t **linkp;
     bus_info_t *b = (void *)link->win;
-    
+
     DEBUG(0, "cb_detach(0x%p)\n", link);
-    
+
     /* Locate device structure */
     for (linkp = &dev->dev_list; *linkp; linkp = &(*linkp)->next)
        if (*linkp == link) break;
@@ -179,16+179,16 @@ static void cb_detach(dev_link_t *link)
 
     if (link->state & DEV_CONFIG)
        cb_release((u_long)link);
-    
+
     /* Don't drop Card Services connection if we are the bus owner */
-    if ((b->flags != 0) && (link == b->owner)) {
+    if (b && (b->flags != 0) && (link == b->owner)) {
        link->state |= DEV_STALE_LINK;
        return;
     }
-    
+
     if (link->handle)
        pcmcia_deregister_client(link->handle);
-    
+
     *linkp = link->next;
     kfree(link);
     MOD_DEC_USE_COUNT;
index acca173..3f9fb1c 100644 (file)
@@ -2,7+2,7 @@
 
     PCMCIA Card Information Structure parser
 
-    cistpl.c 1.77 2000/01/16 19:19:01
+    cistpl.c 1.90 2000/08/30 20:23:47
 
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     rights and limitations under the License.
 
     The initial developer of the original code is David A. Hinds
-    <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
@@ -77,6+77,14 @@ static const u_int exponent[] = {
 /* Upper limit on reasonable # of tuples */
 #define MAX_TUPLES             200
 
+/*====================================================================*/
+
+/* Parameters that can be set with 'insmod' */
+
+#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
+
+INT_MODULE_PARM(cis_width,     0);             /* 16-bit CIS? */
+
 /*======================================================================
 
     Low-level functions to read and write CIS memory.  I think the
@@ -88,6+96,17 @@ static const u_int exponent[] = {
 #define IS_ATTR                1
 #define IS_INDIRECT    8
 
+static void set_cis_map(socket_info_t *s, pccard_mem_map *mem)
+{
+    s->ss_entry->set_mem_map(s->sock, mem);
+    if (s->cap.features & SS_CAP_STATIC_MAP) {
+       if (s->cis_virt)
+           bus_iounmap(s->cap.bus, s->cis_virt);
+       s->cis_virt = bus_ioremap(s->cap.bus, mem->sys_start,
+                                 s->cap.map_size);
+    }
+}
+
 void read_cis_mem(socket_info_t *s, int attr, u_int addr,
                  u_int len, void *ptr)
 {
@@ -99,16+118,17 @@ void read_cis_mem(socket_info_t *s, int attr, u_int addr,
        memset(ptr, 0xff, len);
        return;
     }
-    mem->flags |= MAP_ACTIVE; mem->flags &= ~MAP_ATTRIB;
-    sys = s->cis_virt;
+    mem->flags = MAP_ACTIVE;
+    if (cis_width) mem->flags |= MAP_16BIT;
 
     if (attr & IS_INDIRECT) {
        /* Indirect accesses use a bunch of special registers at fixed
           locations in common memory */
        u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
        if (attr & IS_ATTR) { addr *= 2; flags = ICTRL0_AUTOINC; }
-       mem->card_start = 0;
-       s->ss_entry->set_mem_map(s->sock, mem);
+       mem->card_start = 0; mem->flags = MAP_ACTIVE;
+       set_cis_map(s, mem);
+       sys = s->cis_virt;
        bus_writeb(s->cap.bus, flags, sys+CISREG_ICTRL0);
        bus_writeb(s->cap.bus, addr & 0xff, sys+CISREG_IADDR0);
        bus_writeb(s->cap.bus, (addr>>8) & 0xff, sys+CISREG_IADDR1);
@@ -121,14+141,15 @@ void read_cis_mem(socket_info_t *s, int attr, u_int addr,
        if (attr) { mem->flags |= MAP_ATTRIB; inc++; addr *= 2; }
        sys += (addr & (s->cap.map_size-1));
        mem->card_start = addr & ~(s->cap.map_size-1);
-
-       for (; len > 0; sys = s->cis_virt) {
-           s->ss_entry->set_mem_map(s->sock, mem);
+       while (len) {
+           set_cis_map(s, mem);
+           sys = s->cis_virt + (addr & (s->cap.map_size-1));
            for ( ; len > 0; len--, buf++, sys += inc) {
                if (sys == s->cis_virt+s->cap.map_size) break;
                *buf = bus_readb(s->cap.bus, sys);
            }
            mem->card_start += s->cap.map_size;
+           addr = 0;
        }
     }
     DEBUG(3, "cs:  %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
@@ -144,16+165,17 @@ void write_cis_mem(socket_info_t *s, int attr, u_int addr,
     
     DEBUG(3, "cs: write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
     if (setup_cis_mem(s) != 0) return;
-    mem->flags |= MAP_ACTIVE; mem->flags &= ~MAP_ATTRIB;
-    sys = s->cis_virt;
+    mem->flags = MAP_ACTIVE;
+    if (cis_width) mem->flags |= MAP_16BIT;
 
     if (attr & IS_INDIRECT) {
        /* Indirect accesses use a bunch of special registers at fixed
           locations in common memory */
        u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
        if (attr & IS_ATTR) { addr *= 2; flags = ICTRL0_AUTOINC; }
-       mem->card_start = 0;
-       s->ss_entry->set_mem_map(s->sock, mem);
+       mem->card_start = 0; mem->flags = MAP_ACTIVE;
+       set_cis_map(s, mem);
+       sys = s->cis_virt;
        bus_writeb(s->cap.bus, flags, sys+CISREG_ICTRL0);
        bus_writeb(s->cap.bus, addr & 0xff, sys+CISREG_IADDR0);
        bus_writeb(s->cap.bus, (addr>>8) & 0xff, sys+CISREG_IADDR1);
@@ -164,16+186,16 @@ void write_cis_mem(socket_info_t *s, int attr, u_int addr,
     } else {
        int inc = 1;
        if (attr & IS_ATTR) { mem->flags |= MAP_ATTRIB; inc++; addr *= 2; }
-       sys += (addr & (s->cap.map_size-1));
        mem->card_start = addr & ~(s->cap.map_size-1);
-
-       for (; len > 0; sys = s->cis_virt) {
-           s->ss_entry->set_mem_map(s->sock, mem);
+       while (len) {
+           set_cis_map(s, mem);
+           sys = s->cis_virt + (addr & (s->cap.map_size-1));
            for ( ; len > 0; len--, buf++, sys += inc) {
                if (sys == s->cis_virt+s->cap.map_size) break;
                bus_writeb(s->cap.bus, *buf, sys);
            }
            mem->card_start += s->cap.map_size;
+           addr = 0;
        }
     }
 }
@@ -238,7+260,8 @@ static int checksum_match(u_long base)
 
 int setup_cis_mem(socket_info_t *s)
 {
-    if (s->cis_mem.sys_start == 0) {
+    if (!(s->cap.features & SS_CAP_STATIC_MAP) &&
+       (s->cis_mem.sys_start == 0)) {
        int low = !(s->cap.features & SS_CAP_PAGE_REGS);
        vs = s;
        validate_mem(cis_readable, checksum_match, low);
@@ -262,9+285,11 @@ void release_cis_mem(socket_info_t *s)
     if (s->cis_mem.sys_start != 0) {
        s->cis_mem.flags &= ~MAP_ACTIVE;
        s->ss_entry->set_mem_map(s->sock, &s->cis_mem);
-       release_mem_region(s->cis_mem.sys_start, s->cap.map_size);
+       if (!(s->cap.features & SS_CAP_STATIC_MAP))
+           release_mem_region(s->cis_mem.sys_start, s->cap.map_size);
        bus_iounmap(s->cap.bus, s->cis_virt);
        s->cis_mem.sys_start = 0;
+       s->cis_virt = NULL;
     }
 }
 
@@ -1278,6+1303,25 @@ static int parse_org(tuple_t *tuple, cistpl_org_t *org)
 
 /*====================================================================*/
 
+static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
+{
+    u_char *p;
+
+    if (tuple->TupleDataLen < 10)
+       return CS_BAD_TUPLE;
+
+    p = tuple->TupleData;
+
+    fmt->type = p[0];
+    fmt->edc = p[1];
+    fmt->offset = le32_to_cpu(*(u_int *)(p+2));
+    fmt->length = le32_to_cpu(*(u_int *)(p+6));
+
+    return CS_SUCCESS;
+}
+
+/*====================================================================*/
+
 int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
 {
     int ret = CS_SUCCESS;
@@ -1345,6+1389,10 @@ int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse
     case CISTPL_ORG:
        ret = parse_org(tuple, &parse->org);
        break;
+    case CISTPL_FORMAT:
+    case CISTPL_FORMAT_A:
+       ret = parse_format(tuple, &parse->format);
+       break;
     case CISTPL_NO_LINK:
     case CISTPL_LINKTARGET:
        ret = CS_SUCCESS;
@@ -1395,34+1443,36 @@ int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
 {
     tuple_t tuple;
     cisparse_t p;
-    int ret, reserved, errors;
-    
+    int ret, reserved, dev_ok = 0, ident_ok = 0;
+
     if (CHECK_HANDLE(handle))
        return CS_BAD_HANDLE;
-    
-    info->Chains = reserved = errors = 0;
+
+    info->Chains = reserved = 0;
     tuple.DesiredTuple = RETURN_FIRST_TUPLE;
     tuple.Attributes = TUPLE_RETURN_COMMON;
     ret = pcmcia_get_first_tuple(handle, &tuple);
     if (ret != CS_SUCCESS)
        return CS_SUCCESS;
 
-    /* First tuple should be DEVICE */
-    if (tuple.TupleCode != CISTPL_DEVICE)
-       errors++;
-    /* All cards should have a MANFID tuple */
-    if (read_tuple(handle, CISTPL_MANFID, &p) != CS_SUCCESS)
-       errors++;
-    /* All cards should have either a VERS_1 or a VERS_2 tuple.  But
-       at worst, we'll accept a CFTABLE_ENTRY that parses. */
-    if ((read_tuple(handle, CISTPL_VERS_1, &p) != CS_SUCCESS) &&
-       (read_tuple(handle, CISTPL_VERS_2, &p) != CS_SUCCESS) &&
-       (read_tuple(handle, CISTPL_CFTABLE_ENTRY, &p) != CS_SUCCESS) &&
-       (read_tuple(handle, CISTPL_CFTABLE_ENTRY_CB, &p) != CS_SUCCESS))
-       errors++;
-    if (errors > 1)
+    /* First tuple should be DEVICE; we should really have either that
+       or a CFTABLE_ENTRY of some sort */
+    if ((tuple.TupleCode == CISTPL_DEVICE) ||
+       (read_tuple(handle, CISTPL_CFTABLE_ENTRY, &p) == CS_SUCCESS) ||
+       (read_tuple(handle, CISTPL_CFTABLE_ENTRY_CB, &p) == CS_SUCCESS))
+       dev_ok++;
+
+    /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
+       tuple, for card identification.  Certain old D-Link and Linksys
+       cards have only a broken VERS_2 tuple; hence the bogus test. */
+    if ((read_tuple(handle, CISTPL_MANFID, &p) == CS_SUCCESS) ||
+       (read_tuple(handle, CISTPL_VERS_1, &p) == CS_SUCCESS) ||
+       (read_tuple(handle, CISTPL_VERS_2, &p) != CS_NO_MORE_ITEMS))
+       ident_ok++;
+
+    if (!dev_ok && !ident_ok)
        return CS_SUCCESS;
-    
+
     for (info->Chains = 1; info->Chains < MAX_TUPLES; info->Chains++) {
        ret = pcmcia_get_next_tuple(handle, &tuple);
        if (ret != CS_SUCCESS) break;
@@ -1431,9+1481,10 @@ int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
            ((tuple.TupleCode > 0x90) && (tuple.TupleCode < 0xff)))
            reserved++;
     }
-    if ((info->Chains == MAX_TUPLES) || (reserved > 5))
+    if ((info->Chains == MAX_TUPLES) || (reserved > 5) ||
+       ((!dev_ok || !ident_ok) && (info->Chains > 10)))
        info->Chains = 0;
-    
+
     return CS_SUCCESS;
 }
 
index 93228e5..547a180 100644 (file)
@@ -2,7+2,7 @@
 
     PCMCIA Card Services -- core services
 
-    cs.c 1.249 2000/02/10 23:26:11
+    cs.c 1.267 2000/08/30 22:07:31
     
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     rights and limitations under the License.
 
     The initial developer of the original code is David A. Hinds
-    <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
 int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 static const char *version =
-"cs.c 1.249 2000/02/10 23:26:11 (David Hinds)";
+"cs.c 1.267 2000/08/30 22:07:31 (David Hinds)";
 #endif
 
 #ifdef CONFIG_PCI
@@ -93,7+93,7 @@ static const char *version =
 static const char *release = "Linux PCMCIA Card Services " CS_RELEASE;
 static const char *options = "options: " OPTIONS;
 
-MODULE_AUTHOR("David Hinds <dhinds@pcmcia.sourceforge.org>");
+MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("Linux PCMCIA Card Services " CS_RELEASE
                   "\n  options:" OPTIONS);
 
@@ -773,6+773,13 @@ static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base,
              *base, align);
        align = 0;
     }
+    /* Check for an already-allocated window that must conflict with
+       what was asked for.  It is a hack because it does not catch all
+       potential conflicts, just the most obvious ones. */
+    for (i = 0; i < MAX_IO_WIN; i++)
+       if ((s->io[i].NumPorts != 0) &&
+           ((s->io[i].BasePort & (align-1)) == *base))
+           return 1;
     for (i = 0; i < MAX_IO_WIN; i++) {
        if (s->io[i].NumPorts == 0) {
            if (find_io_region(base, num, align, name) == 0) {
@@ -1676,11+1683,13 @@ int pcmcia_request_configuration(client_handle_t handle,
        write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy);
     }
     if (req->Present & PRESENT_OPTION) {
-       if (s->functions == 1)
+       if (s->functions == 1) {
            c->Option = req->ConfigIndex & COR_CONFIG_MASK;
-       else {
+       else {
            c->Option = req->ConfigIndex & COR_MFC_CONFIG_MASK;
-           c->Option |= COR_FUNC_ENA|COR_ADDR_DECODE|COR_IREQ_ENA;
+           c->Option |= COR_FUNC_ENA|COR_IREQ_ENA;
+           if (req->Present & PRESENT_IOBASE_0)
+               c->Option |= COR_ADDR_DECODE;
        }
        if (c->state & CONFIG_IRQ_REQ)
            if (!(c->irq.Attributes & IRQ_FORCED_PULSE))
@@ -1829,8+1838,8 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
     if (c->state & CONFIG_IRQ_REQ)
        return CS_IN_USE;
     
-    /* Short cut: if the interrupt is PCI, there are no options */
-    if (s->cap.irq_mask == (1 << s->cap.pci_irq))
+    /* Short cut: if there are no ISA interrupts, then it is PCI */
+    if (!s->cap.irq_mask)
        irq = s->cap.pci_irq;
 #ifdef CONFIG_ISA
     else if (s->irq.AssignedIRQ != 0) {
@@ -1845,7+1854,6 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
        ret = CS_IN_USE;
        if (req->IRQInfo1 & IRQ_INFO2_VALID) {
            mask = req->IRQInfo2 & s->cap.irq_mask;
-           mask &= ~(1 << s->cap.pci_irq);
            for (try = 0; try < 2; try++) {
                for (irq = 0; irq < 32; irq++)
                    if ((mask >> irq) & 1) {
@@ -1910,11+1918,12 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
             req->Size : s->cap.map_size);
     if (req->Size & (s->cap.map_size-1))
        return CS_BAD_SIZE;
-    if (req->Base & (align-1))
+    if ((req->Base && (s->cap.features & SS_CAP_STATIC_MAP)) ||
+       (req->Base & (align-1)))
        return CS_BAD_BASE;
     if (req->Base)
        align = 0;
-    
+
     /* Allocate system memory window */
     for (w = 0; w < MAX_WIN; w++)
        if (!(s->state & SOCKET_WIN_REQ(w))) break;
@@ -1928,13+1937,13 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
     win->sock = s;
     win->base = req->Base;
     win->size = req->Size;
-       
-    if (find_mem_region(&win->base, win->size, align,
+
+    if (!(s->cap.features & SS_CAP_STATIC_MAP) &&
+       find_mem_region(&win->base, win->size, align,
                        (req->Attributes & WIN_MAP_BELOW_1MB) ||
                        !(s->cap.features & SS_CAP_PAGE_REGS),
                        (*handle)->dev_info))
        return CS_IN_USE;
-    req->Base = win->base;
     (*handle)->state |= CLIENT_WIN_REQ(w);
 
     /* Configure the socket controller */
@@ -1949,14+1958,15 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
        win->ctl.flags |= MAP_16BIT;
     if (req->Attributes & WIN_USE_WAIT)
        win->ctl.flags |= MAP_USE_WAIT;
-    win->ctl.sys_start = req->Base;
-    win->ctl.sys_stop = req->Base + req->Size-1;
+    win->ctl.sys_start = win->base;
+    win->ctl.sys_stop = win->base + win->size-1;
     win->ctl.card_start = 0;
     if (set_mem_map(s, &win->ctl) != 0)
        return CS_BAD_ARGS;
     s->state |= SOCKET_WIN_REQ(w);
 
     /* Return window handle */
+    req->Base = win->ctl.sys_start;
     *wh = win;
     
     return CS_SUCCESS;
@@ -2168,7+2178,7 @@ int CardServices(int func, void *a1, void *a2, void *a3)
 {
 
 #ifdef PCMCIA_DEBUG
-    if (pc_debug > 1) {
+    if (pc_debug > 2) {
        int i;
        for (i = 0; i < SERVICE_COUNT; i++)
            if (service_table[i].key == func) break;
index a1373f9..47efc86 100644 (file)
@@ -1,5+1,5 @@
 /*
- * cs_internal.h 1.46 1999/11/08 20:46:49
+ * cs_internal.h 1.52 2000/06/12 21:29:37
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  *  are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  */
 
index a2a9632..02c6898 100644 (file)
@@ -2,7+2,7 @@
 
     PC Card Driver Services
     
-    ds.c 1.104 2000/01/11 01:18:02
+    ds.c 1.108 2000/08/07 19:06:15
     
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     rights and limitations under the License.
 
     The initial developer of the original code is David A. Hinds
-    <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
@@ -61,12+61,12 @@ int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static const char *version =
-"ds.c 1.104 2000/01/11 01:18:02 (David Hinds)";
+"ds.c 1.108 2000/08/07 19:06:15 (David Hinds)";
 #else
 #define DEBUG(n, args...)
 #endif
 
-MODULE_AUTHOR("David Hinds <dhinds@pcmcia.sourceforge.org>");
+MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("PCMCIA Driver Services " CS_RELEASE);
 
 /*====================================================================*/
@@ -81,6+81,7 @@ typedef struct driver_info_t {
 
 typedef struct socket_bind_t {
     driver_info_t      *driver;
+    u_char             function;
     dev_link_t         *instance;
     struct socket_bind_t *next;
 } socket_bind_t;
@@ -391,7+392,8 @@ static int bind_request(int i, bind_info_t *bind_info)
     }
 
     for (b = s->bind; b; b = b->next)
-       if (driver == b->driver)
+       if ((driver == b->driver) &&
+           (bind_info->function == b->function))
            break;
     if (b != NULL) {
        bind_info->instance = b->instance;
@@ -413,6+415,7 @@ static int bind_request(int i, bind_info_t *bind_info)
     driver->use_count++;
     b = kmalloc(sizeof(socket_bind_t), GFP_KERNEL);
     b->driver = driver;
+    b->function = bind_info->function;
     b->instance = NULL;
     b->next = s->bind;
     s->bind = b;
@@ -475,16+478,14 @@ static int get_device_info(int i, bind_info_t *bind_info, int first)
 #endif
 
     for (b = s->bind; b; b = b->next)
-       if (strcmp((char *)b->driver->dev_info,
-                  (char *)bind_info->dev_info) == 0)
+       if ((strcmp((char *)b->driver->dev_info,
+                   (char *)bind_info->dev_info) == 0) &&
+           (b->function == bind_info->function))
            break;
     if (b == NULL) return -ENODEV;
-
-    if (b->instance == NULL)
-       return -EAGAIN;
-    if (b->instance->state & DEV_CONFIG_PENDING)
+    if ((b->instance == NULL) ||
+       (b->instance->state & DEV_CONFIG_PENDING))
        return -EAGAIN;
-
     if (first)
        node = b->instance->dev;
     else
@@ -511,8+512,9 @@ static int unbind_request(int i, bind_info_t *bind_info)
     DEBUG(2, "unbind_request(%d, '%s')\n", i,
          (char *)bind_info->dev_info);
     for (b = &s->bind; *b; b = &(*b)->next)
-       if (strcmp((char *)(*b)->driver->dev_info,
-                  (char *)bind_info->dev_info) == 0)
+       if ((strcmp((char *)(*b)->driver->dev_info,
+                   (char *)bind_info->dev_info) == 0) &&
+           ((*b)->function == bind_info->function))
            break;
     if (*b == NULL)
        return -ENODEV;
index f156051..4e06af9 100644 (file)
@@ -2,7+2,7 @@
 
     Resource management routines
 
-    rsrc_mgr.c 1.77 1999/11/16 03:32:59
+    rsrc_mgr.c 1.79 2000/08/30 20:23:58
 
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     rights and limitations under the License.
 
     The initial developer of the original code is David A. Hinds
-    <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
 
 /* Parameters that can be set with 'insmod' */
 
-/* Should we probe resources for conflicts? */
-static int probe_mem = 1;
-MODULE_PARM(probe_mem, "i");
+#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
+
+INT_MODULE_PARM(probe_mem,     1);             /* memory probe? */
 #ifdef CONFIG_ISA
-static int probe_io = 1;
-static int mem_limit = 0x10000;
-MODULE_PARM(probe_io, "i");
-MODULE_PARM(mem_limit, "i");
+INT_MODULE_PARM(probe_io,      1);             /* IO port probe? */
+INT_MODULE_PARM(mem_limit,     0x10000);
 #endif
 
 /*======================================================================
index 739e03b..2f45d2c 100644 (file)
@@ -1,5+1,5 @@
 /*
- * rsrc_mgr.h 1.19 1999/10/25 20:03:34
+ * rsrc_mgr.h 1.20 2000/06/12 21:29:37
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
index ffd440d..2bdd6f8 100644 (file)
@@ -529,7+529,7 @@ static void __init isapnp_add_irq_resource(struct pci_dev *dev,
                (*res)->irq = irq;
 #ifdef CONFIG_PCI
        for (i=0; i<16; i++)
-               if (irq->map & i)
+               if (irq->map & (1<<i))
                        pcibios_penalize_isa_irq(i);
 #endif
 }
index 56f9d38..1332461 100644 (file)
@@ -507,7+507,8 @@ static long read_nibble(unsigned minor, char *c, unsigned long cnt)
           if (pins & BPP_GP_PError) byte |= 0x40;
           if (pins & BPP_GP_Busy)   byte |= 0x80;
 
-          put_user_ret(byte, c, -EFAULT);
+          if (put_user(byte, c))
+                 return -EFAULT;
           c += 1;
           remaining -= 1;
 
@@ -559,7+560,8 @@ static long read_ecp(unsigned minor, char *c, unsigned long cnt)
               for (idx = 0 ;  idx < repeat ;  idx += 1)
                 buffer[idx] = instances[minor].repeat_byte;
 
-              copy_to_user_ret(c, buffer, repeat, -EFAULT);
+              if (copy_to_user(c, buffer, repeat))
+                     return -EFAULT;
               remaining -= repeat;
               c += repeat;
               instances[minor].run_length -= repeat;
@@ -575,7+577,8 @@ static long read_ecp(unsigned minor, char *c, unsigned long cnt)
           if (rc & BPP_GP_Busy) {
                 /* OK, this is data. read it in. */
               unsigned char byte = bpp_inb(base_addrs[minor]);
-              put_user_ret(byte, c, -EFAULT);
+              if (put_user(byte, c))
+                     return -EFAULT;
               c += 1;
               remaining -= 1;
 
@@ -685,7+688,8 @@ static long write_compat(unsigned minor, const char *c, unsigned long cnt)
       while (remaining > 0) {
             unsigned char byte;
 
-            get_user_ret(byte, c, -EFAULT);
+            if (get_user(byte, c))
+                   return -EFAULT;
             c += 1;
 
             rc = wait_for(BPP_GP_nAck, BPP_GP_Busy, TIME_IDLE_LIMIT, minor);
@@ -735,7+739,8 @@ static long write_ecp(unsigned minor, const char *c, unsigned long cnt)
           unsigned char byte;
           int rc;
 
-          get_user_ret(byte, c, -EFAULT);
+          if (get_user(byte, c))
+                 return -EFAULT;
 
           rc = wait_for(0, BPP_GP_Busy, TIME_PResponse, minor);
           if (rc == -1) return -ETIMEDOUT;
index c9d4ea0..2ee0aee 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: display7seg.c,v 1.2 2000/08/02 06:22:35 davem Exp $
+/* $Id: display7seg.c,v 1.3 2000/08/29 07:01:55 davem Exp $
  *
  * display7seg - Driver implementation for the 7-segment display
  * present on Sun Microsystems CP1400 and CP1500
 #include <linux/ioport.h>              /* request_region, check_region */
 #include <asm/ebus.h>                  /* EBus device                                  */
 #include <asm/oplib.h>                 /* OpenProm Library                     */
-#include <asm/uaccess.h>               /* put_/get_user_ret                    */
+#include <asm/uaccess.h>               /* put_/get_user                        */
 
 #include <asm/display7seg.h>
 
@@ -132,7+132,8 @@ static int d7s_ioctl(struct inode *inode, struct file *f,
                /* assign device register values
                 * we mask-out D7S_FLIP if in sol_compat mode
                 */
-               get_user_ret(ireg, (int *) arg, -EFAULT);
+               if (get_user(ireg, (int *) arg))
+                       return -EFAULT;
                if (0 != sol_compat) {
                        (regs & D7S_FLIP) ? 
                                (ireg |= D7S_FLIP) : (ireg &= ~D7S_FLIP);
@@ -147,7+148,8 @@ static int d7s_ioctl(struct inode *inode, struct file *f,
                 * This driver will not misinform you about the state
                 * of your hardware while in sol_compat mode
                 */
-               put_user_ret(regs, (int *) arg, -EFAULT);
+               if (put_user(regs, (int *) arg))
+                       return -EFAULT;
                break;
 
        case D7SIOCTM:
index c381019..26e5ae8 100644 (file)
@@ -73,7+73,8 @@ static int copyin(struct openpromio *info, struct openpromio **opp_p)
        if (!info || !opp_p)
                return -EFAULT;
 
-       get_user_ret(bufsize, &info->oprom_size, -EFAULT);
+       if (get_user(bufsize, &info->oprom_size))
+               return -EFAULT;
 
        if (bufsize == 0)
                return -EINVAL;
@@ -132,7+133,8 @@ static int getstrings(struct openpromio *info, struct openpromio **opp_p)
  */
 static int copyout(void *info, struct openpromio *opp, int len)
 {
-       copy_to_user_ret(info, opp, len, -EFAULT);
+       if (copy_to_user(info, opp, len))
+               return -EFAULT;
        return 0;
 }
 
@@ -364,7+366,8 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
 
        switch (cmd) {
        case OPIOCGET:
-               copy_from_user_ret(&op, (void *)arg, sizeof(op), -EFAULT);
+               if (copy_from_user(&op, (void *)arg, sizeof(op)))
+                       return -EFAULT;
 
                if (!goodnode(op.op_nodeid,data))
                        return -EINVAL;
@@ -386,9+389,10 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
 
                if (len <= 0) {
                        kfree(str);
-                       /* Verified by the above copy_from_user_ret */
-                       __copy_to_user_ret((void *)arg, &op,
-                                          sizeof(op), -EFAULT);
+                       /* Verified by the above copy_from_user */
+                       if (__copy_to_user((void *)arg, &op,
+                                      sizeof(op)))
+                               return -EFAULT;
                        return 0;
                }
 
@@ -414,7+418,8 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
                return error;
 
        case OPIOCNEXTPROP:
-               copy_from_user_ret(&op, (void *)arg, sizeof(op), -EFAULT);
+               if (copy_from_user(&op, (void *)arg, sizeof(op)))
+                       return -EFAULT;
 
                if (!goodnode(op.op_nodeid,data))
                        return -EINVAL;
@@ -457,7+462,8 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
                return error;
 
        case OPIOCSET:
-               copy_from_user_ret(&op, (void *)arg, sizeof(op), -EFAULT);
+               if (copy_from_user(&op, (void *)arg, sizeof(op)))
+                       return -EFAULT;
 
                if (!goodnode(op.op_nodeid,data))
                        return -EINVAL;
@@ -485,13+491,14 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
                return 0;
 
        case OPIOCGETOPTNODE:
-               copy_to_user_ret((void *)arg, &options_node,
-                                sizeof(int), -EFAULT);
+               if (copy_to_user((void *)arg, &options_node, sizeof(int)))
+                       return -EFAULT;
                return 0;
 
        case OPIOCGETNEXT:
        case OPIOCGETCHILD:
-               copy_from_user_ret(&node, (void *)arg, sizeof(int), -EFAULT);
+               if (copy_from_user(&node, (void *)arg, sizeof(int)))
+                       return -EFAULT;
 
                save_and_cli(flags);
                if (cmd == OPIOCGETNEXT)
@@ -500,7+507,8 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
                        node = __prom_getchild(node);
                restore_flags(flags);
 
-               __copy_to_user_ret((void *)arg, &node, sizeof(int), -EFAULT);
+               if (__copy_to_user((void *)arg, &node, sizeof(int)))
+                       return -EFAULT;
 
                return 0;
 
index de875f5..d8454cf 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: rtc.c,v 1.22 2000/08/22 06:56:33 davem Exp $
+/* $Id: rtc.c,v 1.23 2000/08/29 07:01:55 davem Exp $
  *
  * Linux/SPARC Real Time Clock Driver
  * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
@@ -97,7+97,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        case RTCGET:
                get_rtc_time(&rtc_tm);
 
-               copy_to_user_ret((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time), -EFAULT);
+               if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
+                       return -EFAULT;
 
                return 0;
 
@@ -106,7+107,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                if (!capable(CAP_SYS_TIME))
                        return -EPERM;
 
-               copy_from_user_ret(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time), -EFAULT);
+               if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
+                       return -EFAULT;
 
                set_rtc_time(&rtc_tm);
 
index cc71cab..5540e73 100644 (file)
@@ -1346,19+1346,22 @@ repeat:
 
 #ifdef CONFIG_SPARC32_COMPAT
                if (current->thread.flags & SPARC_FLAG_32BIT) {
-                       copy_to_user_ret((Firm_event *)p, &this_event,
-                                        sizeof(Firm_event)-sizeof(struct timeval),
-                                        -EFAULT);
+                       if (copy_to_user((Firm_event *)p, &this_event,
+                                        sizeof(Firm_event)-sizeof(struct timeval)))
+                               return -EFAULT;
                        p += sizeof(Firm_event)-sizeof(struct timeval);
-                       __put_user_ret(this_event.time.tv_sec, (u32 *)p, -EFAULT);
+                       if (__put_user(this_event.time.tv_sec, (u32 *)p))
+                               return -EFAULT;
                        p += sizeof(u32);
-                       __put_user_ret(this_event.time.tv_usec, (u32 *)p, -EFAULT);
+                       if (__put_user(this_event.time.tv_usec, (u32 *)p))
+                               return -EFAULT;
                        p += sizeof(u32);
                } else
 #endif
                {
-                       copy_to_user_ret((Firm_event *)p, &this_event, 
-                                        sizeof(Firm_event), -EFAULT);
+                       if (copy_to_user((Firm_event *)p, &this_event, 
+                                        sizeof(Firm_event)))
+                               return -EFAULT;
                        p += sizeof (Firm_event);
                }
 #ifdef KBD_DEBUG
@@ -1401,22+1404,27 @@ kbd_ioctl (struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
 
        switch (cmd){
        case KIOCTYPE:            /* return keyboard type */
-               put_user_ret(sunkbd_type, (int *) arg, -EFAULT);
+               if (put_user(sunkbd_type, (int *) arg))
+                       return -EFAULT;
                break;
        case KIOCGTRANS:
-               put_user_ret(TR_UNTRANS_EVENT, (int *) arg, -EFAULT);
+               if (put_user(TR_UNTRANS_EVENT, (int *) arg))
+                       return -EFAULT;
                break;
        case KIOCTRANS:
-               get_user_ret(value, (int *) arg, -EFAULT);
+               if (get_user(value, (int *) arg))
+                       return -EFAULT;
                if (value != TR_UNTRANS_EVENT)
                        return -EINVAL;
                break;
        case KIOCLAYOUT:
-               put_user_ret(sunkbd_layout, (int *) arg, -EFAULT);
+               if (put_user(sunkbd_layout, (int *) arg))
+                       return -EFAULT;
                break;
        case KIOCSDIRECT:
 #ifndef CODING_NEW_DRIVER
-               get_user_ret(value, (int *) arg, -EFAULT);
+               if (get_user(value, (int *) arg))
+                       return -EFAULT;
                if(value)
                        kbd_redirected = fg_console + 1;
                else
@@ -1425,7+1433,8 @@ kbd_ioctl (struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
 #endif
                break;
        case KIOCCMD:
-               get_user_ret(value, (int *) arg, -EFAULT);
+               if (get_user(value, (int *) arg))
+                       return -EFAULT;
                c = (unsigned char) value;
                switch (c) {
                        case SKBDCMD_CLICK:
@@ -1444,8+1453,9 @@ kbd_ioctl (struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
                                return -EINVAL;
                }
        case KIOCSLED:
-               get_user_ret(c, (unsigned char *) arg, -EFAULT);
-                       
+               if (get_user(c, (unsigned char *) arg))
+                       return -EFAULT;
+
                if (c & LED_SCRLCK) leds |= (1 << VC_SCROLLOCK);
                if (c & LED_NLOCK) leds |= (1 << VC_NUMLOCK);
                if (c & LED_CLOCK) leds |= (1 << VC_CAPSLOCK);
@@ -1453,7+1463,8 @@ kbd_ioctl (struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
                sun_setledstate(kbd_table + fg_console, leds);
                break;
        case KIOCGLED:
-               put_user_ret(vcleds_to_sunkbd(getleds()), (unsigned char *) arg, -EFAULT);
+               if (put_user(vcleds_to_sunkbd(getleds()), (unsigned char *) arg))
+                       return -EFAULT;
                break;
        case KIOCGRATE:
        {
@@ -1465,8+1476,9 @@ kbd_ioctl (struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
                else
                        rate.rate = 0;
 
-               copy_to_user_ret((struct kbd_rate *)arg, &rate,
-                                sizeof(struct kbd_rate), -EFAULT);
+               if (copy_to_user((struct kbd_rate *)arg, &rate,
+                                sizeof(struct kbd_rate)))
+                       return -EFAULT;
 
                return 0;
        }
@@ -1495,7+1507,8 @@ kbd_ioctl (struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
                int count;
                
                count = kbd_head - kbd_tail;
-               put_user_ret((count < 0) ? KBD_QSIZE - count : count, (int *) arg, -EFAULT);
+               if (put_user((count < 0) ? KBD_QSIZE - count : count, (int *) arg))
+                       return -EFAULT;
                return 0;
        }
        default:
index b9dd256..fd92bc4 100644 (file)
@@ -462,21+462,24 @@ repeat:
                                    ((sizeof(Firm_event) - sizeof(struct timeval) +
                                      (sizeof(u32) * 2))))
                                        break;
-                               copy_to_user_ret((Firm_event *)p, &this_event,
-                                                sizeof(Firm_event)-sizeof(struct timeval),
-                                                -EFAULT);
+                               if (copy_to_user((Firm_event *)p, &this_event,
+                                                sizeof(Firm_event)-sizeof(struct timeval)))
+                                       return -EFAULT;
                                p += sizeof(Firm_event)-sizeof(struct timeval);
-                               __put_user_ret(this_event.time.tv_sec, (u32 *)p, -EFAULT);
+                               if (__put_user(this_event.time.tv_sec, (u32 *)p))
+                                       return -EFAULT;
                                p += sizeof(u32);
-                               __put_user_ret(this_event.time.tv_usec, (u32 *)p, -EFAULT);
+                               if (__put_user(this_event.time.tv_usec, (u32 *)p))
+                                       return -EFAULT;
                                p += sizeof(u32);
                        } else
 #endif 
                        {       
                                if ((end - p) < sizeof(Firm_event))
                                        break;
-                               copy_to_user_ret((Firm_event *)p, &this_event,
-                                                sizeof(Firm_event), -EFAULT);
+                               if (copy_to_user((Firm_event *)p, &this_event,
+                                                sizeof(Firm_event)))
+                                       return -EFAULT;
                                p += sizeof (Firm_event);
                        }
                        spin_lock_irqsave(&sunmouse.lock, flags);
@@ -540,16+543,19 @@ sun_mouse_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsig
        switch (cmd){
                /* VUIDGFORMAT - Get input device byte stream format */
        case _IOR('v', 2, int):
-               put_user_ret(sunmouse.vuid_mode, (int *) arg, -EFAULT);
+               if (put_user(sunmouse.vuid_mode, (int *) arg))
+                       return -EFAULT;
                break;
 
                /* VUIDSFORMAT - Set input device byte stream format*/
        case _IOW('v', 1, int):
-               get_user_ret(i, (int *) arg, -EFAULT);
+               if (get_user(i, (int *) arg))
+                       return -EFAULT;
                if (i == VUID_NATIVE || i == VUID_FIRM_EVENT){
                        int value;
 
-                       get_user_ret(value, (int *)arg, -EFAULT);
+                       if (get_user(value, (int *)arg))
+                               return -EFAULT;
 
                        spin_lock_irq(&sunmouse.lock);
                        sunmouse.vuid_mode = value;
index 40284c6..7acfb2a 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: zs.c,v 1.58 2000/07/06 01:41:38 davem Exp $
+/* $Id: zs.c,v 1.59 2000/08/29 07:01:55 davem Exp $
  * zs.c: Zilog serial port driver for the Sparc.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1319,7+1319,8 @@ static int get_serial_info(struct sun_serial * info,
        tmp.close_delay = info->close_delay;
        tmp.closing_wait = info->closing_wait;
        tmp.custom_divisor = info->custom_divisor;
-       copy_to_user_ret(retinfo,&tmp,sizeof(*retinfo), -EFAULT);
+       if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+               return -EFAULT;
        return 0;
 }
 
@@ -1390,7+1391,8 @@ static int get_lsr_info(struct sun_serial * info, unsigned int *value)
        ZSDELAY();
        ZSLOG(REGCTRL, status, 0);
        sti();
-       put_user_ret(status, value, -EFAULT);
+       if (put_user(status, value))
+               return -EFAULT;
        return 0;
 }
 
@@ -1409,7+1411,8 @@ static int get_modem_info(struct sun_serial * info, unsigned int *value)
                | ((status  & DCD) ? TIOCM_CAR : 0)
                | ((status  & SYNC) ? TIOCM_DSR : 0)
                | ((status  & CTS) ? TIOCM_CTS : 0);
-       put_user_ret(result, value, -EFAULT);
+       if (put_user(result, value))
+               return -EFAULT;
        return 0;
 }
 
@@ -1418,7+1421,8 @@ static int set_modem_info(struct sun_serial * info, unsigned int cmd,
 {
        unsigned int arg;
 
-       get_user_ret(arg, value, -EFAULT);
+       if (get_user(arg, value))
+               return -EFAULT;
        switch (cmd) {
        case TIOCMBIS: 
                if (arg & TIOCM_RTS)
@@ -1494,11+1498,13 @@ static int zs_ioctl(struct tty_struct *tty, struct file * file,
                        send_break(info, arg ? arg*(HZ/10) : HZ/4);
                        return 0;
                case TIOCGSOFTCAR:
-                       put_user_ret(C_CLOCAL(tty) ? 1 : 0,
-                                    (unsigned long *) arg, -EFAULT);
+                       if (put_user(C_CLOCAL(tty) ? 1 : 0,
+                                    (unsigned long *) arg))
+                               return -EFAULT;
                        return 0;
                case TIOCSSOFTCAR:
-                       get_user_ret(arg, (unsigned long *) arg, -EFAULT);
+                       if (get_user(arg, (unsigned long *) arg))
+                               return -EFAULT;
                        tty->termios->c_cflag =
                                ((tty->termios->c_cflag & ~CLOCAL) |
                                 (arg ? CLOCAL : 0));
@@ -1519,8+1525,9 @@ static int zs_ioctl(struct tty_struct *tty, struct file * file,
                        return get_lsr_info(info, (unsigned int *) arg);
 
                case TIOCSERGSTRUCT:
-                       copy_to_user_ret((struct sun_serial *) arg,
-                                   info, sizeof(struct sun_serial), -EFAULT);
+                       if (copy_to_user((struct sun_serial *) arg,
+                                   info, sizeof(struct sun_serial)))
+                               return -EFAULT;
                        return 0;
                        
                default:
@@ -1906,7+1913,7 @@ int zs_open(struct tty_struct *tty, struct file * filp)
 
 static void show_serial_version(void)
 {
-       char *revision = "$Revision: 1.58 $";
+       char *revision = "$Revision: 1.59 $";
        char *version, *p;
 
        version = strchr(revision, ' ');
index 6339d1e..16d14b8 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: esp.c,v 1.95 2000/08/23 22:32:37 davem Exp $
+/* $Id: esp.c,v 1.96 2000/08/24 03:51:26 davem Exp $
  * esp.c:  EnhancedScsiProcessor Sun SCSI driver code.
  *
  * Copyright (C) 1995, 1998 David S. Miller (davem@caip.rutgers.edu)
@@ -1599,7+1599,9 @@ static void esp_exec_cmd(struct esp *esp)
 
        if (SDptr->sync) {
                /* this targets sync is known */
+#ifndef __sparc_v9__
 do_sync_known:
+#endif
                if (SDptr->disconnect)
                        *cmdp++ = IDENTIFY(1, lun);
                else
@@ -2583,6+2585,8 @@ static int esp_do_data(struct esp *esp)
        esp_advance_phase(SCptr, thisphase);
        ESPDATA(("newphase<%s> ", (thisphase == in_datain) ? "DATAIN" : "DATAOUT"));
        hmuch = dma_can_transfer(esp, SCptr);
+       if (hmuch > (64 * 1024) && (esp->erev != fashme))
+               hmuch = (64 * 1024);
        ESPDATA(("hmuch<%d> ", hmuch));
        esp->current_transfer_size = hmuch;
 
index e93fe81..bf738e9 100644 (file)
       #define __PUT_USER               __put_user
    #endif
    
-   #ifndef PUT_USER_RET
-      #define PUT_USER_RET             put_user_ret
-   #endif
-   
    #ifndef GET_USER
       #define GET_USER                 get_user
    #endif
       #define __GET_USER               __get_user
    #endif
    
-   #ifndef GET_USER_RET
-      #define GET_USER_RET             get_user_ret
-   #endif
-
    /*
     * Lock macros
     */
index 195e131..75914a1 100644 (file)
@@ -5,7+5,7 @@
     This driver supports the Adaptec AHA-1460, the New Media Bus
     Toaster, and the New Media Toast & Jam.
     
-    aha152x_cs.c 1.53 2000/05/04 01:30:00
+    aha152x_cs.c 1.54 2000/06/12 21:27:25
 
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     rights and limitations under the License.
 
     The initial developer of the original code is David A. Hinds
-    <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
@@ -62,7+62,7 @@ static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"aha152x_cs.c 1.53 2000/05/04 01:30:00 (David Hinds)";
+"aha152x_cs.c 1.54 2000/06/12 21:27:25 (David Hinds)";
 #else
 #define DEBUG(n, args...)
 #endif
index a6419f1..24ee469 100644 (file)
@@ -2,7+2,7 @@
 
     A driver for the Adaptec APA1480 CardBus SCSI Host Adapter
 
-    apa1480_cb.c 1.19 2000/02/14 22:39:25
+    apa1480_cb.c 1.22 2000/06/12 21:27:25
 
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     rights and limitations under the License.
 
     The initial developer of the original code is David A. Hinds
-    <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
@@ -55,7+55,7 @@ static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"apa1480_cb.c 1.19 2000/02/14 22:39:25 (David Hinds)";
+"apa1480_cb.c 1.22 2000/06/12 21:27:25 (David Hinds)";
 #else
 #define DEBUG(n, args...)
 #endif
index 533bf5a..3c480a3 100644 (file)
@@ -2,7+2,7 @@
 
     A driver for Future Domain-compatible PCMCIA SCSI cards
 
-    fdomain_cs.c 1.42 2000/05/04 01:30:00
+    fdomain_cs.c 1.43 2000/06/12 21:27:25
 
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     rights and limitations under the License.
 
     The initial developer of the original code is David A. Hinds
-    <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
@@ -59,7+59,7 @@ static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"fdomain_cs.c 1.42 2000/05/04 01:30:00 (David Hinds)";
+"fdomain_cs.c 1.43 2000/06/12 21:27:25 (David Hinds)";
 #else
 #define DEBUG(n, args...)
 #endif
index bcbbecf..1cfee65 100644 (file)
@@ -2,7+2,7 @@
 
     A driver for the Qlogic SCSI card
 
-    qlogic_cs.c 1.78 2000/05/04 01:30:00
+    qlogic_cs.c 1.79 2000/06/12 21:27:26
 
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     rights and limitations under the License.
 
     The initial developer of the original code is David A. Hinds
-    <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
@@ -66,7+66,7 @@ static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"qlogic_cs.c 1.78 2000/05/04 01:30:00 (David Hinds)";
+"qlogic_cs.c 1.79 2000/06/12 21:27:26 (David Hinds)";
 #else
 #define DEBUG(n, args...)
 #endif
index 62ca3c5..46f9402 100644 (file)
@@ -100,9+100,10 @@ sgi_graphics_ioctl (struct inode *inode, struct file *file, unsigned int cmd, un
                i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct gfx_getboardinfo_args));
                if (i) return i;
                
-               __get_user_ret (board,    &bia->board, -EFAULT);
-               __get_user_ret (dest_buf, &bia->buf,   -EFAULT);
-               __get_user_ret (max_len,  &bia->len,   -EFAULT);
+               if (__get_user (board,    &bia->board) ||
+                   __get_user (dest_buf, &bia->buf) ||
+                   __get_user (max_len,  &bia->len))
+                       return -EFAULT;
 
                if (board >= boards)
                        return -EINVAL;
@@ -125,8+126,9 @@ sgi_graphics_ioctl (struct inode *inode, struct file *file, unsigned int cmd, un
                i = verify_area (VERIFY_READ, (void *)arg, sizeof (struct gfx_attach_board_args));
                if (i) return i;
 
-               __get_user_ret (board, &att->board, -EFAULT);
-               __get_user_ret (vaddr, &att->vaddr, -EFAULT);
+               if (__get_user (board, &att->board) ||
+                   __get_user (vaddr, &att->vaddr))
+                       return -EFAULT;
 
                /* Ok for now we are assuming /dev/graphicsN -> head N even
                 * if the ioctl api suggests that this is not quite the case.
index 52bc764..57989c0 100644 (file)
@@ -60,7+60,8 @@ rrm_command (unsigned int cmd, void *arg)
        i = verify_area (VERIFY_READ, arg, rrm_functions [cmd].arg_size);
        if (i) return i;
 
-       __get_user_ret (rnid, (int *) arg, -EFAULT);
+       if (__get_user (rnid, (int *) arg))
+               return -EFAULT;
        return (*(rrm_functions [cmd].r_fn))(rnid, arg);
 }
 
index 23e9484..5ed418e 100644 (file)
@@ -419,7+419,8 @@ static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned
 
        if (_IOC_DIR(cmd) == (_IOC_WRITE|_IOC_READ)) {
                codec->modcnt++;
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
 
                switch (_IOC_NR(cmd)) {
                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
index fbba125..836579a 100644 (file)
@@ -1038,7+1038,8 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
        s->mix.modcnt++;
        switch (_IOC_NR(cmd)) {
        case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                i = hweight32(val);
                for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
                        if (!(val & (1 << i)))
@@ -1056,7+1057,8 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
                return 0;
 
        case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
                        if (!(val & (1 << i)))
                                continue;
@@ -1075,7+1077,8 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
                i = _IOC_NR(cmd);
                if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
                        return -EINVAL;
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                l = val & 0xff;
                r = (val >> 8) & 0xff;
                if (l > 100)
@@ -1469,7+1472,8 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_READ) {
                                stop_adc(s);
@@ -1485,7+1489,8 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
                
         case SNDCTL_DSP_STEREO:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                fmtd = 0;
                fmtm = ~0;
                if (file->f_mode & FMODE_READ) {
@@ -1508,7+1513,8 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        fmtd = 0;
                        fmtm = ~0;
@@ -1537,7+1543,8 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                 return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
                
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        fmtd = 0;
                        fmtm = ~0;
@@ -1574,7+1581,8 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return put_user(val, (int *)arg);
                
        case SNDCTL_DSP_SETTRIGGER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
                                if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
@@ -1671,7+1679,8 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return put_user(s->dma_adc.fragsize, (int *)arg);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        s->dma_adc.ossfragshift = val & 0xffff;
                        s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
@@ -1698,7+1707,8 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
                    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
                        return -EINVAL;
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
                if (file->f_mode & FMODE_READ)
index 6a9fec8..1c282b1 100644 (file)
@@ -1233,7+1233,8 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
        case SNDCTL_DSP_SPEED: /* set smaple rate */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_WRITE) {
                                stop_dac(state);
@@ -1249,7+1250,8 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return put_user(dmabuf->rate, (int *)arg);
 
        case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_WRITE) {
                        stop_dac(state);
                        dmabuf->ready = 0;
@@ -1291,7+1293,8 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return put_user(AFMT_S16_LE, (int *)arg);
 
        case SNDCTL_DSP_SETFMT: /* Select sample format */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        if(val==AFMT_S16_LE/* || val==AFMT_U8*/)
                        {
@@ -1315,7+1318,8 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        return put_user(AFMT_U8, (int *)arg);
 
        case SNDCTL_DSP_CHANNELS:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        if (file->f_mode & FMODE_WRITE) {
                                stop_dac(state);
@@ -1340,14+1344,16 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
        case SNDCTL_DSP_SUBDIVIDE:
                if (dmabuf->subdivision)
                        return -EINVAL;
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 1 && val != 2)
                        return -EINVAL;
                dmabuf->subdivision = val;
                return 0;
 
        case SNDCTL_DSP_SETFRAGMENT:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
 
                dmabuf->ossfragshift = val & 0xffff;
                dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
@@ -1408,7+1414,8 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return put_user(val, (int *)arg);
 
        case SNDCTL_DSP_SETTRIGGER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
                                if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
index 1d8804b..21f54bd 100644 (file)
@@ -523,7+523,8 @@ static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
                    strncpy(info.name, dmasound.mach.name2, sizeof(info.name));
                    info.name[sizeof(info.name)-1] = 0;
                    info.modify_counter = mixer.modify_counter;
-                   copy_to_user_ret((int *)arg, &info, sizeof(info), -EFAULT);
+                   if (copy_to_user((int *)arg, &info, sizeof(info)))
+                           return -EFAULT;
                    return 0;
                }
        }
index dca8d56..c06c5df 100644 (file)
@@ -361,7+361,8 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_SPEED:
                DPF(2, "SNDCTL_DSP_SPEED:\n");
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
                DPD(2, "val is %d\n", val);
 
                if (val > 0) {
@@ -415,7+416,8 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_STEREO:
                DPF(2, "SNDCTL_DSP_STEREO:\n");
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
                DPD(2, " val is %d\n", val);
 
                if (file->f_mode & FMODE_READ) {
@@ -460,7+462,8 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_CHANNELS:
                DPF(2, "SNDCTL_DSP_CHANNELS:\n");
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
                DPD(2, " val is %d\n", val);
 
                if (val > 0) {
@@ -522,7+525,8 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_SETFMT: /* Same as SNDCTL_DSP_SAMPLESIZE */
                DPF(2, "SNDCTL_DSP_SETFMT:\n");
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
                DPD(2, " val is %d\n", val);
 
                if (val != AFMT_QUERY) {
@@ -624,7+628,8 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_SETTRIGGER:
                DPF(2, "SNDCTL_DSP_SETTRIGGER:\n");
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
 
                if (file->f_mode & FMODE_WRITE) {
                        spin_lock_irqsave(&woinst->lock, flags);
@@ -850,7+855,8 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_SETFRAGMENT:
                DPF(2, "SNDCTL_DSP_SETFRAGMENT:\n");
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
 
                DPD(2, "val is 0x%x\n", val);
 
index f28787f..296b505 100644 (file)
@@ -1038,7+1038,8 @@ static int emu10k1_mixer_ioctl(struct inode *inode, struct file *file, unsigned
                if (card->isaps)
                        return -EINVAL;
 
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
                i = hweight32(val);
                if (i == 0)
                        return 0;       /* val = mixer_recmask(s); */
@@ -1062,7+1063,8 @@ static int emu10k1_mixer_ioctl(struct inode *inode, struct file *file, unsigned
 
                if (i >= SOUND_MIXER_NRDEVICES)
                        return -EINVAL;
-               get_user_ret(val, (int *) arg, -EFAULT);
+               if (get_user(val, (int *) arg))
+                       return -EFAULT;
                if (emu10k1_mixer_wrch(card, i, val))
                        return -EINVAL;
 
index 01f2cf4..d9d972a 100644 (file)
@@ -842,7+842,8 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a
        VALIDATE_STATE(s);
        if (cmd == SOUND_MIXER_PRIVATE1) {
                /* enable/disable/query mixer preamp */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != -1) {
                        s->mix.micpreamp = !!val;
                        wrcodec(s, 0x19, s->mix.micpreamp);
@@ -851,7+852,8 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a
        }
        if (cmd == SOUND_MIXER_PRIVATE2) {
                /* enable/disable/query use of linein as second lineout */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != -1) {
                        spin_lock_irqsave(&s->lock, flags);
                        if (val)
@@ -865,7+867,8 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a
        }
        if (cmd == SOUND_MIXER_PRIVATE3) {
                /* enable/disable/query microphone impedance setting */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != -1) {
                        spin_lock_irqsave(&s->lock, flags);
                        if (val)
@@ -941,12+944,14 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a
        switch (_IOC_NR(cmd)) {
 
        case SOUND_MIXER_IMIX:
-               get_user_ret(s->mix.imix, (int *)arg, -EFAULT);
+               if (get_user(s->mix.imix, (int *)arg))
+                       return -EFAULT;
                set_recsrc(s, s->mix.recsrc);
                return 0;
 
        case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                set_recsrc(s, val);
                return 0;
 
@@ -954,7+959,8 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a
                i = _IOC_NR(cmd);
                if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
                        return -EINVAL;
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                l = val & 0xff;
                if (l > 100)
                        l = 100;
@@ -1382,7+1388,8 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val >= 0) {
                        if (s->open_mode & (~file->f_mode) & (FMODE_READ|FMODE_WRITE))
                                return -EINVAL;
@@ -1401,7+1408,8 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), (int *)arg);
                
         case SNDCTL_DSP_STEREO:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        stop_adc(s);
                        s->dma_adc.ready = 0;
@@ -1427,7+1435,8 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        if (file->f_mode & FMODE_READ) {
                                stop_adc(s);
@@ -1458,7+1467,8 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                 return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
                
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        if (file->f_mode & FMODE_READ) {
                                stop_adc(s);
@@ -1498,7+1508,8 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return put_user(val, (int *)arg);
                
        case SNDCTL_DSP_SETTRIGGER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
                                if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
@@ -1609,7+1620,8 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return put_user(s->dma_adc.fragsize, (int *)arg);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        s->dma_adc.ossfragshift = val & 0xffff;
                        s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
@@ -1636,7+1648,8 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
                    (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
                        return -EINVAL;
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
                if (file->f_mode & FMODE_READ)
@@ -1916,7+1929,8 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val >= 0) {
                        stop_dac1(s);
                        s->dma_dac1.ready = 0;
@@ -1931,7+1945,8 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], (int *)arg);
                
         case SNDCTL_DSP_STEREO:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                stop_dac1(s);
                s->dma_dac1.ready = 0;
                spin_lock_irqsave(&s->lock, flags);
@@ -1944,7+1959,8 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        if (s->dma_dac1.mapped)
                                return -EINVAL;
@@ -1964,7+1980,8 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                 return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
                
         case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        stop_dac1(s);
                        s->dma_dac1.ready = 0;
@@ -1985,7+2002,8 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, (int *)arg);
                                                
        case SNDCTL_DSP_SETTRIGGER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val & PCM_ENABLE_OUTPUT) {
                        if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
                                return ret;
@@ -2044,7+2062,8 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                 return put_user(s->dma_dac1.fragsize, (int *)arg);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                s->dma_dac1.ossfragshift = val & 0xffff;
                s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff;
                if (s->dma_dac1.ossfragshift < 4)
@@ -2058,7+2077,8 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
         case SNDCTL_DSP_SUBDIVIDE:
                if (s->dma_dac1.subdivision)
                        return -EINVAL;
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
                s->dma_dac1.subdivision = val;
index 4e340c3..c325682 100644 (file)
@@ -1165,7+1165,8 @@ static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned lon
                return 0;
 
        case SOUND_MIXER_WRITE_PCM:   /* use SRC for PCM volume */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                right = ((val >> 8)  & 0xff);
                left = (val  & 0xff);
                if (right > 100)
@@ -1570,7+1571,8 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_READ) {
                                stop_adc(s);
@@ -1586,7+1588,8 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, (int *)arg);
 
         case SNDCTL_DSP_STEREO:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        stop_adc(s);
                        s->dma_adc.ready = 0;
@@ -1612,7+1615,8 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        if (file->f_mode & FMODE_READ) {
                                stop_adc(s);
@@ -1643,7+1647,8 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                 return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
                
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        if (file->f_mode & FMODE_READ) {
                                stop_adc(s);
@@ -1683,7+1688,8 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return put_user(val, (int *)arg);
                
        case SNDCTL_DSP_SETTRIGGER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
                                if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
@@ -1794,7+1800,8 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return put_user(s->dma_adc.fragsize, (int *)arg);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        s->dma_adc.ossfragshift = val & 0xffff;
                        s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
@@ -1821,7+1828,8 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
                    (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
                        return -EINVAL;
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
                if (file->f_mode & FMODE_READ)
@@ -2100,7+2108,8 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val >= 0) {
                        stop_dac1(s);
                        s->dma_dac1.ready = 0;
@@ -2109,7+2118,8 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return put_user(s->dac1rate, (int *)arg);
 
         case SNDCTL_DSP_STEREO:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                stop_dac1(s);
                s->dma_dac1.ready = 0;
                spin_lock_irqsave(&s->lock, flags);
@@ -2122,7+2132,8 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        stop_dac1(s);
                        s->dma_dac1.ready = 0;
@@ -2140,7+2151,8 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                 return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
                
         case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        stop_dac1(s);
                        s->dma_dac1.ready = 0;
@@ -2161,7+2173,8 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, (int *)arg);
                                                
        case SNDCTL_DSP_SETTRIGGER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val & PCM_ENABLE_OUTPUT) {
                        if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
                                return ret;
@@ -2220,7+2233,8 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                 return put_user(s->dma_dac1.fragsize, (int *)arg);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                s->dma_dac1.ossfragshift = val & 0xffff;
                s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff;
                if (s->dma_dac1.ossfragshift < 4)
@@ -2234,7+2248,8 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
         case SNDCTL_DSP_SUBDIVIDE:
                if (s->dma_dac1.subdivision)
                        return -EINVAL;
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
                s->dma_dac1.subdivision = val;
index 4c3bdaf..3d75f8d 100644 (file)
@@ -686,7+686,8 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
 
        if (cmd == SOUND_MIXER_PRIVATE1) {
                /* enable/disable/query mixer preamp */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != -1) {
                        val = val ? 0xff : 0xf7;
                        write_mixer(s, 0x7d, (read_mixer(s, 0x7d) | 0x08) & val);
@@ -696,7+697,8 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
        }
        if (cmd == SOUND_MIXER_PRIVATE2) {
                /* enable/disable/query spatializer */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != -1) {
                        val &= 0x3f;
                        write_mixer(s, 0x52, val);
@@ -773,7+775,8 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
                               0xb4, read_ctrl(s, 0xb4));
                }
 #endif
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                 i = hweight32(val);
                 if (i == 0)
                         return 0;
@@ -789,7+792,8 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
                return 0;
 
        case SOUND_MIXER_VOLUME:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                l = val & 0xff;
                if (l > 100)
                        l = 100;
@@ -820,7+824,8 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
                return put_user(s->mix.vol[9], (int *)arg);
 
        case SOUND_MIXER_SPEAKER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                l = val & 0xff;
                if (l > 100)
                        l = 100;
@@ -837,7+842,8 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
                return put_user(s->mix.vol[7], (int *)arg);
 
        case SOUND_MIXER_RECLEV:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                l = (val << 1) & 0x1fe;
                if (l > 200)
                        l = 200;
@@ -864,7+870,8 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
                i = _IOC_NR(cmd);
                if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
                        return -EINVAL;
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                l = (val << 1) & 0x1fe;
                if (l > 200)
                        l = 200;
@@ -1268,7+1275,8 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val >= 0) {
                        stop_adc(s);
                        stop_dac(s);
@@ -1295,7+1303,8 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return put_user(s->rate, (int *)arg);
                
         case SNDCTL_DSP_STEREO:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                stop_adc(s);
                stop_dac(s);
                s->dma_adc.ready = s->dma_dac.ready = 0;
@@ -1305,7+1314,8 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        stop_adc(s);
                        stop_dac(s);
@@ -1320,7+1330,8 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                 return put_user(AFMT_S16_LE|AFMT_U16_LE|AFMT_S8|AFMT_U8, (int *)arg);
 
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        stop_adc(s);
                        stop_dac(s);
@@ -1346,7+1357,8 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return put_user(val, (int *)arg);
 
        case SNDCTL_DSP_SETTRIGGER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
                                if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
@@ -1459,7+1471,8 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return put_user(s->dma_adc.fragsize, (int *)arg);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        s->dma_adc.ossfragshift = val & 0xffff;
                        s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
@@ -1486,7+1499,8 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
                    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
                        return -EINVAL;
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
                if (file->f_mode & FMODE_READ)
index 15b469c..54b50bb 100644 (file)
@@ -1300,7+1300,8 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return 0;
 
        case SNDCTL_DSP_SPEED: /* set smaple rate */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_WRITE) {
                                stop_dac(state);
@@ -1320,7+1321,8 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return put_user(dmabuf->rate, (int *)arg);
 
        case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if(val==0)
                        return -EINVAL;
                if (file->f_mode & FMODE_WRITE) {
@@ -1351,7+1353,8 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return put_user(AFMT_S16_LE, (int *)arg);
 
        case SNDCTL_DSP_SETFMT: /* Select sample format */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        if (file->f_mode & FMODE_WRITE) {
                                stop_dac(state);
@@ -1365,7+1368,8 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return put_user(AFMT_S16_LE, (int *)arg);
 
        case SNDCTL_DSP_CHANNELS:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        if (file->f_mode & FMODE_WRITE) {
                                stop_dac(state);
@@ -1385,14+1389,16 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        case SNDCTL_DSP_SUBDIVIDE:
                if (dmabuf->subdivision)
                        return -EINVAL;
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
                dmabuf->subdivision = val;
                return 0;
 
        case SNDCTL_DSP_SETFRAGMENT:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
 
                dmabuf->ossfragshift = val & 0xffff;
                dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
@@ -1450,7+1456,8 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return put_user(val, (int *)arg);
 
        case SNDCTL_DSP_SETTRIGGER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
                                if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
index 9d848e2..c2cb304 100644 (file)
@@ -2034,7+2034,8 @@ static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long ar
        
        card->mix.modcnt++;
 
-       get_user_ret(val, (int *)arg, -EFAULT);
+       if (get_user(val, (int *)arg))
+               return -EFAULT;
 
        switch (_IOC_NR(cmd)) {
        case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
@@ -2502,7+2503,8 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_READ) {
                                stop_adc(s);
@@ -2518,7+2520,8 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
                
         case SNDCTL_DSP_STEREO:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                fmtd = 0;
                fmtm = ~0;
                if (file->f_mode & FMODE_READ) {
@@ -2541,7+2544,8 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        fmtd = 0;
                        fmtm = ~0;
@@ -2570,7+2574,8 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                 return put_user(AFMT_U8|AFMT_S16_LE, (int *)arg);
                
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        fmtd = 0;
                        fmtm = ~0;
@@ -2615,7+2620,8 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                return put_user(val, (int *)arg);
                
        case SNDCTL_DSP_SETTRIGGER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
                                if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
@@ -2712,7+2718,8 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                return put_user(s->dma_adc.fragsize, (int *)arg);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                M_printk("maestro: SETFRAGMENT: %0x\n",val);
                if (file->f_mode & FMODE_READ) {
                        s->dma_adc.ossfragshift = val & 0xffff;
@@ -2740,7+2747,8 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
                    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
                        return -EINVAL;
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
                if (file->f_mode & FMODE_READ)
index a07029a..9049b4c 100644 (file)
@@ -1419,7+1419,8 @@ nm256_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
     switch (cmd)
        {
        case SOUND_PCM_WRITE_RATE:
-           get_user_ret(ret, (int *) arg, -EFAULT);
+           if (get_user(ret, (int *) arg))
+               return -EFAULT;
 
            if (ret != 0) {
                oldinfo = card->sinfo[w].samplerate;
@@ -1437,7+1438,8 @@ nm256_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
            break;
 
        case SNDCTL_DSP_STEREO:
-           get_user_ret(ret, (int *) arg, -EFAULT);
+           if (get_user(ret, (int *) arg))
+               return -EFAULT;
 
            card->sinfo[w].stereo = ret ? 1 : 0;
            ret = nm256_setInfo (dev, card);
@@ -1447,7+1449,8 @@ nm256_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
            break;
 
        case SOUND_PCM_WRITE_CHANNELS:
-           get_user_ret(ret, (int *) arg, -EFAULT);
+           if (get_user(ret, (int *) arg))
+               return -EFAULT;
 
            if (ret < 1 || ret > 3)
                ret = card->sinfo[w].stereo + 1;
@@ -1464,7+1467,8 @@ nm256_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
            break;
 
        case SNDCTL_DSP_SETFMT:
-           get_user_ret(ret, (int *) arg, -EFAULT);
+           if (get_user(ret, (int *) arg)
+               return -EFAULT;
 
            if (ret != 0) {
                oldinfo = card->sinfo[w].bits;
index 099bbf1..1c77982 100644 (file)
@@ -1051,7+1051,8 @@ static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
        if (cmd == OSS_GETVERSION)
                return put_user(SOUND_VERSION, (int *)arg);
        if (cmd == SOUND_MIXER_PRIVATE1) {  /* SRS settings */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                spin_lock_irqsave(&s->lock, flags);
                if (val & 1) {
                        if (val & 2) {
@@ -1119,7+1120,8 @@ static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
        s->mix.modcnt++;
        switch (_IOC_NR(cmd)) {
        case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                i = hweight32(val);
                if (i == 0)
                        return 0; /*val = mixer_recmask(s);*/
@@ -1143,7+1145,8 @@ static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
                i = _IOC_NR(cmd);
                if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
                        return -EINVAL;
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                l = val & 0xff;
                r = (val >> 8) & 0xff;
                if (mixtable[i].type == MT_4MUTEMONO)
@@ -1582,7+1585,8 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_READ) {
                                stop_adc(s);
@@ -1598,7+1602,8 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
                
         case SNDCTL_DSP_STEREO:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                fmtd = 0;
                fmtm = ~0;
                if (file->f_mode & FMODE_READ) {
@@ -1621,7+1626,8 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        fmtd = 0;
                        fmtm = ~0;
@@ -1650,7+1656,8 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                 return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
                
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        fmtd = 0;
                        fmtm = ~0;
@@ -1687,7+1694,8 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return put_user(val, (int *)arg);
                
        case SNDCTL_DSP_SETTRIGGER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
                                if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
@@ -1798,7+1806,8 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return put_user(s->dma_adc.fragsize, (int *)arg);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        s->dma_adc.ossfragshift = val & 0xffff;
                        s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
@@ -1825,7+1834,8 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
                    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
                        return -EINVAL;
-                get_user_ret(val, (int *)arg, -EFAULT);
+                if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
                if (file->f_mode & FMODE_READ)
index c85d409..a76755e 100644 (file)
@@ -1633,7+1633,8 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
                return 0;
 
        case SNDCTL_DSP_SPEED: /* set smaple rate */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_WRITE) {
                                stop_dac(state);
@@ -1653,7+1654,8 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
                return put_user(dmabuf->rate, (int *)arg);
 
        case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_WRITE) {
                        stop_dac(state);
                        dmabuf->ready = 0;
@@ -1688,7+1690,8 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
                return put_user(AFMT_S16_LE|AFMT_U16_LE|AFMT_S8|AFMT_U8, (int *)arg);
 
        case SNDCTL_DSP_SETFMT: /* Select sample format */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        if (file->f_mode & FMODE_WRITE) {
                                stop_dac(state);
@@ -1711,7+1714,8 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
                                AFMT_S16_LE : AFMT_U8, (int *)arg);
 
        case SNDCTL_DSP_CHANNELS:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        if (file->f_mode & FMODE_WRITE) {
                                stop_dac(state);
@@ -1740,14+1744,16 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
        case SNDCTL_DSP_SUBDIVIDE:
                if (dmabuf->subdivision)
                        return -EINVAL;
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
                dmabuf->subdivision = val;
                return 0;
 
        case SNDCTL_DSP_SETFRAGMENT:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
 
                dmabuf->ossfragshift = val & 0xffff;
                dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
@@ -1805,7+1811,8 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
                return put_user(val, (int *)arg);
 
        case SNDCTL_DSP_SETTRIGGER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
                                if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
@@ -1881,7+1888,8 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
                if (state->card->pci_id != PCI_DEVICE_ID_SI_7018)
                        return -EINVAL;
 
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val == DSP_BIND_QUERY) {
                        val = dmabuf->channel->attribute | 0x3c00;
                        val = attr2mask[val >> 8];
index 7ed78c9..a58b333 100644 (file)
@@ -1900,7+1900,8 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file,
 
        /* query or set current channel's PCM data format */
        case SNDCTL_DSP_SETFMT:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        rc = 0;
 
@@ -1928,7+1929,8 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file,
 
        /* query or set number of channels (1=mono, 2=stereo) */
         case SNDCTL_DSP_CHANNELS:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        rc = 0;
                        spin_lock_irq (&card->lock);
@@ -1954,7+1956,8 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file,
        
        /* enable (val is not zero) or disable (val == 0) stereo */
         case SNDCTL_DSP_STEREO:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                rc = 0;
                spin_lock_irq (&card->lock);
                if (rc == 0 && rd)
@@ -1969,7+1972,8 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file,
        
        /* query or set sampling rate */
         case SNDCTL_DSP_SPEED:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val < 0)
                        return -EINVAL;
                if (val > 0) {
@@ -2061,7+2065,8 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file,
 
        /* set fragment size.  implemented as a successful no-op for now */
        case SNDCTL_DSP_SETFRAGMENT:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
 
                DPRINTK ("SNDCTL_DSP_SETFRAGMENT (fragshift==0x%04X (%d), maxfrags==0x%04X (%d))\n",
                         val & 0xFFFF,
index d46abd5..3ba0479 100644 (file)
@@ -2476,7+2476,8 @@ static int vwsnd_audio_do_ioctl(struct inode *inode,
                return put_user(ival, (int *) arg);
 
        case SNDCTL_DSP_SPEED:          /* _SIOWR('P', 2, int) */
-               get_user_ret(ival, (int *) arg, -EFAULT);
+               if (get_user(ival, (int *) arg))
+                       return -EFAULT;
                DBGX("SNDCTL_DSP_SPEED %d\n", ival);
                if (ival) {
                        if (aport->swstate != SW_INITIAL) {
@@ -2497,7+2498,8 @@ static int vwsnd_audio_do_ioctl(struct inode *inode,
                return put_user(ival, (int *) arg);
 
        case SNDCTL_DSP_STEREO:         /* _SIOWR('P', 3, int) */
-               get_user_ret(ival, (int *) arg, -EFAULT);
+               if (get_user(ival, (int *) arg))
+                       return -EFAULT;
                DBGX("SNDCTL_DSP_STEREO %d\n", ival);
                if (ival != 0 && ival != 1)
                        return -EINVAL;
@@ -2510,7+2512,8 @@ static int vwsnd_audio_do_ioctl(struct inode *inode,
                return put_user(ival, (int *) arg);
 
        case SNDCTL_DSP_CHANNELS:       /* _SIOWR('P', 6, int) */
-               get_user_ret(ival, (int *) arg, -EFAULT);
+               if (get_user(ival, (int *) arg))
+                       return -EFAULT;
                DBGX("SNDCTL_DSP_CHANNELS %d\n", ival);
                if (ival != 1 && ival != 2)
                        return -EINVAL;
@@ -2533,7+2536,8 @@ static int vwsnd_audio_do_ioctl(struct inode *inode,
                return put_user(ival, (int *) arg);
 
        case SNDCTL_DSP_SETFRAGMENT:    /* _SIOWR('P',10, int) */
-               get_user_ret(ival, (int *) arg, -EFAULT);
+               if (get_user(ival, (int *) arg))
+                       return -EFAULT;
                DBGX("SNDCTL_DSP_SETFRAGMENT %d:%d\n",
                     ival >> 16, ival & 0xFFFF);
                if (aport->swstate != SW_INITIAL)
@@ -2571,7+2575,8 @@ static int vwsnd_audio_do_ioctl(struct inode *inode,
                return put_user(ival, (int *) arg);
 
        case SNDCTL_DSP_SUBDIVIDE:      /* _SIOWR('P', 9, int) */
-                get_user_ret(ival, (int *) arg, -EFAULT);
+                if (get_user(ival, (int *) arg))
+                       return -EFAULT;
                DBGX("SNDCTL_DSP_SUBDIVIDE %d\n", ival);
                if (aport->swstate != SW_INITIAL)
                        return -EINVAL;
@@ -2601,7+2606,8 @@ static int vwsnd_audio_do_ioctl(struct inode *inode,
                return 0;
 
        case SNDCTL_DSP_SETFMT:         /* _SIOWR('P',5, int) */
-               get_user_ret(ival, (int *) arg, -EFAULT);
+               if (get_user(ival, (int *) arg))
+                       return -EFAULT;
                DBGX("SNDCTL_DSP_SETFMT %d\n", ival);
                if (ival != AFMT_QUERY) {
                        if (aport->swstate != SW_INITIAL) {
@@ -2809,7+2815,8 @@ static int vwsnd_audio_do_ioctl(struct inode *inode,
                return put_user(ival, (int *) arg);
 
        case SNDCTL_DSP_SETTRIGGER:     /* _SIOW ('P',16, int) */
-               get_user_ret(ival, (int *) arg, -EFAULT);
+               if (get_user(ival, (int *) arg))
+                       return -EFAULT;
                DBGX("SNDCTL_DSP_SETTRIGGER %d\n", ival);
 
                /*
index 9eac1e3..7badf80 100644 (file)
@@ -1628,7+1628,8 @@ vnc_private_ioctl(int dev, unsigned int cmd, caddr_t arg)
                u_int prev_spkr_mute, prev_line_mute, prev_auto_state;
                int val;
 
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
 
                /* check if parameter is logical */
                if (val & ~(VNC_MUTE_INTERNAL_SPKR |
@@ -1657,7+1658,8 @@ vnc_private_ioctl(int dev, unsigned int cmd, caddr_t arg)
        }
 
        case SOUND_MIXER_PRIVATE2:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
 
                switch (val) {
 #define VNC_SOUND_PAUSE         0x53    //to pause the DSP
@@ -1681,8+1683,10 @@ vnc_private_ioctl(int dev, unsigned int cmd, caddr_t arg)
                unsigned long   flags;
                int             mixer_reg[15], i, val;
 
-               get_user_ret(val, (int *)arg, -EFAULT);
-               copy_from_user_ret(mixer_reg, (void *)val, sizeof(mixer_reg), -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
+               if (copy_from_user(mixer_reg, (void *)val, sizeof(mixer_reg)))
+                       return -EFAULT;
 
                switch (mixer_reg[14]) {
                case MIXER_PRIVATE3_RESET:
@@ -1708,7+1712,8 @@ vnc_private_ioctl(int dev, unsigned int cmd, caddr_t arg)
 
                        spin_unlock_irqrestore(&waveartist_lock, flags);
 
-                       copy_to_user_ret((void *)val, mixer_reg, sizeof(mixer_reg), -EFAULT);
+                       if (copy_to_user((void *)val, mixer_reg, sizeof(mixer_reg)))
+                               return -EFAULT;
                        break;
 
                default:
index 3efd731..12c308b 100644 (file)
@@ -559,7+559,8 @@ static int dmabuf_copyin_user(struct dmabuf *db, unsigned int ptr, const void *b
                rem = db->dmasize - ptr;
                if (pgrem > rem)
                        pgrem = rem;
-               copy_from_user_ret((db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), buffer, pgrem, -EFAULT);
+               if (copy_from_user((db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), buffer, pgrem))
+                       return -EFAULT;
                size -= pgrem;
                (char *)buffer += pgrem;
                ptr += pgrem;
@@ -583,7+584,8 @@ static int dmabuf_copyout_user(struct dmabuf *db, unsigned int ptr, void *buffer
                rem = db->dmasize - ptr;
                if (pgrem > rem)
                        pgrem = rem;
-               copy_to_user_ret(buffer, (db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), pgrem, -EFAULT);
+               if (copy_to_user(buffer, (db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), pgrem))
+                       return -EFAULT;
                size -= pgrem;
                (char *)buffer += pgrem;
                ptr += pgrem;
@@ -2029,7+2031,8 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
        ms->modcnt++;
        switch (_IOC_NR(cmd)) {
        case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                return set_rec_src(ms, val);
 
        default:
@@ -2039,7+2042,8 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
                for (j = 0; j < ms->numch && ms->ch[j].osschannel != i; j++);
                if (j >= ms->numch)
                        return -EINVAL;
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (wrmixer(ms, j, val))
                        return -EIO;
                return put_user(ms->ch[j].value, (int *)arg);
@@ -2352,7+2356,8 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                return 0;
 
        case SNDCTL_DSP_SPEED:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val >= 0) {
                        if (val < 4000)
                                val = 4000;
@@ -2370,7+2375,8 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                return 0;
 
        case SNDCTL_DSP_CHANNELS:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 0) {
                        val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
                        if (val == 1)
@@ -2388,7+2394,8 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                                AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE, (int *)arg);
 
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != AFMT_QUERY) {
                        if (hweight32(val) != 1)
                                return -EINVAL;
@@ -2415,7+2422,8 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                return put_user(val, (int *)arg);
 
        case SNDCTL_DSP_SETTRIGGER:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
                                if (!as->usbin.dma.ready && (ret = prog_dmabuf_in(as)))
@@ -2509,7+2517,8 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                return put_user(as->usbin.dma.fragsize, (int *)arg);
 
        case SNDCTL_DSP_SETFRAGMENT:
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        as->usbin.dma.ossfragshift = val & 0xffff;
                        as->usbin.dma.ossmaxfrags = (val >> 16) & 0xffff;
@@ -2536,7+2545,8 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                if ((file->f_mode & FMODE_READ && as->usbin.dma.subdivision) ||
                    (file->f_mode & FMODE_WRITE && as->usbout.dma.subdivision))
                        return -EINVAL;
-               get_user_ret(val, (int *)arg, -EFAULT);
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
                if (file->f_mode & FMODE_READ)
index 00bd135..8fb3b3c 100644 (file)
@@ -607,7+607,8 @@ static int proc_control(struct dev_state *ps, void *arg)
        unsigned char *tbuf;
        int i, ret;
 
-       copy_from_user_ret(&ctrl, (void *)arg, sizeof(ctrl), -EFAULT);
+       if (copy_from_user(&ctrl, (void *)arg, sizeof(ctrl)))
+               return -EFAULT;
        switch (ctrl.requesttype & 0x1f) {
        case USB_RECIP_ENDPOINT:
                if ((ret = findintfep(ps->dev, ctrl.index & 0xff)) < 0)
@@ -636,11+637,13 @@ static int proc_control(struct dev_state *ps, void *arg)
                i = my_usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.request, ctrl.requesttype,
                                       ctrl.value, ctrl.index, tbuf, ctrl.length, tmo);
                if ((i > 0) && ctrl.length) {
-                       copy_to_user_ret(ctrl.data, tbuf, ctrl.length, -EFAULT);
+                       if (copy_to_user(ctrl.data, tbuf, ctrl.length))
+                               return -EFAULT;
                }
        } else {
                if (ctrl.length) {
-                       copy_from_user_ret(tbuf, ctrl.data, ctrl.length, -EFAULT);
+                       if (copy_from_user(tbuf, ctrl.data, ctrl.length))
+                               return -EFAULT;
                }
                i = my_usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.request, ctrl.requesttype,
                                       ctrl.value, ctrl.index, tbuf, ctrl.length, tmo);
@@ -662,7+665,8 @@ static int proc_bulk(struct dev_state *ps, void *arg)
        unsigned char *tbuf;
        int i, ret;
 
-       copy_from_user_ret(&bulk, (void *)arg, sizeof(bulk), -EFAULT);
+       if (copy_from_user(&bulk, (void *)arg, sizeof(bulk)))
+               return -EFAULT;
        if ((ret = findintfep(ps->dev, bulk.ep)) < 0)
                return ret;
        if ((ret = checkintf(ps, ret)))
@@ -686,11+690,13 @@ static int proc_bulk(struct dev_state *ps, void *arg)
                }
                i = my_usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
                if (!i && len2) {
-                       copy_to_user_ret(bulk.data, tbuf, len2, -EFAULT);
+                       if (copy_to_user(bulk.data, tbuf, len2))
+                               return -EFAULT;
                }
        } else {
                if (len1) {
-                       copy_from_user_ret(tbuf, bulk.data, len1, -EFAULT);
+                       if (copy_from_user(tbuf, bulk.data, len1))
+                               return -EFAULT;
                }
                i = my_usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
        }
@@ -708,7+714,8 @@ static int proc_resetep(struct dev_state *ps, void *arg)
        unsigned int ep;
        int ret;
 
-       get_user_ret(ep, (unsigned int *)arg, -EFAULT);
+       if (get_user(ep, (unsigned int *)arg))
+               return -EFAULT;
        if ((ret = findintfep(ps->dev, ep)) < 0)
                return ret;
        if ((ret = checkintf(ps, ret)))
@@ -723,7+730,8 @@ static int proc_clearhalt(struct dev_state *ps, void *arg)
        int pipe;
        int ret;
 
-       get_user_ret(ep, (unsigned int *)arg, -EFAULT);
+       if (get_user(ep, (unsigned int *)arg))
+               return -EFAULT;
        if ((ret = findintfep(ps->dev, ep)) < 0)
                return ret;
        if ((ret = checkintf(ps, ret)))
@@ -743,7+751,8 @@ static int proc_getdriver(struct dev_state *ps, void *arg)
        struct usb_interface *interface;
        int ret;
 
-       copy_from_user_ret(&gd, arg, sizeof(gd), -EFAULT);
+       if (copy_from_user(&gd, arg, sizeof(gd)))
+               return -EFAULT;
        if ((ret = findintfif(ps->dev, gd.interface)) < 0)
                return ret;
        interface = usb_ifnum_to_if(ps->dev, gd.interface);
@@ -752,7+761,8 @@ static int proc_getdriver(struct dev_state *ps, void *arg)
        if (!interface->driver)
                return -ENODATA;
        strcpy(gd.driver, interface->driver->name);
-       copy_to_user_ret(arg, &gd, sizeof(gd), -EFAULT);
+       if (copy_to_user(arg, &gd, sizeof(gd)))
+               return -EFAULT;
        return 0;
 }
 
@@ -762,7+772,8 @@ static int proc_connectinfo(struct dev_state *ps, void *arg)
 
        ci.devnum = ps->dev->devnum;
        ci.slow = ps->dev->slow;
-       copy_to_user_ret(arg, &ci, sizeof(ci), -EFAULT);
+       if (copy_to_user(arg, &ci, sizeof(ci)))
+               return -EFAULT;
        return 0;
 }
 
@@ -798,7+809,8 @@ static int proc_setintf(struct dev_state *ps, void *arg)
        struct usb_interface *interface;
        int ret;
 
-       copy_from_user_ret(&setintf, arg, sizeof(setintf), -EFAULT);
+       if (copy_from_user(&setintf, arg, sizeof(setintf)))
+               return -EFAULT;
        if ((ret = findintfif(ps->dev, setintf.interface)) < 0)
                return ret;
        interface = usb_ifnum_to_if(ps->dev, setintf.interface);
@@ -817,7+829,8 @@ static int proc_setconfig(struct dev_state *ps, void *arg)
 {
        unsigned int u;
 
-       get_user_ret(u, (unsigned int *)arg, -EFAULT);
+       if (get_user(u, (unsigned int *)arg))
+               return -EFAULT;
        if (usb_set_configuration(ps->dev, u) < 0)
                return -EINVAL;
        return 0;
@@ -831,7+844,8 @@ static int proc_submiturb(struct dev_state *ps, void *arg)
        unsigned int u, totlen, isofrmlen;
        int ret;
 
-       copy_from_user_ret(&uurb, arg, sizeof(uurb), -EFAULT);
+       if (copy_from_user(&uurb, arg, sizeof(uurb)))
+               return -EFAULT;
        if (uurb.flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_DISABLE_SPD))
                return -EINVAL;
        if (!uurb.buffer)
@@ -948,18+962,22 @@ static int processcompl(struct async *as)
        if (as->userbuffer)
                if (copy_to_user(as->userbuffer, as->urb.transfer_buffer, as->urb.transfer_buffer_length))
                        return -EFAULT;
-       put_user_ret(as->urb.status, &((struct usbdevfs_urb *)as->userurb)->status, -EFAULT);
-       put_user_ret(as->urb.actual_length, &((struct usbdevfs_urb *)as->userurb)->actual_length, -EFAULT);
-       put_user_ret(as->urb.error_count, &((struct usbdevfs_urb *)as->userurb)->error_count, -EFAULT);
+       if (put_user(as->urb.status,
+                    &((struct usbdevfs_urb *)as->userurb)->status) ||
+           __put_user(as->urb.actual_length,
+                      &((struct usbdevfs_urb *)as->userurb)->actual_length) ||
+           __put_user(as->urb.error_count,
+                      &((struct usbdevfs_urb *)as->userurb)->error_count))
+               return -EFAULT;
+
        if (!(usb_pipeisoc(as->urb.pipe)))
                return 0;
        for (i = 0; i < as->urb.number_of_packets; i++) {
-               put_user_ret(as->urb.iso_frame_desc[i].actual_length, 
-                            &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].actual_length, 
-                            -EFAULT);
-               put_user_ret(as->urb.iso_frame_desc[i].status, 
-                            &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].status, 
-                            -EFAULT);
+               if (put_user(as->urb.iso_frame_desc[i].actual_length, 
+                            &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].actual_length) ||
+                   __put_user(as->urb.iso_frame_desc[i].status, 
+                              &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].status))
+                       return -EFAULT;
        }
        return 0;
 }
@@ -990,7+1008,8 @@ static int proc_reapurb(struct dev_state *ps, void *arg)
                free_async(as);
                if (ret)
                        return ret;
-               put_user_ret(addr, (void **)arg, -EFAULT);
+               if (put_user(addr, (void **)arg))
+                       return -EFAULT;
                return 0;
        }
        if (signal_pending(current))
@@ -1011,7+1030,8 @@ static int proc_reapurbnonblock(struct dev_state *ps, void *arg)
        free_async(as);
        if (ret)
                return ret;
-       put_user_ret(addr, (void **)arg, -EFAULT);
+       if (put_user(addr, (void **)arg))
+               return -EFAULT;
        return 0;
 }
 
@@ -1019,7+1039,8 @@ static int proc_disconnectsignal(struct dev_state *ps, void *arg)
 {
        struct usbdevfs_disconnectsignal ds;
 
-       copy_from_user_ret(&ds, arg, sizeof(ds), -EFAULT);
+       if (copy_from_user(&ds, arg, sizeof(ds)))
+               return -EFAULT;
        if (ds.signr != 0 && (ds.signr < SIGRTMIN || ds.signr > SIGRTMAX))
                return -EINVAL;
        ps->discsignr = ds.signr;
@@ -1032,7+1053,8 @@ static int proc_claiminterface(struct dev_state *ps, void *arg)
        unsigned int intf;
        int ret;
 
-       get_user_ret(intf, (unsigned int *)arg, -EFAULT);
+       if (get_user(intf, (unsigned int *)arg))
+               return -EFAULT;
        if ((ret = findintfif(ps->dev, intf)) < 0)
                return ret;
        return claimintf(ps, ret);
@@ -1043,7+1065,8 @@ static int proc_releaseinterface(struct dev_state *ps, void *arg)
        unsigned int intf;
        int ret;
 
-       get_user_ret(intf, (unsigned int *)arg, -EFAULT);
+       if (get_user(intf, (unsigned int *)arg))
+               return -EFAULT;
        if ((ret = findintfif(ps->dev, intf)) < 0)
                return ret;
        return releaseintf(ps, intf);
@@ -1057,7+1080,8 @@ static int proc_ioctl (struct dev_state *ps, void *arg)
        int                     retval = 0;
 
        /* get input parameters and alloc buffer */
-       copy_from_user_ret (&ctrl, (void *) arg, sizeof (ctrl), -EFAULT);
+       if (copy_from_user(&ctrl, (void *) arg, sizeof (ctrl)))
+               return -EFAULT;
        if ((size = _IOC_SIZE (ctrl.ioctl_code)) > 0) {
                if ((buf = kmalloc (size, GFP_KERNEL)) == 0)
                        return -ENOMEM;
index c84a01f..59c9737 100644 (file)
@@ -113,15+113,15 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
                data = (void *) arg;
                if (data == NULL)
                        break;
-               copy_from_user_ret(&rio_cmd, data, sizeof(struct RioCommand),
-                                  -EFAULT);
+               if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand)))
+                       return -EFAULT;
                if (rio_cmd.length > PAGE_SIZE)
                        return -EINVAL;
                buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
                if (buffer == NULL)
                        return -ENOMEM;
-               copy_from_user_ret(buffer, rio_cmd.buffer, rio_cmd.length,
-                                  -EFAULT);
+               if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length))
+                       return -EFAULT;
 
                requesttype = rio_cmd.requesttype | USB_DIR_IN |
                    USB_TYPE_VENDOR | USB_RECIP_DEVICE;
@@ -150,8+150,9 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
                                dbg("Executed ioctl. Result = %d (data=%04x)",
                                     le32_to_cpu(result),
                                     le32_to_cpu(*((long *) buffer)));
-                               copy_to_user_ret(rio_cmd.buffer, buffer,
-                                                rio_cmd.length, -EFAULT);
+                               if (copy_to_user(rio_cmd.buffer, buffer,
+                                                rio_cmd.length))
+                                       return -EFAULT;
                                retries = 0;
                        }
 
@@ -170,15+171,15 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
                data = (void *) arg;
                if (data == NULL)
                        break;
-               copy_from_user_ret(&rio_cmd, data, sizeof(struct RioCommand),
-                                  -EFAULT);
+               if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand)))
+                       return -EFAULT;
                if (rio_cmd.length > PAGE_SIZE)
                        return -EINVAL;
                buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
                if (buffer == NULL)
                        return -ENOMEM;
-               copy_from_user_ret(buffer, rio_cmd.buffer, rio_cmd.length,
-                                  -EFAULT);
+               if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length))
+                       return -EFAULT;
 
                requesttype = rio_cmd.requesttype | USB_DIR_OUT |
                    USB_TYPE_VENDOR | USB_RECIP_DEVICE;
index f6206dd..fb91aae 100644 (file)
@@ -1,4+1,4 @@
-/*  $Id: atyfb.c,v 1.146 2000/07/26 23:02:51 davem Exp $
+/*  $Id: atyfb.c,v 1.147 2000/08/29 07:01:56 davem Exp $
  *  linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
  *
  *     Copyright (C) 1997-1998  Geert Uytterhoeven
@@ -3010,7+3010,8 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
        fbtyp.fb_depth = info->current_par.crtc.bpp;
        fbtyp.fb_cmsize = disp->cmap.len;
        fbtyp.fb_size = info->total_vram;
-       copy_to_user_ret((struct fbtype *)arg, &fbtyp, sizeof(fbtyp), -EFAULT);
+       if (copy_to_user((struct fbtype *)arg, &fbtyp, sizeof(fbtyp)))
+               return -EFAULT;
        break;
 #endif /* __sparc__ */
 #ifdef DEBUG
@@ -3031,8+3032,8 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
            clk.dsp_precision = (dsp_config>>20) & 7;
            clk.dsp_on = dsp_on_off & 0x7ff;
            clk.dsp_off = (dsp_on_off>>16) & 0x7ff;
-           copy_to_user_ret((struct atyclk *)arg, &clk, sizeof(clk),
-                            -EFAULT);
+           if (copy_to_user((struct atyclk *)arg, &clk, sizeof(clk)))
+                   return -EFAULT;
        } else
            return -EINVAL;
        break;
@@ -3040,8+3041,8 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
        if ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
            struct atyclk clk;
            struct pll_ct *pll = &info->current_par.pll.ct;
-           copy_from_user_ret(&clk, (struct atyclk *)arg, sizeof(clk),
-                              -EFAULT);
+           if (copy_from_user(&clk, (struct atyclk *)arg, sizeof(clk)))
+                   return -EFAULT;
            info->ref_clk_per = clk.ref_clk_per;
            pll->pll_ref_div = clk.pll_ref_div;
            pll->mclk_fb_div = clk.mclk_fb_div;
index fe7fae5..05a578b 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: cgfourteenfb.c,v 1.7 1999/11/19 09:57:01 davem Exp $
+/* $Id: cgfourteenfb.c,v 1.8 2000/08/29 07:01:56 davem Exp $
  * cgfourteenfb.c: CGfourteen frame buffer driver
  *
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -299,15+299,17 @@ static int cg14_ioctl (struct fb_info_sbusfb *fb, unsigned int cmd, unsigned lon
                break;
        case MDI_GET_CFGINFO:
                mdii = (struct mdi_cfginfo *)arg;
-               put_user_ret(FBTYPE_MDICOLOR, &mdii->mdi_type, -EFAULT);
-               __put_user_ret(fb->type.fb_height, &mdii->mdi_height, -EFAULT);
-               __put_user_ret(fb->type.fb_width, &mdii->mdi_width, -EFAULT);
-               __put_user_ret(fb->s.cg14.mode, &mdii->mdi_mode, -EFAULT);
-               __put_user_ret(72, &mdii->mdi_pixfreq, -EFAULT); /* FIXME */
-               __put_user_ret(fb->s.cg14.ramsize, &mdii->mdi_size, -EFAULT);
+               if (put_user(FBTYPE_MDICOLOR, &mdii->mdi_type) ||
+                   __put_user(fb->type.fb_height, &mdii->mdi_height) ||
+                   __put_user(fb->type.fb_width, &mdii->mdi_width) ||
+                   __put_user(fb->s.cg14.mode, &mdii->mdi_mode) ||
+                   __put_user(72, &mdii->mdi_pixfreq) || /* FIXME */
+                   __put_user(fb->s.cg14.ramsize, &mdii->mdi_size))
+                       return -EFAULT;
                break;
        case MDI_SET_PIXELMODE:
-               get_user_ret(mode, (int *)arg, -EFAULT);
+               if (get_user(mode, (int *)arg))
+                       return -EFAULT;
 
                spin_lock_irqsave(&fb->lock, flags);
                tmp = sbus_readb(mcr);
index 9a21d5d..b13b0aa 100644 (file)
@@ -1030,7+1030,8 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                err = matroxfb_get_vblank(PMINFO &vblank);
                                if (err)
                                        return err;
-                               copy_to_user_ret((struct fb_vblank*)arg, &vblank, sizeof(vblank), -EFAULT);
+                               if (copy_to_user((struct fb_vblank*)arg, &vblank, sizeof(vblank)))
+                                       return -EFAULT;
                                return 0;
                        }
                case MATROXFB_SET_OUTPUT_MODE:
@@ -1038,7+1039,8 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                struct matroxioc_output_mode mom;
                                int val;
 
-                               copy_from_user_ret(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom), -EFAULT);
+                               if (copy_from_user(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom)))
+                                       return -EFAULT;
                                if (mom.output >= sizeof(u_int32_t))
                                        return -EINVAL;
                                switch (mom.output) {
@@ -1084,7+1086,8 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                struct matroxioc_output_mode mom;
                                int val;
 
-                               copy_from_user_ret(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom), -EFAULT);
+                               if (copy_from_user(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom)))
+                                       return -EFAULT;
                                if (mom.output >= sizeof(u_int32_t))
                                        return -EINVAL;
                                switch (mom.output) {
@@ -1108,14+1111,16 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                        default:
                                                return -EINVAL;
                                }
-                               copy_to_user_ret((struct matroxioc_output_mode*)arg, &mom, sizeof(mom), -EFAULT);
+                               if (copy_to_user((struct matroxioc_output_mode*)arg, &mom, sizeof(mom)))
+                                       return -EFAULT;
                                return 0;
                        }
                case MATROXFB_SET_OUTPUT_CONNECTION:
                        {
                                u_int32_t tmp;
 
-                               copy_from_user_ret(&tmp, (u_int32_t*)arg, sizeof(tmp), -EFAULT);
+                               if (copy_from_user(&tmp, (u_int32_t*)arg, sizeof(tmp)))
+                                       return -EFAULT;
                                if (tmp & ~ACCESS_FBINFO(output.all))
                                        return -EINVAL;
                                if (tmp & ACCESS_FBINFO(output.sh))
@@ -1134,7+1139,8 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                        }
                case MATROXFB_GET_OUTPUT_CONNECTION:
                        {
-                               put_user_ret(ACCESS_FBINFO(output.ph), (u_int32_t*)arg, -EFAULT);
+                               if (put_user(ACCESS_FBINFO(output.ph), (u_int32_t*)arg))
+                                       return -EFAULT;
                                return 0;
                        }
                case MATROXFB_GET_AVAILABLE_OUTPUTS:
@@ -1146,12+1152,14 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                        tmp &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
                                if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY)
                                        tmp &= ~MATROXFB_OUTPUT_CONN_DFP;
-                               put_user_ret(tmp, (u_int32_t*)arg, -EFAULT);
+                               if (put_user(tmp, (u_int32_t*)arg))
+                                       return -EFAULT;
                                return 0;
                        }
                case MATROXFB_GET_ALL_OUTPUTS:
                        {
-                               put_user_ret(ACCESS_FBINFO(output.all), (u_int32_t*)arg, -EFAULT);
+                               if (put_user(ACCESS_FBINFO(output.all), (u_int32_t*)arg))
+                                       return -EFAULT;
                                return 0;
                        }
        }
index fff0a4f..515eb1e 100644 (file)
@@ -509,7+509,8 @@ static int matroxfb_dh_ioctl(struct inode* inode,
                                err = matroxfb_dh_get_vblank(m2info, &vblank);
                                if (err)
                                        return err;
-                               copy_to_user_ret((struct fb_vblank*)arg, &vblank, sizeof(vblank), -EFAULT);
+                               if (copy_to_user((struct fb_vblank*)arg, &vblank, sizeof(vblank)))
+                                       return -EFAULT;
                                return 0;
                        }
                case MATROXFB_SET_OUTPUT_MODE:
@@ -522,7+523,8 @@ static int matroxfb_dh_ioctl(struct inode* inode,
                        {
                                u_int32_t tmp;
 
-                               get_user_ret(tmp, (u_int32_t*)arg, -EFAULT);
+                               if (get_user(tmp, (u_int32_t*)arg))
+                                       return -EFAULT;
                                if (tmp & ~ACCESS_FBINFO(output.all))
                                        return -EINVAL;
                                if (tmp & ACCESS_FBINFO(output.ph))
@@ -539,7+541,8 @@ static int matroxfb_dh_ioctl(struct inode* inode,
                        }
                case MATROXFB_GET_OUTPUT_CONNECTION:
                        {
-                               put_user_ret(ACCESS_FBINFO(output.sh), (u_int32_t*)arg, -EFAULT);
+                               if (put_user(ACCESS_FBINFO(output.sh), (u_int32_t*)arg))
+                                       return -EFAULT;
                                return 0;
                        }
                case MATROXFB_GET_AVAILABLE_OUTPUTS:
@@ -551,7+554,8 @@ static int matroxfb_dh_ioctl(struct inode* inode,
                                /* CRTC1 in DFP mode disables CRTC2 at all (I know, I'm lazy) */
                                if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_DFP)
                                        tmp = 0;
-                               put_user_ret(tmp, (u_int32_t*)arg, -EFAULT);
+                               if (put_user(tmp, (u_int32_t*)arg))
+                                       return -EFAULT;
                                return 0;
                        }
        }
index 63d2b7c..f9fa0d2 100644 (file)
@@ -584,22+584,26 @@ static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
        
        switch (cmd){
        case FBIOGTYPE:         /* return frame buffer type */
-               copy_to_user_ret((struct fbtype *)arg, &fb->type, sizeof(struct fbtype), -EFAULT);
+               if (copy_to_user((struct fbtype *)arg, &fb->type, sizeof(struct fbtype)))
+                       return -EFAULT;
                break;
        case FBIOGATTR: {
                struct fbgattr *fba = (struct fbgattr *) arg;
                
                i = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct fbgattr));
                if (i) return i;
-               __put_user_ret(fb->emulations[0], &fba->real_type, -EFAULT);
-               __put_user_ret(0, &fba->owner, -EFAULT);
-               __copy_to_user_ret(&fba->fbtype, &fb->type,
-                                  sizeof(struct fbtype), -EFAULT);
-               __put_user_ret(0, &fba->sattr.flags, -EFAULT);
-               __put_user_ret(fb->type.fb_type, &fba->sattr.emu_type, -EFAULT);
-               __put_user_ret(-1, &fba->sattr.dev_specific[0], -EFAULT);
-               for (i = 0; i < 4; i++)
-                       put_user_ret(fb->emulations[i], &fba->emu_types[i], -EFAULT);
+               if (__put_user(fb->emulations[0], &fba->real_type) ||
+                   __put_user(0, &fba->owner) ||
+                   __copy_to_user(&fba->fbtype, &fb->type,
+                                  sizeof(struct fbtype)) ||
+                   __put_user(0, &fba->sattr.flags) ||
+                   __put_user(fb->type.fb_type, &fba->sattr.emu_type) ||
+                   __put_user(-1, &fba->sattr.dev_specific[0]))
+                       return -EFAULT;
+               for (i = 0; i < 4; i++) {
+                       if (put_user(fb->emulations[i], &fba->emu_types[i]))
+                               return -EFAULT;
+               }
                break;
        }
        case FBIOSATTR:
@@ -612,7+616,8 @@ static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
                        if (vt_cons[lastconsole]->vc_mode == KD_TEXT)
                                break;
                }
-               get_user_ret(i, (int *)arg, -EFAULT);
+               if (get_user(i, (int *)arg))
+                       return -EFAULT;
                if (i){
                        if (!fb->blanked || !fb->unblank)
                                break;
@@ -627,7+632,8 @@ static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
                }
                break;
        case FBIOGVIDEO:
-               put_user_ret(fb->blanked, (int *) arg, -EFAULT);
+               if (put_user(fb->blanked, (int *) arg))
+                       return -EFAULT;
                break;
        case FBIOGETCMAP_SPARC: {
                char *rp, *gp, *bp;
@@ -639,23+645,29 @@ static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
                i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct fbcmap));
                if (i) return i;
                cmap = (struct fbcmap *) arg;
-               __get_user_ret(count, &cmap->count, -EFAULT);
-               __get_user_ret(index, &cmap->index, -EFAULT);
+               if (__get_user(count, &cmap->count) ||
+                   __get_user(index, &cmap->index))
+                       return -EFAULT;
                if ((index < 0) || (index > 255))
                        return -EINVAL;
                if (index + count > 256)
                        count = 256 - index;
-               __get_user_ret(rp, &cmap->red, -EFAULT);
-               __get_user_ret(gp, &cmap->green, -EFAULT);
-               __get_user_ret(bp, &cmap->blue, -EFAULT);
-               if(verify_area (VERIFY_WRITE, rp, count))  return -EFAULT;
-               if(verify_area (VERIFY_WRITE, gp, count))  return -EFAULT;
-               if(verify_area (VERIFY_WRITE, bp, count))  return -EFAULT;
+               if (__get_user(rp, &cmap->red) ||
+                   __get_user(gp, &cmap->green) ||
+                   __get_user(bp, &cmap->blue))
+                       return -EFAULT;
+               if (verify_area (VERIFY_WRITE, rp, count))
+                       return -EFAULT;
+               if (verify_area (VERIFY_WRITE, gp, count))
+                       return -EFAULT;
+               if (verify_area (VERIFY_WRITE, bp, count))
+                       return -EFAULT;
                end = index + count;
                for (i = index; i < end; i++){
-                       __put_user_ret(fb->color_map CM(i,0), rp, -EFAULT);
-                       __put_user_ret(fb->color_map CM(i,1), gp, -EFAULT);
-                       __put_user_ret(fb->color_map CM(i,2), bp, -EFAULT);
+                       if (__put_user(fb->color_map CM(i,0), rp) ||
+                           __put_user(fb->color_map CM(i,1), gp) ||
+                           __put_user(fb->color_map CM(i,2), bp))
+                               return -EFAULT;
                        rp++; gp++; bp++;
                }
                (*fb->loadcmap)(fb, NULL, index, count);
@@ -671,24+683,32 @@ static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
                i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct fbcmap));
                if (i) return i;
                cmap = (struct fbcmap *) arg;
-               __get_user_ret(count, &cmap->count, -EFAULT);
-               __get_user_ret(index, &cmap->index, -EFAULT);
+               if (__get_user(count, &cmap->count) ||
+                   __get_user(index, &cmap->index))
+                       return -EFAULT;
                if ((index < 0) || (index > 255))
                        return -EINVAL;
                if (index + count > 256)
                        count = 256 - index;
-               __get_user_ret(rp, &cmap->red, -EFAULT);
-               __get_user_ret(gp, &cmap->green, -EFAULT);
-               __get_user_ret(bp, &cmap->blue, -EFAULT);
-               if(verify_area (VERIFY_READ, rp, count)) return -EFAULT;
-               if(verify_area (VERIFY_READ, gp, count)) return -EFAULT;
-               if(verify_area (VERIFY_READ, bp, count)) return -EFAULT;
+               if (__get_user(rp, &cmap->red) ||
+                   __get_user(gp, &cmap->green) ||
+                   __get_user(bp, &cmap->blue))
+                       return -EFAULT;
+               if (verify_area (VERIFY_READ, rp, count))
+                       return -EFAULT;
+               if (verify_area (VERIFY_READ, gp, count))
+                       return -EFAULT;
+               if (verify_area (VERIFY_READ, bp, count))
+                       return -EFAULT;
 
                end = index + count;
                for (i = index; i < end; i++){
-                       __get_user_ret(fb->color_map CM(i,0), rp, -EFAULT);
-                       __get_user_ret(fb->color_map CM(i,1), gp, -EFAULT);
-                       __get_user_ret(fb->color_map CM(i,2), bp, -EFAULT);
+                       if (__get_user(fb->color_map CM(i,0), rp))
+                               return -EFAULT;
+                       if (__get_user(fb->color_map CM(i,1), gp))
+                               return -EFAULT;
+                       if (__get_user(fb->color_map CM(i,2), bp))
+                               return -EFAULT;
                        rp++; gp++; bp++;
                }
                (*fb->loadcmap)(fb, NULL, index, count);
@@ -699,8+719,9 @@ static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
                if (!fb->setcursor) return -EINVAL;
                if(verify_area (VERIFY_WRITE, p, sizeof (struct fbcurpos)))
                        return -EFAULT;
-               __put_user_ret(fb->cursor.hwsize.fbx, &p->fbx, -EFAULT);
-               __put_user_ret(fb->cursor.hwsize.fby, &p->fby, -EFAULT);
+               if (__put_user(fb->cursor.hwsize.fbx, &p->fbx) ||
+                   __put_user(fb->cursor.hwsize.fby, &p->fby))
+                       return -EFAULT;
                break;
        }
        case FBIOSCURSOR:
index 994e873..0307995 100644 (file)
@@ -1,5+1,5 @@
 /*
- * SiS 300/630/540 frame buffer device For Kernal 2.3.x
+ * SiS 300/630/540 frame buffer device For Kernal 2.4.x
  *
  * This driver is partly based on the VBE 2.0 compliant graphic 
  * boards framebuffer driver, which is 
 
 #define EXPORT_SYMTAB
 #undef  SISFBDEBUG
+#undef CONFIG_FB_SIS_LINUXBIOS
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -174,11+175,10 @@ static struct board {
        u16 vendor, device;
        const char *name;
 } dev_list[] = {
-       {
-       PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300,  "SIS 300"}, {
-       PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5300, "SIS 540"}, {
-       PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_6300, "SIS 630"}, {
-       0, 0, NULL}
+       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300,     "SIS 300"},
+       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, "SIS 540"},
+       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, "SIS 630"},
+       {0, 0, NULL}
 };
 
 /* card parameters */
@@ -192,9+192,16 @@ static int video_cmap_len;
 static int sisfb_off = 0;
 
 static struct fb_var_screeninfo default_var = {
-       0, 0, 0, 0, 0, 0, 0, 0,
-       {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-       0, FB_ACTIVATE_NOW, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0,
+       0, 0,
+       0,
+       0,
+       {0, 8, 0},
+       {0, 8, 0},
+       {0, 8, 0},
+       {0, 0, 0},
+       0,
+       FB_ACTIVATE_NOW, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0,
        0,
        FB_VMODE_NONINTERLACED,
        {0, 0, 0, 0, 0, 0}
@@ -202,9+209,11 @@ static struct fb_var_screeninfo default_var = {
 
 static struct display disp;
 static struct fb_info fb_info;
+
 static struct {
        u16 blue, green, red, pad;
 } palette[256];
+
 static union {
 #ifdef FBCON_HAS_CFB16
        u16 cfb16[16];
@@ -230,7+239,7 @@ u16 P3c4, P3d4, P3c0, P3ce, P3c2, P3ca, P3c6, P3c7, P3c8, P3c9, P3da;
 u16 CRT1VCLKLen;
 u16 flag_clearbuffer;
 u16 CRT1VCLKLen;
-int ModeIDOffset, StandTable, CRT1Table, ScreenOffset, MCLKData, ECLKData;
+int ModeIDOffset, StandTable, CRT1Table, ScreenOffset;
 int REFIndex, ModeType;
 int VCLKData;
 int RAMType;
@@ -249,26+258,25 @@ static const struct _sisbios_mode {
        u16 cols;
        u16 rows;
 } sisbios_mode[] = {
-       {
-       "640x480x8", 0x2E, 640, 480, 8, 1, 80, 30}, {
-       "640x480x16", 0x44, 640, 480, 16, 1, 80, 30}, {
-       "640x480x32", 0x62, 640, 480, 32, 1, 80, 30}, {
-       "800x600x8", 0x30, 800, 600, 8, 2, 100, 37}, {
-       "800x600x16", 0x47, 800, 600, 16, 2, 100, 37}, {
-       "800x600x32", 0x63, 800, 600, 32, 2, 100, 37}, {
-       "1024x768x8", 0x38, 1024, 768, 8, 2, 128, 48}, {
-       "1024x768x16", 0x4A, 1024, 768, 16, 2, 128, 48}, {
-       "1024x768x32", 0x64, 1024, 768, 32, 2, 128, 48}, {
-       "1280x1024x8", 0x3A, 1280, 1024, 8, 2, 160, 64}, {
-       "1280x1024x16", 0x4D, 1280, 1024, 16, 2, 160, 64}, {
-       "1280x1024x32", 0x65, 1280, 1024, 32, 2, 160, 64}, {
-       "1600x1200x8", 0x3C, 1600, 1200, 8, 1, 200, 75}, {
-       "1600x1200x16", 0x3D, 1600, 1200, 16, 1, 200, 75}, {
-       "1600x1200x32", 0x66, 1600, 1200, 32, 1, 200, 75}, {
-       "1920x1440x8", 0x68, 1920, 1440, 8, 1, 240, 75}, {
-       "1920x1440x16", 0x69, 1920, 1440, 16, 1, 240, 75}, {
-       "1920x1440x32", 0x6B, 1920, 1440, 32, 1, 240, 75}, {
-       "\0", 0x00, 0, 0, 0, 0, 0, 0}
+       {"640x480x8",    0x2E,  640,  480,  8, 1,  80, 30},
+       {"640x480x16",   0x44,  640,  480, 16, 1,  80, 30},
+       {"640x480x32",   0x62,  640,  480, 32, 1,  80, 30},
+       {"800x600x8",    0x30,  800,  600,  8, 2, 100, 37},
+       {"800x600x16",   0x47,  800,  600, 16, 2, 100, 37},
+       {"800x600x32",   0x63,  800,  600, 32, 2, 100, 37}, 
+       {"1024x768x8",   0x38, 1024,  768,  8, 2, 128, 48},
+       {"1024x768x16",  0x4A, 1024,  768, 16, 2, 128, 48},
+       {"1024x768x32",  0x64, 1024,  768, 32, 2, 128, 48},
+       {"1280x1024x8",  0x3A, 1280, 1024,  8, 2, 160, 64},
+       {"1280x1024x16", 0x4D, 1280, 1024, 16, 2, 160, 64},
+       {"1280x1024x32", 0x65, 1280, 1024, 32, 2, 160, 64},
+       {"1600x1200x8",  0x3C, 1600, 1200,  8, 1, 200, 75},
+       {"1600x1200x16", 0x3D, 1600, 1200, 16, 1, 200, 75},
+       {"1600x1200x32", 0x66, 1600, 1200, 32, 1, 200, 75},
+       {"1920x1440x8",  0x68, 1920, 1440,  8, 1, 240, 75},
+       {"1920x1440x16", 0x69, 1920, 1440, 16, 1, 240, 75},
+       {"1920x1440x32", 0x6B, 1920, 1440, 32, 1, 240, 75},
+       {"\0", 0x00, 0, 0, 0, 0, 0, 0}
 };
 
 static struct _vrate {
@@ -277,57+285,33 @@ static struct _vrate {
        u16 yres;
        u16 refresh;
 } vrate[] = {
-       {
-       1, 640, 480, 60}, {
-       2, 640, 480, 72}, {
-       3, 640, 480, 75}, {
-       4, 640, 480, 85}, {
-       5, 640, 480, 100}, {
-       6, 640, 480, 120}, {
-       7, 640, 480, 160}, {
-       8, 640, 480, 200}, {
-       1, 800, 600, 56}, {
-       2, 800, 600, 60}, {
-       3, 800, 600, 72}, {
-       4, 800, 600, 75}, {
-       5, 800, 600, 85}, {
-       6, 800, 600, 100}, {
-       7, 800, 600, 120}, {
-       8, 800, 600, 160}, {
-       1, 1024, 768, 56}, {
-       2, 1024, 768, 60}, {
-       3, 1024, 768, 72}, {
-       4, 1024, 768, 75}, {
-       5, 1024, 768, 85}, {
-       6, 1024, 768, 100}, {
-       7, 1024, 768, 120}, {
-       1, 1280, 1024, 43}, {
-       2, 1280, 1024, 60}, {
-       3, 1280, 1024, 75}, {
-       4, 1280, 1024, 85}, {
-       1, 1600, 1200, 60}, {
-       2, 1600, 1200, 65}, {
-       3, 1600, 1200, 70}, {
-       4, 1600, 1200, 75}, {
-       5, 1600, 1200, 85}, {
-       1, 1920, 1440, 60}, {
-       0, 0, 0, 0}
+       {1,  640,  480,  60}, {2,  640, 480,  72}, {3,  640, 480,  75}, {4,  640, 480,  85},
+       {5,  640,  480, 100}, {6,  640, 480, 120}, {7,  640, 480, 160}, {8,  640, 480, 200},
+       {1,  800,  600,  56}, {2,  800, 600,  60}, {3,  800, 600,  72}, {4,  800, 600,  75},
+       {5,  800,  600,  85}, {6,  800, 600, 100}, {7,  800, 600, 120}, {8,  800, 600, 160},
+       {1, 1024,  768,  43}, {2, 1024, 768,  60}, {3, 1024, 768,  70}, {4, 1024, 768,  75},
+       {5, 1024,  768,  85}, {6, 1024, 768, 100}, {7, 1024, 768, 120},
+       {1, 1280, 1024,  43}, {2, 1280, 1024, 60}, {3, 1280, 1024, 75}, {4, 1280, 1024, 85},
+       {1, 1600, 1200,  60}, {2, 1600, 1200, 65}, {3, 1600, 1200, 70}, {4, 1600, 1200, 75},
+       {5, 1600, 1200,  85},
+       {1, 1920, 1440,  60},
+       {0, 0, 0, 0}
 };
 
-
-u16 DRAMType[17][5] =
-    { {0x0C, 0x0A, 0x02, 0x40, 0x39}, {0x0D, 0x0A, 0x01, 0x40, 0x48},
-{0x0C, 0x09, 0x02, 0x20, 0x35}, {0x0D, 0x09, 0x01, 0x20, 0x44},
-{0x0C, 0x08, 0x02, 0x10, 0x31}, {0x0D, 0x08, 0x01, 0x10, 0x40},
-{0x0C, 0x0A, 0x01, 0x20, 0x34}, {0x0C, 0x09, 0x01, 0x08, 0x32},
-{0x0B, 0x08, 0x02, 0x08, 0x21}, {0x0C, 0x08, 0x01, 0x08, 0x30},
-{0x0A, 0x08, 0x02, 0x04, 0x11}, {0x0B, 0x0A, 0x01, 0x10, 0x28},
-{0x09, 0x08, 0x02, 0x02, 0x01}, {0x0B, 0x09, 0x01, 0x08, 0x24},
-{0x0B, 0x08, 0x01, 0x04, 0x20}, {0x0A, 0x08, 0x01, 0x02, 0x10},
-{0x09, 0x08, 0x01, 0x01, 0x00}
+u16 DRAMType[17][5] = {
+       {0x0C, 0x0A, 0x02, 0x40, 0x39}, {0x0D, 0x0A, 0x01, 0x40, 0x48},
+       {0x0C, 0x09, 0x02, 0x20, 0x35}, {0x0D, 0x09, 0x01, 0x20, 0x44},
+       {0x0C, 0x08, 0x02, 0x10, 0x31}, {0x0D, 0x08, 0x01, 0x10, 0x40},
+       {0x0C, 0x0A, 0x01, 0x20, 0x34}, {0x0C, 0x09, 0x01, 0x08, 0x32},
+       {0x0B, 0x08, 0x02, 0x08, 0x21}, {0x0C, 0x08, 0x01, 0x08, 0x30},
+       {0x0A, 0x08, 0x02, 0x04, 0x11}, {0x0B, 0x0A, 0x01, 0x10, 0x28},
+       {0x09, 0x08, 0x02, 0x02, 0x01}, {0x0B, 0x09, 0x01, 0x08, 0x24},
+       {0x0B, 0x08, 0x01, 0x04, 0x20}, {0x0A, 0x08, 0x01, 0x02, 0x10},
+       {0x09, 0x08, 0x01, 0x01, 0x00}
 };
 
-u16 MDA_DAC[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+u16 MDA_DAC[] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
        0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
        0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
@@ -337,7+321,8 @@ u16 MDA_DAC[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
 };
 
-u16 CGA_DAC[] = { 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+u16 CGA_DAC[] = {
+       0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
        0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
        0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
        0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
@@ -347,7+332,8 @@ u16 CGA_DAC[] = { 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
        0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F
 };
 
-u16 EGA_DAC[] = { 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15,
+u16 EGA_DAC[] = {
+       0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15,
        0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35,
        0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D,
        0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D,
@@ -357,7+343,8 @@ u16 EGA_DAC[] = { 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15,
        0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F
 };
 
-u16 VGA_DAC[] = { 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+u16 VGA_DAC[] = {
+       0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
        0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
        0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
        0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
@@ -369,6+356,55 @@ u16 VGA_DAC[] = { 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
        0x0B, 0x0C, 0x0D, 0x0F, 0x10
 };
 
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+
+#define Monitor1Sense 0x20
+
+unsigned char SRegsInit[] = { 
+       0x03, 0x00, 0x03, 0x00, 0x02, 0xa1, 0x00, 0x13,
+       0x2f, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+       0x00, 0x0f, 0x00, 0x00, 0x4f, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 
+       0xa1, 0x76, 0xb2, 0xf6, 0x0d, 0x00, 0x00, 0x00,
+       0x37, 0x61, 0x80, 0x1b, 0xe1, 0x01, 0x55, 0x43, 
+       0x80, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0xff,
+       0x8e, 0x40, 0x00, 0x00, 0x08, 0x00, 0xff, 0xff
+};
+
+unsigned char SRegs[] = { 
+       0x03, 0x01, 0x0F, 0x00, 0x0E, 0xA1, 0x02, 0x13,
+       0x3F, 0x86, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+       0x0B, 0x0F, 0x00, 0x00, 0x4F, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x40, 0x00,
+       0xA1, 0xB6, 0xB2, 0xF6, 0x0D, 0x00, 0xF8, 0xF0,
+       0x37, 0x61, 0x80, 0x1B, 0xE1, 0x80, 0x55, 0x43,
+       0x80, 0x00, 0x11, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+       0x8E, 0x40, 0x00, 0x00, 0x08, 0x00, 0xFF, 0xFF
+};
+
+unsigned char CRegs[] = { 
+       0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
+       0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+       0xe9, 0x0b, 0xdf, 0x50, 0x40, 0xe7, 0x04, 0xa3,
+       0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff
+};     // clear CR11[7]
+
+unsigned char GRegs[] = { 
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff, 0x00
+};
+
+unsigned char ARegs[] = { 
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+unsigned char MReg = 0x6f;
+
+#endif
+
+
 /* HEAP stuff */
 
 struct OH {
@@ -463,6+499,7 @@ static void set_reg3(u16 port, u16 data);
 static void set_reg4(u16 port, unsigned long data);
 static u8 get_reg1(u16 port, u16 index);
 static u8 get_reg2(u16 port);
+//#ifndef CONFIG_FB_SIS_LINUXBIOS
 static u32 get_reg3(u16 port);
 static u16 get_modeID_length(unsigned long ROMAddr, u16 ModeNo);
 static int search_modeID(unsigned long ROMAddr, u16 ModeNo);
@@ -488,6+525,7 @@ static void set_crt1_FIFO(unsigned long ROMAddr);
 static void set_crt1_FIFO2(unsigned long ROMAddr);
 static void set_crt1_mode_regs(unsigned long ROMAddr, u16 ModeNo);
 static void set_interlace(unsigned long ROMAddr, u16 ModeNo);
+//#endif
 static void write_DAC(u16 dl, u16 ah, u16 al, u16 dh);
 static void load_DAC(unsigned long ROMAddr);
 static void display_on(void);
@@ -781,6+819,7 @@ static void sisfb_set_disp(int con, struct fb_var_screeninfo *var)
                sw = &fbcon_cfb8;
                break;
 #endif
+
 #ifdef FBCON_HAS_CFB16
        case 15:
        case 16:
@@ -788,18+827,21 @@ static void sisfb_set_disp(int con, struct fb_var_screeninfo *var)
                display->dispsw_data = fbcon_cmap.cfb16;
                break;
 #endif
+
 #ifdef FBCON_HAS_CFB24
        case 24:
                sw = &fbcon_cfb24;
                display->dispsw_data = fbcon_cmap.cfb24;
                break;
 #endif
+
 #ifdef FBCON_HAS_CFB32
        case 32:
                sw = &fbcon_cfb32;
                display->dispsw_data = fbcon_cmap.cfb32;
                break;
 #endif
+
        default:
                sw = &fbcon_dummy;
                return;
@@ -810,7+852,6 @@ static void sisfb_set_disp(int con, struct fb_var_screeninfo *var)
 
        display->scrollmode = SCROLL_YREDRAW;
        sisfb_sw.bmove = fbcon_redraw_bmove;
-
 }
 
 /*
@@ -818,9+859,8 @@ static void sisfb_set_disp(int con, struct fb_var_screeninfo *var)
  *    Return != 0 for invalid regno.
  */
 
-static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-                        unsigned *blue, unsigned *transp,
-                        struct fb_info *fb_info)
+static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
+                        unsigned *transp, struct fb_info *fb_info)
 {
        if (regno >= video_cmap_len)
                return 1;
@@ -838,9+878,8 @@ static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
  *    entries in the var structure). Return != 0 for invalid regno.
  */
 
-static int sis_setcolreg(unsigned regno, unsigned red, unsigned green,
-                        unsigned blue, unsigned transp,
-                        struct fb_info *fb_info)
+static int sis_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+                        unsigned transp, struct fb_info *fb_info)
 {
 
        if (regno >= video_cmap_len)
@@ -949,14+988,13 @@ static int do_set_var(struct fb_var_screeninfo *var, int isactive,
                return 1;
        }
 
-       if (search_refresh_rate(ivideo.refresh_rate) == 0) {    /* not supported rate */
+       if (search_refresh_rate(ivideo.refresh_rate) == 0) {
+               /* not supported rate */
                rate_idx = sisbios_mode[mode_idx].rate_idx;
                ivideo.refresh_rate = 60;
        }
 
-
-       if (((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
-           && isactive) {
+       if (((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
                pre_setmode();
 
                if (SiSSetMode(mode_no)) {
@@ -1020,7+1058,8 @@ static int sisfb_heap_init(void)
        struct OH *poh;
        u8 jTemp, tq_state;
 
-       if(ivideo.video_size > 0x800000)   /* video ram is large than 8M */
+       if (ivideo.video_size > 0x800000)
+               /* video ram is large than 8M */
                heap_start = (unsigned long) ivideo.video_vbase + RESERVED_MEM_SIZE_8M;
        else
                heap_start = (unsigned long) ivideo.video_vbase + RESERVED_MEM_SIZE_4M;
@@ -1401,22+1440,28 @@ static u32 get_reg3(u16 port)
 
 static u16 get_modeID_length(unsigned long ROMAddr, u16 ModeNo)
 {
-#if 0
        unsigned char ModeID;
        u16 modeidlength;
        u16 usModeIDOffset;
+       unsigned short PreviousWord,CurrentWord;
 
-       modeidlength = 0;
-       usModeIDOffset = *((u16 *) (ROMAddr + 0x20A));
-       ModeID = *((unsigned char *) (ROMAddr + usModeIDOffset));
-       while (ModeID != 0x2E) {
-               modeidlength++;
-               usModeIDOffset = usModeIDOffset + 1;
-               ModeID = *((unsigned char *) (ROMAddr + usModeIDOffset));
-       }
-       return (modeidlength);
-#endif
        return(10);
+   
+       modeidlength=0;
+       usModeIDOffset=*((unsigned short *)(ROMAddr+0x20A));      // Get EModeIDTable
+
+       CurrentWord=*((unsigned short *)(ROMAddr+usModeIDOffset));     // Offset 0x20A
+       PreviousWord=*((unsigned short *)(ROMAddr+usModeIDOffset-2));     // Offset 0x20A
+       while((CurrentWord!=0x2E07)||(PreviousWord!=0x0801)) 
+       {
+       modeidlength++;
+       usModeIDOffset=usModeIDOffset+1;               // 10 <= ExtStructSize
+       CurrentWord=*((unsigned short *)(ROMAddr+usModeIDOffset));
+       PreviousWord=*((unsigned short *)(ROMAddr+usModeIDOffset-2)); 
+       }
+       modeidlength++;
+
+       return(modeidlength);
 }
 
 static int search_modeID(unsigned long ROMAddr, u16 ModeNo)
@@ -1470,8+1515,7 @@ static void get_mode_ptr(unsigned long ROMAddr, u16 ModeNo)
        StandTable = *((u16 *) (ROMAddr + 0x202));
 
        if (ModeNo <= 13)
-               index =
-                   *((unsigned char *) (ROMAddr + ModeIDOffset + 0x03));
+               index = *((unsigned char *) (ROMAddr + ModeIDOffset + 0x03));
        else {
                if (ModeType <= 0x02)
                        index = 0x1B;
@@ -1488,26+1532,40 @@ static void set_seq_regs(unsigned long ROMAddr)
        unsigned char SRdata;
        u16 i;
 
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+       SRdata = SRegs[0x01];
+#else
        set_reg1(P3c4, 0x00, 0x03);
        StandTable = StandTable + 0x05;
        SRdata = *((unsigned char *) (ROMAddr + StandTable));
+#endif
+
        SRdata = SRdata | 0x20;
        set_reg1(P3c4, 0x01, SRdata);
 
+
        for (i = 02; i <= 04; i++) {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+               SRdata = SRegs[i];
+#else
                StandTable++;
                SRdata = *((unsigned char *) (ROMAddr + StandTable));
+#endif
                set_reg1(P3c4, i, SRdata);
        }
 }
 
 static void set_misc_regs(unsigned long ROMAddr)
 {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+       set_reg3(P3c2, 0x23);
+#else
        unsigned char Miscdata;
 
        StandTable++;
        Miscdata = *((unsigned char *) (ROMAddr + StandTable));
        set_reg3(P3c2, Miscdata);
+#endif
 }
 
 static void set_crtc_regs(unsigned long ROMAddr)
@@ -1516,13+1574,19 @@ static void set_crtc_regs(unsigned long ROMAddr)
        u16 i;
 
        CRTCdata = (unsigned char) get_reg1(P3d4, 0x11);
+#ifndef CONFIG_FB_SIS_LINUXBIOS
        CRTCdata = CRTCdata & 0x7f;
+#endif
        set_reg1(P3d4, 0x11, CRTCdata);
 
        for (i = 0; i <= 0x18; i++) {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+               set_reg1(P3d4, i, CRegs[i]);
+#else
                StandTable++;
                CRTCdata = *((unsigned char *) (ROMAddr + StandTable));
                set_reg1(P3d4, i, CRTCdata);
+#endif
        }
 }
 
@@ -1532,17+1596,23 @@ static void set_attregs(unsigned long ROMAddr)
        u16 i;
 
        for (i = 0; i <= 0x13; i++) {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+               get_reg2(P3da);
+               set_reg3(P3c0, i);
+               set_reg3(P3c0, ARegs[i]);
+#else
                StandTable++;
                ARdata = *((unsigned char *) (ROMAddr + StandTable));
 
                get_reg2(P3da);
                set_reg3(P3c0, i);
                set_reg3(P3c0, ARdata);
+#endif
        }
+
        get_reg2(P3da);
        set_reg3(P3c0, 0x14);
        set_reg3(P3c0, 0x00);
-
        get_reg2(P3da);
        set_reg3(P3c0, 0x20);
 }
@@ -1553,15+1623,22 @@ static void set_grc_regs(unsigned long ROMAddr)
        u16 i;
 
        for (i = 0; i <= 0x08; i++) {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+               set_reg1(P3ce, i, GRegs[i]);
+#else
                StandTable++;
                GRdata = *((unsigned char *) (ROMAddr + StandTable));
                set_reg1(P3ce, i, GRdata);
+#endif
        }
+
+#ifndef CONFIG_FB_SIS_LINUXBIOS
        if (ModeType > ModeVGA) {
                GRdata = (unsigned char) get_reg1(P3ce, 0x05);
                GRdata = GRdata & 0xBF;
                set_reg1(P3ce, 0x05, GRdata);
        }
+#endif
 }
 
 static void ClearExt1Regs(void)
@@ -1637,6+1714,9 @@ static int get_rate_ptr(unsigned long ROMAddr, u16 ModeNo)
 
 static void set_sync(unsigned long ROMAddr)
 {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+       set_reg3(P3c2, MReg);
+#else
        u16 sync;
        u16 temp;
 
@@ -1645,10+1725,33 @@ static void set_sync(unsigned long ROMAddr)
        temp = 0x2F;
        temp = temp | sync;
        set_reg3(P3c2, temp);
+#endif
 }
 
 static void set_crt1_crtc(unsigned long ROMAddr)
 {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+       unsigned char data;
+       u16 i;
+
+       data = (unsigned char) get_reg1(P3d4, 0x11);
+       data = data & 0x7F;
+       set_reg1(P3d4, 0x11, data);
+
+       for (i = 0; i <= 0x07; i++)
+               set_reg1(P3d4, i, CRegs[i]);
+       for (i = 0x10; i <= 0x12; i++)
+               set_reg1(P3d4, i, CRegs[i]);
+       for (i = 0x15; i <= 0x16; i++)
+               set_reg1(P3d4, i, CRegs[i]);
+       for (i = 0x0A; i <= 0x0C; i++)
+               set_reg1(P3c4, i, SRegs[i]);
+
+       data = SRegs[0x0E] & 0xE0;
+       set_reg1(P3c4, 0x0E, data);
+
+       set_reg1(P3d4, 0x09, CRegs[0x09]);
+#else
        unsigned char index;
        unsigned char data;
        u16 i;
@@ -1707,10+1810,16 @@ static void set_crt1_crtc(unsigned long ROMAddr)
 
        if (ModeType > 0x03)
                set_reg1(P3d4, 0x14, 0x4F);
+#endif
 }
 
+
 static void set_crt1_offset(unsigned long ROMAddr)
 {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+       set_reg1(P3c4, 0x0E, SRegs[0x0E]);
+       set_reg1(P3c4, 0x10, SRegs[0x10]);
+#else
        u16 temp, ah, al;
        u16 temp2, i;
        u16 DisplayUnit;
@@ -1773,6+1882,7 @@ static void set_crt1_offset(unsigned long ROMAddr)
        else
                ah = ah + 2;
        set_reg1(P3c4, 0x10, ah);
+#endif
 }
 
 static u16 get_vclk_len(unsigned long ROMAddr)
@@ -1792,31+1902,44 @@ static u16 get_vclk_len(unsigned long ROMAddr)
 static void set_crt1_vclk(unsigned long ROMAddr)
 {
        u16 i;
+
+#ifndef CONFIG_FB_SIS_LINUXBIOS
        unsigned char index, data;
 
        index = *((unsigned char *) (ROMAddr + REFIndex + 0x03));
+       index &= 0x03F;
        CRT1VCLKLen = get_vclk_len(ROMAddr);
        data = index * CRT1VCLKLen;
        VCLKData = *((u16 *) (ROMAddr + 0x208));
        VCLKData = VCLKData + data;
+#endif
 
        set_reg1(P3c4, 0x31, 0);
 
        for (i = 0x2B; i <= 0x2C; i++) {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+               set_reg1(P3c4, i, SRegs[i]);
+#else
                data = *((unsigned char *) (ROMAddr + VCLKData));
                set_reg1(P3c4, i, data);
                VCLKData++;
+#endif
        }
        set_reg1(P3c4, 0x2D, 0x80);
 }
-
 static void set_vclk_state(unsigned long ROMAddr, u16 ModeNo)
 {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+       set_reg1(P3c4, 0x32, SRegs[0x32]);
+       set_reg1(P3c4, 0x07, SRegs[0x07]);
+#else
+
        u16 data, data2;
        u16 VCLK;
        unsigned char index;
 
        index = *((unsigned char *) (ROMAddr + REFIndex + 0x03));
+       index &= 0x3F;
        CRT1VCLKLen = get_vclk_len(ROMAddr);
        data = index * CRT1VCLKLen;
        VCLKData = *((u16 *) (ROMAddr + 0x208));
@@ -1849,6+1972,7 @@ static void set_vclk_state(unsigned long ROMAddr, u16 ModeNo)
        data = data & 0xFC;
        data = data | data2;
        set_reg1(P3c4, 0x07, data);
+#endif
 }
 
 static u16 calc_delay2(unsigned long ROMAddr, u16 key)
@@ -1926,6+2050,7 @@ static void set_crt1_FIFO(unsigned long ROMAddr)
        u16 ah, bl, A, B;
 
        index = *((unsigned char *) (ROMAddr + REFIndex + 0x03));
+       index &= 0x3F;
        CRT1VCLKLen = get_vclk_len(ROMAddr);
        data = index * CRT1VCLKLen;
        VCLKData = *((u16 *) (ROMAddr + 0x208));
@@ -2017,14+2142,26 @@ static void set_crt1_FIFO(unsigned long ROMAddr)
        set_reg1(P3c4, 0x09, data2);
 }
 
-
 static void set_crt1_FIFO2(unsigned long ROMAddr)
 {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+       set_reg1(P3c4, 0x15, SRegs[0x15]);
+
+       set_reg4(0xcf8, 0x80000050);
+       set_reg4(0xcfc, 0xc5041e04);
+
+       set_reg1(P3c4, 0x08, SRegs[0x08]);
+       set_reg1(P3c4, 0x0F, SRegs[0x0F]);
+       set_reg1(P3c4, 0x3b, 0x00);
+       set_reg1(P3c4, 0x09, SRegs[0x09]);
+#else
+
        u16 index, data, VCLK, data2, MCLKOffset, MCLK, colorth = 1;
        u16 ah, bl, B;
        unsigned long eax;
 
        index = *((unsigned char *) (ROMAddr + REFIndex + 0x03));
+       index &= 0x3F;
        CRT1VCLKLen = get_vclk_len(ROMAddr);
        data = index * CRT1VCLKLen;
        VCLKData = *((u16 *) (ROMAddr + 0x208));
@@ -2115,10+2252,17 @@ static void set_crt1_FIFO2(unsigned long ROMAddr)
        data2 = data2 & 0xF0;
        data2 = data2 | data;
        set_reg1(P3c4, 0x09, data2);
+#endif
 }
 
 static void set_crt1_mode_regs(unsigned long ROMAddr, u16 ModeNo)
 {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+       set_reg1(P3c4, 0x06, SRegs[0x06]);
+       set_reg1(P3c4, 0x01, SRegs[0x01]);
+       set_reg1(P3c4, 0x0F, SRegs[0x0F]);
+       set_reg1(P3c4, 0x21, SRegs[0x21]);
+#else
 
        u16 data, data2, data3;
 
@@ -2166,11+2310,16 @@ static void set_crt1_mode_regs(unsigned long ROMAddr, u16 ModeNo)
        else
                data = data | 0xA0;
        set_reg1(P3c4, 0x21, data);
+#endif
 }
 
-
 static void set_interlace(unsigned long ROMAddr, u16 ModeNo)
 {
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+       set_reg1(P3d4, 0x19, CRegs[0x19]);
+       set_reg1(P3d4, 0x1A, CRegs[0x1A]);
+#else
+
        unsigned long Temp;
        u16 data, Temp2;
 
@@ -2201,6+2350,7 @@ static void set_interlace(unsigned long ROMAddr, u16 ModeNo)
        if (ModeNo == 0x37)
                Temp2 = Temp2 | 0x40;
        set_reg1(P3d4, 0x1A, (u16) Temp2);
+#endif
 }
 
 static void write_DAC(u16 dl, u16 ah, u16 al, u16 dh)
@@ -2239,6+2389,7 @@ static void load_DAC(unsigned long ROMAddr)
        u16 al, ah, dh;
        u16 *table = VGA_DAC;
 
+#ifndef CONFIG_FB_SIS_LINUXBIOS
        data = *((u16 *) (ROMAddr + ModeIDOffset + 0x01));
        data = data & DACInfoFlag;
        time = 64;
@@ -2252,6+2403,11 @@ static void load_DAC(unsigned long ROMAddr)
                time = 256;
                table = VGA_DAC;
        }
+#else
+       time = 256;
+       table = VGA_DAC;
+#endif
+
        if (time == 256)
                j = 16;
        else
@@ -2316,12+2472,339 @@ static void display_on(void)
        set_reg1(P3c4, 0x01, data);
 }
 
+void SetMemoryClock(void)
+{
+       unsigned char i;
+       int idx;
+
+       u8 MCLK[] = {
+               0x5A, 0x64, 0x80, 0x66, 0x00,   // SDRAM
+               0xB3, 0x45, 0x80, 0x83, 0x00,   // SGRAM
+               0x37, 0x61, 0x80, 0x00, 0x01,   // ESDRAM
+               0x37, 0x22, 0x80, 0x33, 0x01,
+               0x37, 0x61, 0x80, 0x00, 0x01,
+               0x37, 0x61, 0x80, 0x00, 0x01,
+               0x37, 0x61, 0x80, 0x00, 0x01,
+               0x37, 0x61, 0x80, 0x00, 0x01
+       };
+
+       u8 ECLK[] = {
+               0x54, 0x43, 0x80, 0x00, 0x01,
+               0x53, 0x43, 0x80, 0x00, 0x01,
+               0x55, 0x43, 0x80, 0x00, 0x01,
+               0x52, 0x43, 0x80, 0x00, 0x01,
+               0x3f, 0x42, 0x80, 0x00, 0x01,
+               0x54, 0x43, 0x80, 0x00, 0x01,
+               0x54, 0x43, 0x80, 0x00, 0x01,
+               0x54, 0x43, 0x80, 0x00, 0x01
+       };
+
+       idx = RAMType * 5;
+
+       for (i = 0x28; i <= 0x2A; i++) {        // Set MCLK
+               set_reg1(P3c4, i, MCLK[idx]);
+               idx++;
+       }
+
+       idx = RAMType * 5;
+       for (i = 0x2E; i <= 0x30; i++) {        // Set ECLK
+               set_reg1(P3c4, i, ECLK[idx]);
+               idx++;
+       }
+}
+
+void ClearDAC(u16 port)
+{
+       int i;
+
+       set_reg3(P3c8, 0x00);
+       for (i = 0; i < (256 * 3); i++)
+               set_reg3(P3c9, 0x00);
+}
+
+void ClearALLBuffer(void)
+{
+       unsigned long AdapterMemorySize;
+
+       AdapterMemorySize = get_reg1(P3c4, 0x14);
+       AdapterMemorySize = AdapterMemorySize & 0x3F;
+       AdapterMemorySize++;
+
+       memset((char *) ivideo.video_vbase, 0, AdapterMemorySize);
+}
+
+void LongWait(void)
+{
+       unsigned long temp;
+
+       for (temp = 1; temp > 0;) {
+               temp = get_reg2(P3da);
+               temp = temp & 0x08;
+       }
+       for (; temp == 0;) {
+               temp = get_reg2(P3da);
+               temp = temp & 0x08;
+       }
+}
+
+void WaitDisplay(void)
+{
+       unsigned short temp;
+
+       for (temp = 0; temp == 0;) {
+               temp = get_reg2(P3da);
+               temp = temp & 0x01;
+       }
+       for (; temp == 1;) {
+               temp = get_reg2(P3da);
+               temp = temp & 0x01;
+       }
+}
+
+int TestMonitorType(unsigned short d1, unsigned short d2, unsigned short d3)
+{
+       unsigned short temp;
+       set_reg3(P3c6, 0xFF);
+       set_reg3(P3c8, 0x00);
+       set_reg3(P3c9, d1);
+       set_reg3(P3c9, d2);
+       set_reg3(P3c9, d3);
+       WaitDisplay();          //wait horizontal retrace
+       temp = get_reg2(P3c2);
+       if (temp & 0x10)
+               return 1;
+       else
+               return 0;
+}
+
+void SetRegANDOR(unsigned short Port, unsigned short Index,
+                unsigned short DataAND, unsigned short DataOR)
+{
+       unsigned short temp1;
+       temp1 = get_reg1(Port, Index);  //part1port index 02
+       temp1 = (temp1 & (DataAND)) | DataOR;
+       set_reg1(Port, Index, temp1);
+}
+
+
+int DetectMonitor(void)
+{
+       unsigned short flag1;
+       unsigned short DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F };
+       unsigned short DAC_CLR_PARMS[3] = { 0x00, 0x00, 0x00 };
+
+       flag1 = get_reg1(P3c4, 0x38);   //call BridgeisOn
+       if ((flag1 & 0x20)) {
+               set_reg1(P3d4, 0x30, 0x41);
+       }
+
+       SiSSetMode(0x2E);       //set mode to 0x2E instead of 0x3
+
+       ClearDAC(P3c8);
+       ClearALLBuffer();
+
+       LongWait();
+       LongWait();
+
+       flag1 = TestMonitorType(DAC_TEST_PARMS[0], DAC_TEST_PARMS[1],
+                               DAC_TEST_PARMS[2]);
+       if (flag1 == 0) {
+               flag1 = TestMonitorType(DAC_TEST_PARMS[0], DAC_TEST_PARMS[1],
+                                       DAC_TEST_PARMS[2]);
+       }
+
+       if (flag1 == 1) {
+               SetRegANDOR(P3d4, 0x32, ~Monitor1Sense, Monitor1Sense);
+       } else {
+               SetRegANDOR(P3d4, 0x32, ~Monitor1Sense, 0x0);
+       }
+
+       TestMonitorType(DAC_CLR_PARMS[0], DAC_CLR_PARMS[1],
+                       DAC_CLR_PARMS[2]);
+
+       set_reg1(P3d4, 0x34, 0x4A);
+
+       return 1;
+}
+
+int SiSInit300(void)
+{
+       //unsigned long ROMAddr = rom_vbase;
+       u16 BaseAddr = (u16) ivideo.vga_base;
+       unsigned char i, temp, AGP;
+       unsigned long j, k, ulTemp;
+       unsigned char SR11, SR19, SR1A, SR21, SR22;
+       unsigned char SR14;
+       unsigned long Temp;
+
+       P3c4 = BaseAddr + 0x14;
+       P3d4 = BaseAddr + 0x24;
+       P3c0 = BaseAddr + 0x10;
+       P3ce = BaseAddr + 0x1e;
+       P3c2 = BaseAddr + 0x12;
+       P3ca = BaseAddr + 0x1a;
+       P3c6 = BaseAddr + 0x16;
+       P3c7 = BaseAddr + 0x17;
+       P3c8 = BaseAddr + 0x18;
+       P3c9 = BaseAddr + 0x19;
+       P3da = BaseAddr + 0x2A;
+
+       set_reg1(P3c4, 0x05, 0x86);     // 1.Openkey
+
+       SR14 = (unsigned char) get_reg1(P3c4, 0x14);
+       SR19 = (unsigned char) get_reg1(P3c4, 0x19);
+       SR1A = (unsigned char) get_reg1(P3c4, 0x1A);
+
+       for (i = 0x06; i < 0x20; i++)
+               set_reg1(P3c4, i, 0);   // 2.Reset Extended register
+       for (i = 0x21; i <= 0x27; i++)
+               set_reg1(P3c4, i, 0);   //   Reset Extended register
+       for (i = 0x31; i <= 0x3D; i++)
+               set_reg1(P3c4, i, 0);
+       for (i = 0x30; i <= 0x37; i++)
+               set_reg1(P3d4, i, 0);
+
+#if 0
+       if ((ivideo.chip_id == SIS_Trojan) || (ivideo.chip_id == SIS_Spartan))
+               // 3.Set Define Extended register
+               temp = (unsigned char) SR1A;
+       else {
+               temp = *((unsigned char *) (ROMAddr + SoftSettingAddr));
+               if ((temp & SoftDRAMType) == 0) {
+                       // 3.Set Define Extended register
+                       temp = (unsigned char) get_reg1(P3c4, 0x3A);
+               }
+       }
+#endif
+
+       // 3.Set Define Extended register
+       temp = (unsigned char) SR1A;
+
+       RAMType = temp & 0x07;
+       SetMemoryClock();
+       for (k = 0; k < 5; k++)
+               for (j = 0; j < 0xffff; j++)
+                       ulTemp = (unsigned long) get_reg1(P3c4, 0x05);
+
+       Temp = (unsigned long) get_reg1(P3c4, 0x3C);
+       Temp = Temp | 0x01;
+       set_reg1(P3c4, 0x3C, (unsigned short) Temp);
+       for (k = 0; k < 5; k++)
+               for (j = 0; j < 0xffff; j++)
+                       Temp = (unsigned long) get_reg1(P3c4, 0x05);
+
+       Temp = (unsigned long) get_reg1(P3c4, 0x3C);
+       Temp = Temp & 0xFE;
+       set_reg1(P3c4, 0x3C, (unsigned short) Temp);
+       for (k = 0; k < 5; k++)
+               for (j = 0; j < 0xffff; j++)
+                       Temp = (unsigned long) get_reg1(P3c4, 0x05);
+
+       //SR07=*((unsigned char *)(ROMAddr+0xA4));  // todo
+       set_reg1(P3c4, 0x07, SRegsInit[0x07]);
+#if 0
+       if (HwDeviceExtension->jChipID == SIS_Glamour)
+               for (i = 0x15; i <= 0x1C; i++) {
+                       temp = *((unsigned char *) (ROMAddr + 0xA5 + ((i - 0x15) * 8) + RAMType));
+                       set_reg1(P3c4, i, temp);
+               }
+#endif
+
+       //SR1F=*((unsigned char *)(ROMAddr+0xE5));  
+       set_reg1(P3c4, 0x1F, SRegsInit[0x1F]);
+
+       // Get AGP
+       AGP = 1;
+       temp = (unsigned char) get_reg1(P3c4, 0x3A);
+       temp = temp & 0x30;
+       if (temp == 0x30)
+               // PCI
+               AGP = 0;
+
+       //SR21=*((unsigned char *)(ROMAddr+0xE6));
+       SR21 = SRegsInit[0x21];
+       if (AGP == 0)
+               SR21 = SR21 & 0xEF;     // PCI
+       set_reg1(P3c4, 0x21, SR21);
+
+       //SR22=*((unsigned char *)(ROMAddr+0xE7));
+       SR22 = SRegsInit[0x22];
+       if (AGP == 1)
+               SR22 = SR22 & 0x20;     // AGP
+       set_reg1(P3c4, 0x22, SR22);
+
+       //SR23=*((unsigned char *)(ROMAddr+0xE8));
+       set_reg1(P3c4, 0x23, SRegsInit[0x23]);
+
+       //SR24=*((unsigned char *)(ROMAddr+0xE9));
+       set_reg1(P3c4, 0x24, SRegsInit[0x24]);
+
+       //SR25=*((unsigned char *)(ROMAddr+0xEA));
+       set_reg1(P3c4, 0x25, SRegsInit[0x25]);
+
+       //SR32=*((unsigned char *)(ROMAddr+0xEB));
+       set_reg1(P3c4, 0x32, SRegsInit[0x32]);
+
+       SR11 = 0x0F;
+       set_reg1(P3c4, 0x11, SR11);
+
+#if 0
+       if (IF_DEF_LVDS == 1) {
+               //LVDS
+               temp = ExtChipLVDS;
+       } else if (IF_DEF_TRUMPION == 1) {
+               //Trumpion
+               temp = ExtChipTrumpion;
+       } else {
+               //301
+               temp = ExtChip301;
+       }
+#endif
+
+       // 301;
+       temp = 0x02;
+       set_reg1(P3d4, 0x37, temp);
+
+#if 0
+       //09/07/99 modify by domao for 630/540 MM
+       if (HwDeviceExtension->jChipID == SIS_Glamour) {
+               //For SiS 300 Chip
+               SetDRAMSize(HwDeviceExtension);
+               SetDRAMSize(HwDeviceExtension);
+       } else {
+               //For SiS 630/540 Chip
+               //Restore SR14, SR19 and SR1A
+               set_reg1(P3c4, 0x14, SR14);
+               set_reg1(P3c4, 0x19, SR19);
+               set_reg1(P3c4, 0x1A, SR1A);
+       }
+#endif
+
+       set_reg1(P3c4, 0x14, SR14);
+       set_reg1(P3c4, 0x19, SR19);
+       set_reg1(P3c4, 0x1A, SR1A);
+       set_reg3(P3c6, 0xff);
+       ClearDAC(P3c8);
+       DetectMonitor();
+
+#if 0
+       //sense CRT2
+       GetSenseStatus(HwDeviceExtension, BaseAddr, ROMAddr);      
+#endif
+
+       return (TRUE);
+}
+
 static int SiSSetMode(u16 ModeNo)
 {
+       //#ifndef CONFIG_FB_SIS_LINUXBIOS
        unsigned long temp;
+       //#endif
+
        u16 cr30flag, cr31flag;
        unsigned long ROMAddr = rom_vbase;
        u16 BaseAddr = (u16) ivideo.vga_base;
+       u_short i;
 
        P3c4 = BaseAddr + 0x14;
        P3d4 = BaseAddr + 0x24;
@@ -2335,6+2818,7 @@ static int SiSSetMode(u16 ModeNo)
        P3c9 = BaseAddr + 0x19;
        P3da = BaseAddr + 0x2A;
 
+#ifndef CONFIG_FB_SIS_LINUXBIOS
        temp = search_modeID(ROMAddr, ModeNo);
 
        if (temp == 0)
@@ -2343,39+2827,186 @@ static int SiSSetMode(u16 ModeNo)
        temp = check_memory_size(ROMAddr);
        if (temp == 0)
                return (0);
+#endif
 
+#if 1
        cr30flag = (unsigned char) get_reg1(P3d4, 0x30);
        if (((cr30flag & 0x01) == 1) || ((cr30flag & 0x02) == 0)) {
+#ifndef CONFIG_FB_SIS_LINUXBIOS
                get_mode_ptr(ROMAddr, ModeNo);
+#endif
                set_seq_regs(ROMAddr);
                set_misc_regs(ROMAddr);
                set_crtc_regs(ROMAddr);
                set_attregs(ROMAddr);
                set_grc_regs(ROMAddr);
                ClearExt1Regs();
+
+#ifndef CONFIG_FB_SIS_LINUXBIOS
                temp = get_rate_ptr(ROMAddr, ModeNo);
                if (temp) {
+#endif
                        set_sync(ROMAddr);
                        set_crt1_crtc(ROMAddr);
                        set_crt1_offset(ROMAddr);
                        set_crt1_vclk(ROMAddr);
                        set_vclk_state(ROMAddr, ModeNo);
-                       if ((ivideo.chip_id == SIS_Trojan)
-                           || (ivideo.chip_id == SIS_Spartan))
+
+                       if ((ivideo.chip_id == SIS_Trojan) || (ivideo.chip_id == SIS_Spartan))
                                set_crt1_FIFO2(ROMAddr);
                        else    /* SiS 300 */
                                set_crt1_FIFO(ROMAddr);
+#ifndef CONFIG_FB_SIS_LINUXBIOS
                }
+#endif
                set_crt1_mode_regs(ROMAddr, ModeNo);
+               if ((ivideo.chip_id == SIS_Trojan) || (ivideo.chip_id == SIS_Spartan))
+                       set_interlace(ROMAddr, ModeNo);
+               load_DAC(ROMAddr);
+
+               /* clear OnScreen */
+               memset((char *) ivideo.video_vbase, 0,
+                      video_linelength * ivideo.video_height);
+       }
+#else
+       cr30flag = (unsigned char) get_reg1(P3d4, 0x30);
+       if (((cr30flag & 0x01) == 1) || ((cr30flag & 0x02) == 0)) {
+               //set_seq_regs(ROMAddr);
+               {
+                       unsigned char SRdata;
+                       SRdata = SRegs[0x01] | 0x20;
+                       set_reg1(P3c4, 0x01, SRdata);
+
+                       for (i = 02; i <= 04; i++)
+                               set_reg1(P3c4, i, SRegs[i]);
+               }
+
+               //set_misc_regs(ROMAddr);
+               {
+                       set_reg3(P3c2, 0x23);
+               }
+
+               //set_crtc_regs(ROMAddr);
+               {
+                       unsigned char CRTCdata;
+
+                       CRTCdata = (unsigned char) get_reg1(P3d4, 0x11);
+                       set_reg1(P3d4, 0x11, CRTCdata);
+
+                       for (i = 0; i <= 0x18; i++)
+                               set_reg1(P3d4, i, CRegs[i]);
+               }
+
+               //set_attregs(ROMAddr);
+               {
+                       for (i = 0; i <= 0x13; i++) {
+                               get_reg2(P3da);
+                               set_reg3(P3c0, i);
+                               set_reg3(P3c0, ARegs[i]);
+                       }
+                       get_reg2(P3da);
+                       set_reg3(P3c0, 0x14);
+                       set_reg3(P3c0, 0x00);
+                       get_reg2(P3da);
+                       set_reg3(P3c0, 0x20);
+               }
+
+               //set_grc_regs(ROMAddr);
+               {
+                       for (i = 0; i <= 0x08; i++)
+                               set_reg1(P3ce, i, GRegs[i]);
+               }
+
+               //ClearExt1Regs();
+               {
+                       for (i = 0x0A; i <= 0x0E; i++)
+                               set_reg1(P3c4, i, 0x00);
+               }
+
+               //set_sync(ROMAddr);
+               {
+                       set_reg3(P3c2, MReg);
+               }
+
+               //set_crt1_crtc(ROMAddr);
+               {
+                       unsigned char data;
+
+                       data = (unsigned char) get_reg1(P3d4, 0x11);
+                       data = data & 0x7F;
+                       set_reg1(P3d4, 0x11, data);
+
+                       for (i = 0; i <= 0x07; i++)
+                               set_reg1(P3d4, i, CRegs[i]);
+                       for (i = 0x10; i <= 0x12; i++)
+                               set_reg1(P3d4, i, CRegs[i]);
+                       for (i = 0x15; i <= 0x16; i++)
+                               set_reg1(P3d4, i, CRegs[i]);
+                       for (i = 0x0A; i <= 0x0C; i++)
+                               set_reg1(P3c4, i, SRegs[i]);
+
+                       data = SRegs[0x0E] & 0xE0;
+                       set_reg1(P3c4, 0x0E, data);
+
+                       set_reg1(P3d4, 0x09, CRegs[0x09]);
+
+               }
+
+               //set_crt1_offset(ROMAddr);
+               {
+                       set_reg1(P3c4, 0x0E, SRegs[0x0E]);
+                       set_reg1(P3c4, 0x10, SRegs[0x10]);
+               }
+
+               //set_crt1_vclk(ROMAddr);
+               {
+                       set_reg1(P3c4, 0x31, 0);
+
+                       for (i = 0x2B; i <= 0x2C; i++)
+                               set_reg1(P3c4, i, SRegs[i]);
+                       set_reg1(P3c4, 0x2D, 0x80);
+               }
+
+               //set_vclk_state(ROMAddr, ModeNo);
+               {
+                       set_reg1(P3c4, 0x32, SRegs[0x32]);
+                       set_reg1(P3c4, 0x07, SRegs[0x07]);
+               }
+
                if ((ivideo.chip_id == SIS_Trojan)
-                   || (ivideo.chip_id ==
-                       SIS_Spartan)) set_interlace(ROMAddr, ModeNo);
+                   || (ivideo.chip_id == SIS_Spartan)) {
+                       //set_crt1_FIFO2(ROMAddr);
+                       set_reg1(P3c4, 0x15, SRegs[0x15]);
+
+                       set_reg4(0xcf8, 0x80000050);
+                       set_reg4(0xcfc, 0xc5041e04);
+
+                       set_reg1(P3c4, 0x08, SRegs[0x08]);
+                       set_reg1(P3c4, 0x0F, SRegs[0x0F]);
+                       set_reg1(P3c4, 0x3b, 0x00);
+                       set_reg1(P3c4, 0x09, SRegs[0x09]);
+               }
+
+               //set_crt1_mode_regs(ROMAddr, ModeNo);
+               {
+                       set_reg1(P3c4, 0x06, SRegs[0x06]);
+                       set_reg1(P3c4, 0x01, SRegs[0x01]);
+                       set_reg1(P3c4, 0x0F, SRegs[0x0F]);
+                       set_reg1(P3c4, 0x21, SRegs[0x21]);
+               }
+
+               if ((ivideo.chip_id == SIS_Trojan) || (ivideo.chip_id == SIS_Spartan)) {
+                       //set_interlace(ROMAddr, ModeNo);
+                       set_reg1(P3d4, 0x19, CRegs[0x19]);
+                       set_reg1(P3d4, 0x1A, CRegs[0x1A]);
+               }
                load_DAC(ROMAddr);
 
                /* clear OnScreen */
                memset((char *) ivideo.video_vbase, 0,
                       video_linelength * ivideo.video_height);
        }
+#endif
        cr31flag = (unsigned char) get_reg1(P3d4, 0x31);
 
        display_on();
@@ -2508,8+3139,7 @@ static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
        DPRINTK("sisfb: sisfb_get_var:[%d]\n", con);
 
        if (con == -1)
-               memcpy(var, &default_var,
-                      sizeof(struct fb_var_screeninfo));
+               memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
        else
                *var = fb_display[con].var;
        return 0;
@@ -2570,8+3200,8 @@ static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
        else if (fb_display[con].cmap.len)      /* non default colormap? */
                fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
        else
-               fb_copy_cmap(fb_default_cmap(video_cmap_len),
-                            cmap, kspc ? 0 : 2);
+               fb_copy_cmap(fb_default_cmap(video_cmap_len), cmap, kspc ? 0 : 2);
+
        return 0;
 }
 
@@ -2602,12+3232,12 @@ static int sisfb_ioctl(struct inode *inode, struct file *file,
 {
        switch (cmd) {
        case FBIO_ALLOC:
-               if(!capable(CAP_SYS_RAWIO))
+               if (!capable(CAP_SYS_RAWIO))
                        return -EPERM;
                sis_malloc((struct sis_memreq *) arg);
                break;
        case FBIO_FREE:
-               if(!capable(CAP_SYS_RAWIO))
+               if (!capable(CAP_SYS_RAWIO))
                        return -EPERM;
                sis_free(*(unsigned long *) arg);
                break;
@@ -2668,9+3298,9 @@ static int sisfb_mmap(struct fb_info *info, struct file *file,
        if (boot_cpu_data.x86 > 3)
                pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
 #endif
-       if (io_remap_page_range(vma->vm_start, off,
-                               vma->vm_end - vma->vm_start,
-                               vma->vm_page_prot)) return -EAGAIN;
+       if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start,
+                               vma->vm_page_prot))
+               return -EAGAIN;
        return 0;
 }
 
@@ -2695,7+3325,7 @@ int sisfb_setup(char *options)
        if (!options || !*options)
                return 0;
 
-       for (this_opt = strtok(options, ","); this_opt;
+       for (this_opt = strtok(options, ","); this_opt; 
             this_opt = strtok(NULL, ",")) {
                if (!*this_opt)
                        continue;
@@ -2786,10+3416,13 @@ static void sisfb_blank(int blank, struct fb_info *info)
 
 int __init sisfb_init(void)
 {
-       struct pci_dev *pdev;
+       struct pci_dev *pdev = NULL;
        struct board *b;
        int pdev_valid = 0;
        unsigned char jTemp;
+       u32 cmd;
+
+       outb(0x77, 0x80);
 
        if (sisfb_off)
                return -ENXIO;
@@ -2814,12+3447,45 @@ int __init sisfb_init(void)
        if (!pdev_valid)
                return -1;
 
-       ivideo.video_base = pdev->resource[0].start & ~0x7FFFFF;
-       ivideo.mmio_base = pdev->resource[1].start & ~0x3FFF;
-       ivideo.vga_base = (pdev->resource[2].start & 0xFFFFFC) + 0x30;
-       rom_base = 0x000C0000;
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+       pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
+       cmd |= PCI_COMMAND_IO;
+       cmd |= PCI_COMMAND_MEMORY;
+       pci_write_config_dword(pdev, PCI_COMMAND, cmd); 
+#endif
 
+       ivideo.video_base = pci_resource_start(pdev, 0);
+       if (!request_mem_region(ivideo.video_base, pci_resource_len(pdev, 0),
+                               "sisfb FB")) {
+               printk(KERN_ERR "sisfb: cannot reserve frame buffer memory\n");
+               return -ENODEV;
+       }
+       ivideo.mmio_base = pci_resource_start(pdev, 1);
+       if (!request_mem_region(ivideo.mmio_base, pci_resource_len(pdev, 1),
+                               "sisfb MMIO")) {
+               printk(KERN_ERR "sisfb: cannot reserve MMIO region\n");
+               release_mem_region(pci_resource_start(pdev, 1), 
+                                  pci_resource_len(pdev, 1));
+               return -ENODEV;
+       }
+       ivideo.vga_base = pci_resource_start(pdev, 2);
+       if (!request_region(ivideo.vga_base, pci_resource_len(pdev, 2),
+                           "sisfb IO")) {
+               printk(KERN_ERR "sisfb: cannot reserve I/O ports\n");
+               release_mem_region(pci_resource_start(pdev, 1),
+                                  pci_resource_len(pdev, 1));
+               release_mem_region(pci_resource_start(pdev, 0),
+                                  pci_resource_len(pdev, 0));
+               return -ENODEV;
+       }
+       ivideo.vga_base += 0x30;
+
+#ifndef CONFIG_FB_SIS_LINUXBIOS
+       rom_base = 0x000C0000;
        request_region(rom_base, 32, "sisfb");
+#else
+        rom_base = 0x0;
+#endif
 
        /* set passwd */
        vgawb(SEQ_ADR, IND_SIS_PASSWORD);
@@ -2839,13+3505,21 @@ int __init sisfb_init(void)
        if (mode_idx < 0)
                mode_idx = DEFAULT_MODE;        /* 0:640x480x8 */
 
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+       mode_idx = DEFAULT_MODE;
+       rate_idx = sisbios_mode[mode_idx].rate_idx;
+       /* set to default refresh rate 60MHz */
+       ivideo.refresh_rate = 60;
+#endif
+
        mode_no = sisbios_mode[mode_idx].mode_no;
 
        if (ivideo.refresh_rate != 0)
                search_refresh_rate(ivideo.refresh_rate);
 
        if (rate_idx == 0) {
-               rate_idx = sisbios_mode[mode_idx].rate_idx;     /* set to default refresh rate 60MHz */
+               rate_idx = sisbios_mode[mode_idx].rate_idx;
+               /* set to default refresh rate 60MHz */
                ivideo.refresh_rate = 60;
        }
 
@@ -2854,25+3528,14 @@ int __init sisfb_init(void)
        ivideo.video_height = sisbios_mode[mode_idx].yres;
        video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
 
-       if (!request_mem_region(ivideo.video_base, ivideo.video_size, "sisfb FB")) 
-       {
-               printk(KERN_ERR
-                      "sisfb: abort, cannot reserve video memory at 0x%lx\n",
-                      ivideo.video_base);
-               return -1;
-       }
-
-       if (!request_mem_region(ivideo.mmio_base, MMIO_SIZE, "sisfb MMIO")) 
-       {
-               printk(KERN_ERR
-                      "sisfb: abort, cannot reserve mmio memory at 0x%lx\n",
-                      ivideo.mmio_base);
-               return -1;
-       }
-
        ivideo.video_vbase = ioremap(ivideo.video_base, ivideo.video_size);
        ivideo.mmio_vbase = ioremap(ivideo.mmio_base, MMIO_SIZE);
+
+#ifndef CONFIG_FB_SIS_LINUXBIOS
        rom_vbase = (unsigned long) ioremap(rom_base, MAX_ROM_SCAN);
+#endif
+
+       SiSInit300(); 
 
        printk(KERN_INFO
               "sisfb: framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
index 4e67ec8..6abc44d 100644 (file)
@@ -11,9+11,10 @@ FILESYSTEMS = $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o))
 O_TARGET := fs.o
 O_OBJS    = open.o read_write.o devices.o file_table.o buffer.o \
                super.o  block_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
-               ioctl.o readdir.o select.o fifo.o locks.o filesystems.o \
+               ioctl.o readdir.o select.o fifo.o locks.o \
                dcache.o inode.o attr.o bad_inode.o file.o iobuf.o \
                $(BINFMTS) $(FILESYSTEMS)
+OX_OBJS := filesystems.o
 
 ALL_SUB_DIRS := coda minix ext2 fat msdos vfat proc isofs nfs umsdos ntfs \
                hpfs sysv smbfs ncpfs ufs efs affs romfs autofs hfs lockd \
index 7b6573d..7c7c8ba 100644 (file)
@@ -53,7+53,7 @@ static int autofs_write(struct file *file, const void *addr, int bytes)
 
        /** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/
 
-       sigpipe = sigismember(&current->signal, SIGPIPE);
+       sigpipe = sigismember(&current->pending.signal, SIGPIPE);
 
        /* Save pointer to user space and point back to kernel space */
        fs = get_fs();
@@ -71,7+71,7 @@ static int autofs_write(struct file *file, const void *addr, int bytes)
           SIGPIPE unless it was already supposed to get one */
        if (wr == -EPIPE && !sigpipe) {
                spin_lock_irqsave(&current->sigmask_lock, flags);
-               sigdelset(&current->signal, SIGPIPE);
+               sigdelset(&current->pending.signal, SIGPIPE);
                recalc_sigpending(current);
                spin_unlock_irqrestore(&current->sigmask_lock, flags);
        }
index f49f213..a76cde2 100644 (file)
@@ -57,7+57,7 @@ static int autofs4_write(struct file *file, const void *addr, int bytes)
 
        /** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/
 
-       sigpipe = sigismember(&current->signal, SIGPIPE);
+       sigpipe = sigismember(&current->pending.signal, SIGPIPE);
 
        /* Save pointer to user space and point back to kernel space */
        fs = get_fs();
@@ -75,7+75,7 @@ static int autofs4_write(struct file *file, const void *addr, int bytes)
           SIGPIPE unless it was already supposed to get one */
        if (wr == -EPIPE && !sigpipe) {
                spin_lock_irqsave(&current->sigmask_lock, flags);
-               sigdelset(&current->signal, SIGPIPE);
+               sigdelset(&current->pending.signal, SIGPIPE);
                recalc_sigpending(current);
                spin_unlock_irqrestore(&current->sigmask_lock, flags);
        }
index 4225311..445c47a 100644 (file)
@@ -1045,7+1045,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
        notes[0].datasz = sizeof(prstatus);
        notes[0].data = &prstatus;
        prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
-       prstatus.pr_sigpend = current->signal.sig[0];
+       prstatus.pr_sigpend = current->pending.signal.sig[0];
        prstatus.pr_sighold = current->blocked.sig[0];
        psinfo.pr_pid = prstatus.pr_pid = current->pid;
        psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid;
index ca6e2f9..05f52aa 100644 (file)
@@ -2606,8+2606,8 @@ int kupdate(void *sem)
                if (signal_pending(tsk)) {
                        int stopped = 0;
                        spin_lock_irq(&tsk->sigmask_lock);
-                       if (sigismember(&tsk->signal, SIGSTOP)) {
-                               sigdelset(&tsk->signal, SIGSTOP);
+                       if (sigismember(&tsk->pending.signal, SIGSTOP)) {
+                               sigdelset(&tsk->pending.signal, SIGSTOP);
                                stopped = 1;
                        }
                        recalc_sigpending(tsk);
@@ -2625,9+2625,9 @@ int kupdate(void *sem)
 static int __init bdflush_init(void)
 {
        DECLARE_MUTEX_LOCKED(sem);
-       kernel_thread(bdflush, &sem, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+       kernel_thread(bdflush, &sem, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
        down(&sem);
-       kernel_thread(kupdate, &sem, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+       kernel_thread(kupdate, &sem, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
        down(&sem);
        return 0;
 }
index f0c64b4..1cab951 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -427,7+427,7 @@ static int exec_mmap(void)
  * This function makes sure the current process has its own signal table,
  * so that flush_signal_handlers can later reset the handlers without
  * disturbing other processes.  (Other processes might share the signal
- * table via the CLONE_SIGHAND option to clone().)
+ * table via the CLONE_SIGNAL option to clone().)
  */
  
 static inline int make_private_signals(void)
index 456f9ba..7321f45 100644 (file)
@@ -9,7+9,7 @@
 
 O_TARGET := ext2.o
 O_OBJS   := acl.o balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
-               ioctl.o namei.o super.o symlink.o truncate.o
+               ioctl.o namei.o super.o symlink.o
 M_OBJS   := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
index c99f7f2..6f5eceb 100644 (file)
@@ -398,9+398,13 @@ repeat:
                        ext2_error (sb, "ext2_new_inode",
                                    "Free inodes count corrupted in group %d",
                                    i);
-                       unlock_super (sb);
-                       iput (inode);
-                       return NULL;
+                       if (sb->s_flags & MS_RDONLY) {
+                               unlock_super (sb);
+                               iput (inode);
+                               return NULL;
+                       }
+                       gdp->bg_free_inodes_count = 0;
+                       mark_buffer_dirty(bh2, 1);
                }
                goto repeat;
        }
@@ -411,6+415,7 @@ repeat:
                            "block_group = %d,inode=%d", i, j);
                unlock_super (sb);
                iput (inode);
+               *err = -EIO;
                return NULL;
        }
        gdp->bg_free_inodes_count =
index 4f0b78d..9c2abac 100644 (file)
@@ -704,6+704,285 @@ struct address_space_operations ext2_aops = {
        bmap: ext2_bmap
 };
 
+/*
+ * Probably it should be a library function... search for first non-zero word
+ * or memcmp with zero_page, whatever is better for particular architecture.
+ * Linus?
+ */
+static inline int all_zeroes(u32 *p, u32 *q)
+{
+       while (p < q)
+               if (*p++)
+                       return 1;
+       return 0;
+}
+
+/**
+ *     ext2_find_shared - find the indirect blocks for partial truncation.
+ *     @inode:   inode in question
+ *     @depth:   depth of the affected branch
+ *     @offsets: offsets of pointers in that branch (see ext2_block_to_path)
+ *     @chain:   place to store the pointers to partial indirect blocks
+ *     @top:     place to the (detached) top of branch
+ *
+ *     This is a helper function used by ext2_truncate().
+ *
+ *     When we do truncate() we may have to clean the ends of several indirect
+ *     blocks but leave the blocks themselves alive. Block is partially
+ *     truncated if some data below the new i_size is refered from it (and
+ *     it is on the path to the first completely truncated data block, indeed).
+ *     We have to free the top of that path along with everything to the right
+ *     of the path. Since no allocation past the truncation point is possible
+ *     until ext2_truncate() finishes, we may safely do the latter, but top
+ *     of branch may require special attention - pageout below the truncation
+ *     point might try to populate it.
+ *
+ *     We atomically detach the top of branch from the tree, store the block
+ *     number of its root in *@top, pointers to buffer_heads of partially
+ *     truncated blocks - in @chain[].bh and pointers to their last elements
+ *     that should not be removed - in @chain[].p. Return value is the pointer
+ *     to last filled element of @chain.
+ *
+ *     The work left to caller to do the actual freeing of subtrees:
+ *             a) free the subtree starting from *@top
+ *             b) free the subtrees whose roots are stored in
+ *                     (@chain[i].p+1 .. end of @chain[i].bh->b_data)
+ *             c) free the subtrees growing from the inode past the @chain[0].p
+ *                     (no partially truncated stuff there).
+ */
+
+static Indirect *ext2_find_shared(struct inode *inode,
+                               int depth,
+                               int offsets[4],
+                               Indirect chain[4],
+                               u32 *top)
+{
+       Indirect *partial, *p;
+       int k, err;
+
+       *top = 0;
+       for (k = depth; k > 1 && !offsets[k-1]; k--)
+               ;
+       partial = ext2_get_branch(inode, k, offsets, chain, &err);
+       /* Writer: pointers */
+       if (!partial)
+               partial = chain + k-1;
+       /*
+        * If the branch acquired continuation since we've looked at it -
+        * fine, it should all survive and (new) top doesn't belong to us.
+        */
+       if (!partial->key && *partial->p)
+               /* Writer: end */
+               goto no_top;
+       for (p=partial; p>chain && all_zeroes((u32*)p->bh->b_data,p->p); p--)
+               ;
+       /*
+        * OK, we've found the last block that must survive. The rest of our
+        * branch should be detached before unlocking. However, if that rest
+        * of branch is all ours and does not grow immediately from the inode
+        * it's easier to cheat and just decrement partial->p.
+        */
+       if (p == chain + k - 1 && p > chain) {
+               p->p--;
+       } else {
+               *top = *p->p;
+               *p->p = 0;
+       }
+       /* Writer: end */
+
+       while(partial > p)
+       {
+               brelse(partial->bh);
+               partial--;
+       }
+no_top:
+       return partial;
+}
+
+/**
+ *     ext2_free_data - free a list of data blocks
+ *     @inode: inode we are dealing with
+ *     @p:     array of block numbers
+ *     @q:     points immediately past the end of array
+ *
+ *     We are freeing all blocks refered from that array (numbers are
+ *     stored as little-endian 32-bit) and updating @inode->i_blocks
+ *     appropriately.
+ */
+static inline void ext2_free_data(struct inode *inode, u32 *p, u32 *q)
+{
+       int blocks = inode->i_sb->s_blocksize / 512;
+       unsigned long block_to_free = 0, count = 0;
+       unsigned long nr;
+
+       for ( ; p < q ; p++) {
+               nr = le32_to_cpu(*p);
+               if (nr) {
+                       *p = 0;
+                       /* accumulate blocks to free if they're contiguous */
+                       if (count == 0)
+                               goto free_this;
+                       else if (block_to_free == nr - count)
+                               count++;
+                       else {
+                               /* Writer: ->i_blocks */
+                               inode->i_blocks -= blocks * count;
+                               /* Writer: end */
+                               ext2_free_blocks (inode, block_to_free, count);
+                               mark_inode_dirty(inode);
+                       free_this:
+                               block_to_free = nr;
+                               count = 1;
+                       }
+               }
+       }
+       if (count > 0) {
+               /* Writer: ->i_blocks */
+               inode->i_blocks -= blocks * count;
+               /* Writer: end */
+               ext2_free_blocks (inode, block_to_free, count);
+               mark_inode_dirty(inode);
+       }
+}
+
+/**
+ *     ext2_free_branches - free an array of branches
+ *     @inode: inode we are dealing with
+ *     @p:     array of block numbers
+ *     @q:     pointer immediately past the end of array
+ *     @depth: depth of the branches to free
+ *
+ *     We are freeing all blocks refered from these branches (numbers are
+ *     stored as little-endian 32-bit) and updating @inode->i_blocks
+ *     appropriately.
+ */
+static void ext2_free_branches(struct inode *inode, u32 *p, u32 *q, int depth)
+{
+       struct buffer_head * bh;
+       unsigned long nr;
+
+       if (depth--) {
+               int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
+               for ( ; p < q ; p++) {
+                       nr = le32_to_cpu(*p);
+                       if (!nr)
+                               continue;
+                       *p = 0;
+                       bh = bread (inode->i_dev, nr, inode->i_sb->s_blocksize);
+                       /*
+                        * A read failure? Report error and clear slot
+                        * (should be rare).
+                        */ 
+                       if (!bh) {
+                               ext2_error(inode->i_sb, "ext2_free_branches",
+                                       "Read failure, inode=%ld, block=%ld",
+                                       inode->i_ino, nr);
+                               continue;
+                       }
+                       ext2_free_branches(inode,
+                                          (u32*)bh->b_data,
+                                          (u32*)bh->b_data + addr_per_block,
+                                          depth);
+                       bforget(bh);
+                       /* Writer: ->i_blocks */
+                       inode->i_blocks -= inode->i_sb->s_blocksize / 512;
+                       /* Writer: end */
+                       ext2_free_blocks(inode, nr, 1);
+                       mark_inode_dirty(inode);
+               }
+       } else
+               ext2_free_data(inode, p, q);
+}
+
+void ext2_truncate (struct inode * inode)
+{
+       u32 *i_data = inode->u.ext2_i.i_data;
+       int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
+       int offsets[4];
+       Indirect chain[4];
+       Indirect *partial;
+       int nr = 0;
+       int n;
+       long iblock;
+
+       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+           S_ISLNK(inode->i_mode)))
+               return;
+       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+               return;
+
+       ext2_discard_prealloc(inode);
+
+       iblock = (inode->i_size + inode->i_sb->s_blocksize-1)
+                                       >> EXT2_BLOCK_SIZE_BITS(inode->i_sb);
+
+       n = ext2_block_to_path(inode, iblock, offsets);
+       if (n == 0)
+               return;
+
+       if (n == 1) {
+               ext2_free_data(inode, i_data+offsets[0],
+                                       i_data + EXT2_NDIR_BLOCKS);
+               goto do_indirects;
+       }
+
+       partial = ext2_find_shared(inode, n, offsets, chain, &nr);
+       /* Kill the top of shared branch (already detached) */
+       if (nr) {
+               if (partial == chain)
+                       mark_inode_dirty(inode);
+               else
+                       mark_buffer_dirty(partial->bh, 1);
+               ext2_free_branches(inode, &nr, &nr+1, (chain+n-1) - partial);
+       }
+       /* Clear the ends of indirect blocks on the shared branch */
+       while (partial > chain) {
+               ext2_free_branches(inode,
+                                  partial->p + 1,
+                                  (u32*)partial->bh->b_data + addr_per_block,
+                                  (chain+n-1) - partial);
+               mark_buffer_dirty(partial->bh, 1);
+               if (IS_SYNC(inode)) {
+                       ll_rw_block (WRITE, 1, &partial->bh);
+                       wait_on_buffer (partial->bh);
+               }
+               brelse (partial->bh);
+               partial--;
+       }
+do_indirects:
+       /* Kill the remaining (whole) subtrees */
+       switch (offsets[0]) {
+               default:
+                       nr = i_data[EXT2_IND_BLOCK];
+                       if (nr) {
+                               i_data[EXT2_IND_BLOCK] = 0;
+                               mark_inode_dirty(inode);
+                               ext2_free_branches(inode, &nr, &nr+1, 1);
+                       }
+               case EXT2_IND_BLOCK:
+                       nr = i_data[EXT2_DIND_BLOCK];
+                       if (nr) {
+                               i_data[EXT2_DIND_BLOCK] = 0;
+                               mark_inode_dirty(inode);
+                               ext2_free_branches(inode, &nr, &nr+1, 2);
+                       }
+               case EXT2_DIND_BLOCK:
+                       nr = i_data[EXT2_TIND_BLOCK];
+                       if (nr) {
+                               i_data[EXT2_TIND_BLOCK] = 0;
+                               mark_inode_dirty(inode);
+                               ext2_free_branches(inode, &nr, &nr+1, 3);
+                       }
+               case EXT2_TIND_BLOCK:
+                       ;
+       }
+       inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+       if (IS_SYNC(inode))
+               ext2_sync_inode (inode);
+       else
+               mark_inode_dirty(inode);
+}
+
 void ext2_read_inode (struct inode * inode)
 {
        struct buffer_head * bh;
@@ -781,30+1060,22 @@ void ext2_read_inode (struct inode * inode)
        inode->i_blksize = PAGE_SIZE;   /* This is the optimal IO size (for stat), not the fs block size */
        inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
        inode->i_version = ++event;
-       inode->u.ext2_i.i_new_inode = 0;
        inode->u.ext2_i.i_flags = le32_to_cpu(raw_inode->i_flags);
        inode->u.ext2_i.i_faddr = le32_to_cpu(raw_inode->i_faddr);
        inode->u.ext2_i.i_frag_no = raw_inode->i_frag;
        inode->u.ext2_i.i_frag_size = raw_inode->i_fsize;
-       inode->u.ext2_i.i_osync = 0;
        inode->u.ext2_i.i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
        if (S_ISDIR(inode->i_mode))
                inode->u.ext2_i.i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl);
        else {
-               inode->u.ext2_i.i_dir_acl = 0;
                inode->u.ext2_i.i_high_size = le32_to_cpu(raw_inode->i_size_high);
                inode->i_size |= ((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32;
        }
        inode->i_generation = le32_to_cpu(raw_inode->i_generation);
        inode->u.ext2_i.i_block_group = block_group;
-       inode->u.ext2_i.i_next_alloc_block = 0;
-       inode->u.ext2_i.i_next_alloc_goal = 0;
-       if (inode->u.ext2_i.i_prealloc_count)
-               ext2_error (inode->i_sb, "ext2_read_inode",
-                           "New inode has non-zero prealloc count!");
 
        /*
-        * NOTE! The in-memory inode i_blocks array is in little-endian order
+        * NOTE! The in-memory inode i_data array is in little-endian order
         * even on big-endian machines: we do NOT byteswap the block numbers!
         */
        for (block = 0; block < EXT2_N_BLOCKS; block++)
@@ -940,9+1211,23 @@ static int ext2_update_inode(struct inode * inode, int do_sync)
        raw_inode->i_file_acl = cpu_to_le32(inode->u.ext2_i.i_file_acl);
        if (S_ISDIR(inode->i_mode))
                raw_inode->i_dir_acl = cpu_to_le32(inode->u.ext2_i.i_dir_acl);
-       else
+       else {
                raw_inode->i_size_high = cpu_to_le32(inode->i_size >> 32);
-
+               if (raw_inode->i_size_high) {
+                       struct super_block *sb = inode->i_sb;
+                       struct ext2_super_block *es = sb->u.ext2_sb.s_es;
+                       if (!(es->s_feature_ro_compat & cpu_to_le32(EXT2_FEATURE_RO_COMPAT_LARGE_FILE))) {
+                              /* If this is the first large file
+                               * created, add a flag to the superblock.
+                               */
+                               lock_kernel();
+                               es->s_feature_ro_compat |= cpu_to_le32(EXT2_FEATURE_RO_COMPAT_LARGE_FILE);
+                               unlock_kernel();
+                               ext2_write_super(sb);
+                       }
+               }
+       }
+       
        raw_inode->i_generation = cpu_to_le32(inode->i_generation);
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
                raw_inode->i_block[0] = cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
@@ -966,7+1251,7 @@ static int ext2_update_inode(struct inode * inode, int do_sync)
 void ext2_write_inode (struct inode * inode, int wait)
 {
        lock_kernel();
-       ext2_update_inode (inode, 0);
+       ext2_update_inode (inode, wait);
        unlock_kernel();
 }
 
index 46e2739..44423a6 100644 (file)
@@ -366,12+366,9 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, int mode)
        struct inode * inode;
        int err;
 
-       /*
-        * N.B. Several error exits in ext2_new_inode don't set err.
-        */
        inode = ext2_new_inode (dir, mode, &err);
        if (!inode)
-               return -EIO;
+               return err;
 
        inode->i_op = &ext2_file_inode_operations;
        inode->i_fop = &ext2_file_operations;
@@ -397,7+394,7 @@ static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int
 
        inode = ext2_new_inode (dir, mode, &err);
        if (!inode)
-               return -EIO;
+               return err;
 
        inode->i_uid = current->fsuid;
        init_special_inode(inode, mode, rdev);
@@ -428,7+425,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
 
        inode = ext2_new_inode (dir, S_IFDIR, &err);
        if (!inode)
-               return -EIO;
+               return err;
 
        inode->i_op = &ext2_dir_inode_operations;
        inode->i_fop = &ext2_dir_operations;
@@ -634,7+631,7 @@ static int ext2_symlink (struct inode * dir, struct dentry *dentry, const char *
                return -ENAMETOOLONG;
 
        if (!(inode = ext2_new_inode (dir, S_IFLNK, &err)))
-               return -EIO;
+               return err;
 
        inode->i_mode = S_IFLNK | S_IRWXUGO;
 
diff --git a/fs/ext2/truncate.c b/fs/ext2/truncate.c
deleted file mode 100644 (file)
index ba83971..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- *  linux/fs/ext2/truncate.c
- *
- * Copyright (C) 1992, 1993, 1994, 1995
- * Remy Card (card@masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
- *
- *  from
- *
- *  linux/fs/minix/truncate.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *
- *  Big-endian to little-endian byte-swapping/bitmaps by
- *        David S. Miller (davem@caip.rutgers.edu), 1995
- *
- *  General cleanup and race fixes, wsh, 1998
- */
-
-#include <linux/fs.h>
-#include <linux/locks.h>
-
-
-/*
- * Real random numbers for secure rm added 94/02/18
- * Idea from Pierre del Perugia <delperug@gla.ecoledoc.ibp.fr>
- */
-
-#if 0
-
-/*
- * Secure deletion currently doesn't work. It interacts very badly
- * with buffers shared with memory mappings, and for that reason
- * can't be done in the truncate() routines. It should instead be
- * done separately in "release()" before calling the truncate routines
- * that will release the actual file blocks.
- *
- *             Linus
- */
-static int ext2_secrm_seed = 152;      /* Random generator base */
-
-#define RANDOM_INT (ext2_secrm_seed = ext2_secrm_seed * 69069l +1)
-#endif
-
-/*
- * Macros to return the block number for the inode size and offset.
- * Currently we always hold the inode semaphore during truncate, so
- * there's no need to test for changes during the operation.
- */
-#define DIRECT_BLOCK(inode) \
-       ((unsigned long) ((inode->i_size + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits))
-#define INDIRECT_BLOCK(inode,offset) ((int)DIRECT_BLOCK(inode) - offset)
-#define DINDIRECT_BLOCK(inode,offset) \
-       (INDIRECT_BLOCK(inode,offset) / addr_per_block)
-#define TINDIRECT_BLOCK(inode,offset) \
-       (INDIRECT_BLOCK(inode,offset) / (addr_per_block*addr_per_block))
-
-/*
- * Truncate has the most races in the whole filesystem: coding it is
- * a pain in the a**. Especially as I don't do any locking...
- *
- * The code may look a bit weird, but that's just because I've tried to
- * handle things like file-size changes in a somewhat graceful manner.
- * Anyway, truncating a file at the same time somebody else writes to it
- * is likely to result in pretty weird behaviour...
- *
- * The new code handles normal truncates (size = 0) as well as the more
- * general case (size = XXX). I hope.
- *
- *
- * Truncate operations have been rewritten to avoid various races. The
- * previous code was allowing blocking operations to precede a call to
- * bforget(), possible allowing the buffer to be used again.
- *
- * We now ensure that b_count == 1 before calling bforget() and that the
- * parent buffer (if any) is unlocked before clearing the block pointer.
- * The operations are always performed in this order:
- *     (1) Make sure that the parent buffer is unlocked.
- *     (2) Use find_buffer() to find the block buffer without blocking,
- *         and set 'retry' if the buffer is locked or b_count > 1.
- *     (3) Clear the block pointer in the parent (buffer or inode).
- *     (4) Update the inode block count and mark the inode dirty.
- *     (5) Forget the block buffer, if any. This call won't block, as
- *         we know the buffer is unlocked from (2).
- *     (6) If the block pointer is in a (parent) buffer, mark the buffer
- *         dirty. (Note that this can block on a loop device.)
- *     (7) Accumulate the blocks to free and/or update the block bitmap.
- *         (This operation will frequently block.)
- *
- * The requirement that parent buffers be unlocked follows from the general
- * principle of not modifying a buffer that may be undergoing I/O. With the
- * the present kernels there's no problem with modifying a locked inode, as
- * the I_DIRTY bit is cleared before setting I_LOCK.
- *             -- WSH, 1998
- */
-
-/*
- * Check whether any of the slots in an indirect block are
- * still in use, and if not free the block.
- */
-static int check_block_empty(struct inode *inode, struct buffer_head *bh,
-                               u32 *p, struct buffer_head *ind_bh)
-{
-       int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
-       u32 * ind = (u32 *) bh->b_data;
-       int i, retry;
-
-       /* Make sure both buffers are unlocked */
-       do {
-               retry = 0;
-               if (buffer_locked(bh)) {
-                       __wait_on_buffer(bh);
-                       retry = 1;
-               }
-               if (ind_bh && buffer_locked(ind_bh)) {
-                       __wait_on_buffer(ind_bh);
-                       retry = 1;
-               }
-       } while (retry);
-
-       for (i = 0; i < addr_per_block; i++)
-               if (*(ind++))
-                       goto in_use;
-
-       if (atomic_read(&bh->b_count) == 1) {
-               int tmp;
-               tmp = le32_to_cpu(*p);
-               *p = 0;
-               inode->i_blocks -= (inode->i_sb->s_blocksize / 512);
-               mark_inode_dirty(inode);
-               /*
-                * Forget the buffer, then mark the parent buffer dirty.
-                */
-               bforget(bh);
-               if (ind_bh)
-                       mark_buffer_dirty(ind_bh, 1);
-               ext2_free_blocks(inode, tmp, 1);
-               goto out;
-       }
-       retry = 1;
-
-in_use:
-       if (IS_SYNC(inode) && buffer_dirty(bh)) {
-               ll_rw_block (WRITE, 1, &bh);
-               wait_on_buffer (bh);
-       }
-       brelse (bh);
-
-out:
-       return retry;
-}
-
-#define DATA_BUFFER_USED(bh) \
-       (atomic_read(&bh->b_count) || buffer_locked(bh))
-
-static int trunc_direct (struct inode * inode)
-{
-       int i, retry = 0;
-       unsigned long block_to_free = 0, free_count = 0;
-       int blocks = inode->i_sb->s_blocksize / 512;
-       int direct_block = DIRECT_BLOCK(inode);
-
-       for (i = direct_block ; i < EXT2_NDIR_BLOCKS ; i++) {
-               u32 * p = inode->u.ext2_i.i_data + i;
-               int tmp = le32_to_cpu(*p);
-
-               if (!tmp)
-                       continue;
-
-               *p = 0;
-               inode->i_blocks -= blocks;
-               mark_inode_dirty(inode);
-
-               /* accumulate blocks to free if they're contiguous */
-               if (free_count == 0)
-                       goto free_this;
-               else if (block_to_free == tmp - free_count)
-                       free_count++;
-               else {
-                       ext2_free_blocks (inode, block_to_free, free_count);
-               free_this:
-                       block_to_free = tmp;
-                       free_count = 1;
-               }
-       }
-       if (free_count > 0)
-               ext2_free_blocks (inode, block_to_free, free_count);
-       return retry;
-}
-
-static int trunc_indirect (struct inode * inode, int offset, u32 * p, struct buffer_head *dind_bh)
-{
-       struct buffer_head * ind_bh;
-       int i, tmp, retry = 0;
-       unsigned long block_to_free = 0, free_count = 0;
-       int indirect_block, addr_per_block, blocks;
-
-       tmp = le32_to_cpu(*p);
-       if (!tmp)
-               return 0;
-       ind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize);
-       if (tmp != le32_to_cpu(*p)) {
-               brelse (ind_bh);
-               return 1;
-       }
-       /* A read failure? Report error and clear slot (should be rare). */ 
-       if (!ind_bh) {
-               ext2_error(inode->i_sb, "trunc_indirect",
-                       "Read failure, inode=%ld, block=%d",
-                       inode->i_ino, tmp);
-               *p = 0;
-               if (dind_bh)
-                       mark_buffer_dirty(dind_bh, 1);
-               else
-                       mark_inode_dirty(inode);
-               return 0;
-       }
-
-       blocks = inode->i_sb->s_blocksize / 512;
-       addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
-       indirect_block = INDIRECT_BLOCK(inode, offset);
-       if (indirect_block < 0)
-               indirect_block = 0;
-       for (i = indirect_block ; i < addr_per_block ; i++) {
-               u32 * ind = i + (u32 *) ind_bh->b_data;
-
-               wait_on_buffer(ind_bh);
-               tmp = le32_to_cpu(*ind);
-               if (!tmp)
-                       continue;
-
-               *ind = 0;
-               inode->i_blocks -= blocks;
-               mark_inode_dirty(inode);
-               mark_buffer_dirty(ind_bh, 1);
-
-               /* accumulate blocks to free if they're contiguous */
-               if (free_count == 0)
-                       goto free_this;
-               else if (block_to_free == tmp - free_count)
-                       free_count++;
-               else {
-                       ext2_free_blocks (inode, block_to_free, free_count);
-               free_this:
-                       block_to_free = tmp;
-                       free_count = 1;
-               }
-       }
-       if (free_count > 0)
-               ext2_free_blocks (inode, block_to_free, free_count);
-       /*
-        * Check the block and dispose of the ind_bh buffer.
-        */
-       retry |= check_block_empty(inode, ind_bh, p, dind_bh);
-
-       return retry;
-}
-
-static int trunc_dindirect (struct inode * inode, int offset, u32 * p,
-                       struct buffer_head * tind_bh)
-{
-       struct buffer_head * dind_bh;
-       int i, tmp, retry = 0;
-       int dindirect_block, addr_per_block;
-
-       tmp = le32_to_cpu(*p);
-       if (!tmp)
-               return 0;
-       dind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize);
-       if (tmp != le32_to_cpu(*p)) {
-               brelse (dind_bh);
-               return 1;
-       }
-       /* A read failure? Report error and clear slot (should be rare). */ 
-       if (!dind_bh) {
-               ext2_error(inode->i_sb, "trunc_dindirect",
-                       "Read failure, inode=%ld, block=%d",
-                       inode->i_ino, tmp);
-               *p = 0;
-               if (tind_bh)
-                       mark_buffer_dirty(tind_bh, 1);
-               else
-                       mark_inode_dirty(inode);
-               return 0;
-       }
-
-       addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
-       dindirect_block = DINDIRECT_BLOCK(inode, offset);
-       if (dindirect_block < 0)
-               dindirect_block = 0;
-       for (i = dindirect_block ; i < addr_per_block ; i++) {
-               u32 * dind = i + (u32 *) dind_bh->b_data;
-
-               retry |= trunc_indirect(inode,
-                                       offset + (i * addr_per_block),
-                                       dind, dind_bh);
-       }
-       /*
-        * Check the block and dispose of the dind_bh buffer.
-        */
-       retry |= check_block_empty(inode, dind_bh, p, tind_bh);
-
-       return retry;
-}
-
-static int trunc_tindirect (struct inode * inode)
-{
-       u32 * p = inode->u.ext2_i.i_data + EXT2_TIND_BLOCK;
-       struct buffer_head * tind_bh;
-       int i, tmp, retry = 0;
-       int tindirect_block, addr_per_block, offset;
-
-       tmp = le32_to_cpu(*p);
-       if (!tmp)
-               return 0;
-       tind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize);
-       if (tmp != le32_to_cpu(*p)) {
-               brelse (tind_bh);
-               return 1;
-       }
-       /* A read failure? Report error and clear slot (should be rare). */ 
-       if (!tind_bh) {
-               ext2_error(inode->i_sb, "trunc_tindirect",
-                       "Read failure, inode=%ld, block=%d",
-                       inode->i_ino, tmp);
-               *p = 0;
-               mark_inode_dirty(inode);
-               return 0;
-       }
-
-       addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
-       offset = EXT2_NDIR_BLOCKS + addr_per_block + 
-               (addr_per_block * addr_per_block);
-       tindirect_block = TINDIRECT_BLOCK(inode, offset);
-       if (tindirect_block < 0)
-               tindirect_block = 0;
-       for (i = tindirect_block ; i < addr_per_block ; i++) {
-               u32 * tind = i + (u32 *) tind_bh->b_data;
-
-               retry |= trunc_dindirect(inode,
-                               offset + (i * addr_per_block * addr_per_block),
-                               tind, tind_bh);
-       }
-       /*
-        * Check the block and dispose of the tind_bh buffer.
-        */
-       retry |= check_block_empty(inode, tind_bh, p, NULL);
-
-       return retry;
-}
-               
-void ext2_truncate (struct inode * inode)
-{
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-           S_ISLNK(inode->i_mode)))
-               return;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return;
-       ext2_discard_prealloc(inode);
-       while (1) {
-               int retry = trunc_direct(inode);
-               retry |= trunc_indirect (inode, 
-                               EXT2_IND_BLOCK,
-                               (u32 *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK],
-                               NULL);
-               retry |= trunc_dindirect (inode,
-                               EXT2_IND_BLOCK+EXT2_ADDR_PER_BLOCK(inode->i_sb),
-                               (u32 *)&inode->u.ext2_i.i_data[EXT2_DIND_BLOCK],
-                               NULL);
-               retry |= trunc_tindirect (inode);
-               if (!retry)
-                       break;
-               if (IS_SYNC(inode) && (inode->i_state & I_DIRTY))
-                       ext2_sync_inode (inode);
-               run_task_queue(&tq_disk);
-               current->policy |= SCHED_YIELD;
-               schedule();
-       }
-       inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-       mark_inode_dirty(inode);
-}
index e57b7b3..30c18c2 100644 (file)
 #include <linux/major.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
-#ifdef CONFIG_KMOD
 #include <linux/kmod.h>
-#endif
-#include <linux/lockd/bind.h>
-#include <linux/lockd/xdr.h>
 #include <linux/init.h>
+#include <linux/module.h>
+#include <linux/nfsd/interface.h>
 
 #ifdef CONFIG_CODA_FS
 extern int init_coda(void);
@@ -48,32+46,28 @@ void __init filesystem_setup(void)
 #endif
 }
 
-#ifndef CONFIG_NFSD
-#ifdef CONFIG_NFSD_MODULE
-long (*do_nfsservctl)(int, void *, void *);
-#endif
+#if defined(CONFIG_NFSD_MODULE)
+struct nfsd_linkage *nfsd_linkage = NULL;
+
 long
 asmlinkage sys_nfsservctl(int cmd, void *argp, void *resp)
 {
-#ifndef CONFIG_NFSD_MODULE
-       return -ENOSYS;
-#else
        int ret = -ENOSYS;
        
        lock_kernel();
-       if (do_nfsservctl) {
-               ret = do_nfsservctl(cmd, argp, resp);
-               goto out;
-       }
-#ifdef CONFIG_KMOD
-       if (request_module ("nfsd") == 0) {
-               if (do_nfsservctl)
-                       ret = do_nfsservctl(cmd, argp, resp);
-       }
-#endif /* CONFIG_KMOD */
-out:
+
+       if (nfsd_linkage ||
+           (request_module ("nfsd") == 0 && nfsd_linkage))
+               ret = nfsd_linkage->do_nfsservctl(cmd, argp, resp);
+
        unlock_kernel();
        return ret;
-#endif /* CONFIG_NFSD_MODULE */
+}
+EXPORT_SYMBOL(nfsd_linkage);
+
+#elif ! defined (CONFIG_NFSD)
+asmlinkage int sys_nfsservctl(int cmd, void *argp, void *resp)
+{
+       return -ENOSYS;
 }
 #endif /* CONFIG_NFSD */
index ae4cc80..1aeb4d7 100644 (file)
@@ -1040,17+1040,12 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
         */
        if (IS_MANDLOCK(inode) &&
            (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) {
-               struct vm_area_struct *vma;
                struct address_space *mapping = inode->i_mapping;
-               spin_lock(&mapping->i_shared_lock);
-               for(vma = mapping->i_mmap;vma;vma = vma->vm_next_share) {
-                       if (!(vma->vm_flags & VM_MAYSHARE))
-                               continue;
-                       spin_unlock(&mapping->i_shared_lock);
+
+               if (mapping->i_mmap_shared != NULL) {
                        error = -EAGAIN;
                        goto out_putf;
                }
-               spin_unlock(&mapping->i_shared_lock);
        }
 
        error = -EINVAL;
@@ -1199,17+1194,12 @@ int fcntl_setlk64(unsigned int fd, unsigned int cmd, struct flock64 *l)
         */
        if (IS_MANDLOCK(inode) &&
            (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) {
-               struct vm_area_struct *vma;
                struct address_space *mapping = inode->i_mapping;
-               spin_lock(&mapping->i_shared_lock);
-               for(vma = mapping->i_mmap;vma;vma = vma->vm_next_share) {
-                       if (!(vma->vm_flags & VM_MAYSHARE))
-                               continue;
-                       spin_unlock(&mapping->i_shared_lock);
+
+               if (mapping->i_mmap_shared != NULL) {
                        error = -EAGAIN;
                        goto out_putf;
                }
-               spin_unlock(&mapping->i_shared_lock);
        }
 
        error = -EINVAL;
index f1c9099..4df91ab 100644 (file)
@@ -290,7+290,8 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
                                return -EACCES;
                        }
                        /* get only low 8 bits... */
-                       get_user_ret(newstate, (unsigned char*)arg, -EFAULT);
+                       if (get_user(newstate, (unsigned char *) arg))
+                               return -EFAULT;
                        if (server->sign_active) {
                                /* cannot turn signatures OFF when active */
                                if (!newstate) return -EINVAL;
index 20e82fa..5509212 100644 (file)
@@ -312,7+312,9 @@ done:
 EXPORT_NO_SYMBOLS;
 MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
 
-extern long (*do_nfsservctl)(int, void *, void *);
+struct nfsd_linkage nfsd_linkage_s = {
+       do_nfsservctl: handle_sys_nfsservctl,
+};
 
 /*
  * Initialize the module
@@ -321,7+323,7 @@ int
 init_module(void)
 {
        printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
-       do_nfsservctl = handle_sys_nfsservctl;
+       nfsd_linkage = &nfsd_linkage_s;
        return 0;
 }
 
@@ -331,7+333,7 @@ init_module(void)
 void
 cleanup_module(void)
 {
-       do_nfsservctl = NULL;
+       nfsd_linkage = NULL;
        nfsd_export_shutdown();
        nfsd_cache_shutdown();
        remove_proc_entry("fs/nfs/exports", NULL);
index 11297fe..7fa97f6 100644 (file)
@@ -213,7+213,7 @@ nfsd(struct svc_rqst *rqstp)
                unsigned int    signo;
 
                for (signo = 1; signo <= _NSIG; signo++)
-                       if (sigismember(&current->signal, signo) &&
+                       if (sigismember(&current->pending.signal, signo) &&
                            !sigismember(&current->blocked, signo))
                                break;
                printk(KERN_WARNING "nfsd: terminating on signal %d\n", signo);
index 20fa7fa..bcd5281 100644 (file)
@@ -142,6+142,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
                } else
                        dentry = dget(dparent->d_parent);
        } else {
+               fh_lock(fhp);
                dentry = lookup_one(name, dparent);
                err = PTR_ERR(dentry);
                if (IS_ERR(dentry))
index 29b93e5..32ff587 100644 (file)
@@ -228,24+228,35 @@ unsigned int get_ptable_blocksize(kdev_t dev)
 }
 
 #ifdef CONFIG_PROC_FS
-int get_partition_list(char * page)
+int get_partition_list(char *page, char **start, off_t offset, int count)
 {
-       struct gendisk *p;
-       char buf[64];
-       int n, len;
+       struct gendisk *dsk;
+       int len;
 
        len = sprintf(page, "major minor  #blocks  name\n\n");
-       for (p = gendisk_head; p; p = p->next) {
-               for (n=0; n < (p->nr_real << p->minor_shift); n++) {
-                       if (p->part[n].nr_sects && len < PAGE_SIZE - 80) {
-                               len += sprintf(page+len,
+       for (dsk = gendisk_head; dsk; dsk = dsk->next) {
+               int n;
+
+               for (n = 0; n < (dsk->nr_real << dsk->minor_shift); n++)
+                       if (dsk->part[n].nr_sects) {
+                               char buf[64];
+
+                               len += sprintf(page + len,
                                               "%4d  %4d %10d %s\n",
-                                              p->major, n, p->sizes[n],
-                                              disk_name(p, n, buf));
+                                              dsk->major, n, dsk->sizes[n],
+                                              disk_name(dsk, n, buf));
+                               if (len < offset)
+                                       offset -= len, len = 0;
+                               else if (len >= offset + count)
+                                       goto leave_loops;
                        }
-               }
        }
-       return len;
+leave_loops:
+       *start = page + offset;
+       len -= offset;
+       if (len < 0)
+               len = 0;
+       return len > count ? count : len;
 }
 #endif
 
index 9b00883..f7f9038 100644 (file)
@@ -241,7+241,7 @@ static inline char * task_sig(struct task_struct *p, char *buffer)
        sigset_t ign, catch;
 
        buffer += sprintf(buffer, "SigPnd:\t");
-       buffer = render_sigset_t(&p->signal, buffer);
+       buffer = render_sigset_t(&p->pending.signal, buffer);
        *buffer++ = '\n';
        buffer += sprintf(buffer, "SigBlk:\t");
        buffer = render_sigset_t(&p->blocked, buffer);
@@ -382,7+382,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
                 * It must be decimal for Linux 2.0 compatibility.
                 * Use /proc/#/status for real-time signals.
                 */
-               task->signal .sig[0] & 0x7fffffffUL,
+               task->pending.signal.sig[0] & 0x7fffffffUL,
                task->blocked.sig[0] & 0x7fffffffUL,
                sigign      .sig[0] & 0x7fffffffUL,
                sigcatch    .sig[0] & 0x7fffffffUL,
index 600ff99..576d1be 100644 (file)
@@ -56,7+56,7 @@ extern int get_module_list(char *);
 extern int get_ksyms_list(char *, char **, off_t, int);
 #endif
 extern int get_device_list(char *);
-extern int get_partition_list(char *);
+extern int get_partition_list(char *, char **, off_t, int);
 extern int get_filesystem_list(char *);
 extern int get_filesystem_info(char *);
 extern int get_exec_domain_list(char *);
@@ -375,12+375,8 @@ static int devices_read_proc(char *page, char **start, off_t off,
 static int partitions_read_proc(char *page, char **start, off_t off,
                                 int count, int *eof, void *data)
 {
-       int len = get_partition_list(page);
-       if (len <= off+count) *eof = 1;
-       *start = page + off;
-       len -= off;
-       if (len>count) len = count;
-       if (len<0) len = 0;
+       int len = get_partition_list(page, start, off, count);
+       if (len < count) *eof = 1;
        return len;
 }
 
index 69bfdca..c93491f 100644 (file)
@@ -175,13+175,10 @@ extern inline unsigned long ffz_b(unsigned long x)
 
 extern inline unsigned long ffz(unsigned long word)
 {
-#if 0 && defined(__alpha_cix__)
-       /* Swine architects -- a year after they publish v3 of the
-          handbook, in the 21264 data sheet they quietly change CIX
-          to FIX and remove the spiffy counting instructions.  */
+#if defined(__alpha_cix__) && defined(__alpha_fix__)
        /* Whee.  EV6 can calculate it directly.  */
        unsigned long result;
-       __asm__("ctlz %1,%0" : "=r"(result) : "r"(~word));
+       __asm__("cttz %1,%0" : "=r"(result) : "r"(~word));
        return result;
 #else
        unsigned long bits, qofs, bofs;
@@ -214,10+211,7 @@ extern inline int ffs(int word)
  * of bits set) of a N-bit word
  */
 
-#if 0 && defined(__alpha_cix__)
-/* Swine architects -- a year after they publish v3 of the handbook, in
-   the 21264 data sheet they quietly change CIX to FIX and remove the
-   spiffy counting instructions.  */
+#if defined(__alpha_cix__) && defined(__alpha_fix__)
 /* Whee.  EV6 can calculate it directly.  */
 extern __inline__ unsigned long hweight64(unsigned long w)
 {
index c97283d..e2c9fa9 100644 (file)
@@ -83,247+83,24 @@ typedef struct {
        igcsr32 agpmode;                /* 0xB0 - AGP/GART mode control */
 } Irongate0;
 
-/* Bitfield and mask register definitions */
-
-/* Device, vendor IDs - offset 0x00 */
-
-typedef union {
-       igcsr32 i;                      /* integer value of CSR */
-       struct {
-               unsigned v : 16;
-               unsigned d : 16;
-       } r;                            /* structured interpretation */
-} ig_dev_vendor_t;
-
-
-/* Status, command registers - offset 0x04 */
-
-typedef union {
-       igcsr32 i;
-       struct {
-               unsigned command;
-               unsigned status;
-       } s;
-       struct {
-               /* command register fields */
-               unsigned iospc : 1;             /* always reads zero */
-               unsigned memspc  : 1;           /* PCI memory space accesses? */
-               unsigned iten : 1;              /* always 1: can be bus initiator */
-               unsigned scmon : 1;             /* always 0 special cycles not chckd */
-               unsigned mwic : 1;              /* always 0 - no mem write & invalid */
-               unsigned vgaps : 1;             /* always 0 - palette rds not special */
-               unsigned per : 1;               /* parity error resp: always 0 */
-               unsigned step : 1;              /* address/data stepping : always 0 */
-               unsigned serre : 1;             /* 1 = sys err output driver enable */
-               unsigned fbbce : 1;             /* fast back-back cycle : always 0 */
-               unsigned zero1 : 6;             /* must be zero */
-
-               /* status register fields */
-               unsigned zero2 : 4;          /* must be zero */
-               unsigned cl : 1;            /* config space capa list: always 1 */
-               unsigned pci66 : 1;         /* 66 MHz PCI support - always 0 */
-               unsigned udf : 1;           /* user defined features - always 0 */
-               unsigned fbbc : 1;          /* back-back transactions - always 0 */
-               unsigned ppe : 1;           /* PCI parity error detected (0) */
-               unsigned devsel : 2;        /* DEVSEL timing (always 01) */
-               unsigned sta : 1;           /* signalled target abort (0) */
-               unsigned rta : 1;           /* recvd target abort */
-               unsigned ria : 1;           /* recvd initiator abort */
-               unsigned serr : 1;          /* SERR has been asserted */
-               unsigned dpe : 1;           /* DRAM parity error (0) */
-       } r;
-} ig_stat_cmd_t;
-
-
-/* Revision ID, Programming interface, subclass, baseclass - offset 0x08 */
-
-typedef union {
-       igcsr32 i;
-       struct {
-               /* revision ID */
-               unsigned step : 4;              /* stepping Revision ID */
-               unsigned die : 4;               /* die Revision ID */
-               unsigned pif : 8;               /* programming interface (0x00) */
-               unsigned sub : 8;               /* subclass code (0x00) */
-               unsigned base: 8;               /* baseclass code (0x06) */
-       } r;
-} ig_class_t;
-
-
-/* Latency Timer, PCI Header type - offset 0x0C */
-
-typedef union {
-       igcsr32 i;
-       struct {
-               unsigned zero1:8;               /* reserved */
-               unsigned lat : 8;               /* latency in PCI bus clocks */
-               unsigned hdr : 8;               /* PCI header type */
-               unsigned zero2:8;               /* reserved */
-       } r;
-} ig_latency_t;
-
-
-/* Base Address Register 0 - offset 0x10 */
-
-typedef union {
-       igcsr32 i;
-       struct {
-               unsigned mem : 1;               /* Reg pts to memory (always 0) */
-               unsigned type: 2;               /* 32 bit register = 0b00 */
-               unsigned pref: 1;               /* graphics mem prefetchable=1 */
-               unsigned baddrl : 21;           /* 32M = minimum alloc -> all zero */
-               unsigned size : 6;              /* size requirements for AGP */
-               unsigned zero : 1;              /* reserved=0 */
-       } r;
-} ig_bar0_t;
-
-
-/* Base Address Register 1 - offset 0x14 */
-
-typedef union {
-       igcsr32 i;
-       struct {
-               unsigned mem : 1;               /* BAR0 maps to memory -> 0 */
-               unsigned type : 2;              /* BAR1 is 32-bit -> 0b00 */
-               unsigned pref : 1;              /* graphics mem prefetchable=1 */
-               unsigned baddrl : 8;            /* 4K alloc for AGP CSRs -> 0b00 */
-               unsigned baddrh : 20;           /* base addr of AGP CSRs A[30:11] */
-       } r;
-} ig_bar1_t;
-
-
-/* Base Address Register 2 - offset 0x18 */
-
-typedef union {
-       igcsr32 i;
-       struct {
-               unsigned io  : 1;               /* BAR2 maps to I/O space -> 1 */
-               unsigned zero1: 1;              /* reserved */
-               unsigned addr : 22;             /* BAR2[31:10] - PM2_BLK base */
-               unsigned zero2: 8;              /* reserved */
-       } r;
-} ig_bar2_t;
-
-
-/* Capabilities Pointer - offset 0x34 */
-
-typedef union {
-       igcsr32 i;
-       struct {
-               unsigned cap : 8;               /* =0xA0, offset of AGP ctrl regs */
-               unsigned zero: 24;              /* reserved */
-       } r;
-} ig_capptr_t;
-
-
-/* Base Address Chip Select Register 1,0 - offset 0x40 */
-/* Base Address Chip Select Register 3,2 - offset 0x44 */
-/* Base Address Chip Select Register 5,4 - offset 0x48 */
-
-typedef union {
-
-       igcsr32 i;
-       struct {
-               /* lower bank */
-               unsigned en0 : 1;               /* memory bank enabled */
-               unsigned mask0 : 6;             /* Address mask for A[28:23] */
-               unsigned base0 : 9;             /* Bank Base Address A[31:23] */
-
-               /* upper bank */
-               unsigned en1 : 1;               /* memory bank enabled */
-               unsigned mask1 : 6;             /* Address mask for A[28:23] */
-               unsigned base1 : 9;             /* Bank Base Address A[31:23] */
-       } r;
-} ig_bacsr_t, ig_bacsr10_t, ig_bacsr32_t, ig_bacsr54_t;
-
-
-/* SDRAM Address Mapping Control Register - offset 0x50 */
-
-typedef union {
-       igcsr32 i;
-       struct {
-               unsigned z1 : 1;                /* reserved */
-               unsigned bnks0: 1;              /* 0->2 banks in chip select 0 */
-               unsigned am0 : 1;               /* row/column addressing */
-               unsigned z2 : 1;                /* reserved */
-
-               unsigned z3 : 1;                /* reserved */
-               unsigned bnks1: 1;              /* 0->2 banks in chip select 1 */
-               unsigned am1 : 1;               /* row/column addressing */
-               unsigned z4 : 1;                /* reserved */
-
-               unsigned z5 : 1;                /* reserved */
-               unsigned bnks2: 1;              /* 0->2 banks in chip select 2 */
-               unsigned am2 : 1;               /* row/column addressing */
-               unsigned z6 : 1;                /* reserved */
-
-               unsigned z7 : 1;                /* reserved */
-               unsigned bnks3: 1;              /* 0->2 banks in chip select 3 */
-               unsigned am3 : 1;               /* row/column addressing */
-               unsigned z8 : 1;                /* reserved */
-
-               unsigned z9 : 1;                /* reserved */
-               unsigned bnks4: 1;              /* 0->2 banks in chip select 4 */
-               unsigned am4 : 1;               /* row/column addressing */
-               unsigned z10 : 1;               /* reserved */
-
-               unsigned z11 : 1;               /* reserved */
-               unsigned bnks5: 1;              /* 0->2 banks in chip select 5 */
-               unsigned am5 : 1;               /* row/column addressing */
-               unsigned z12 : 1;               /* reserved */
-
-               unsigned rsrvd: 8;              /* reserved */
-       } r;
-} ig_drammap_t;
-
-
-/* DRAM timing and driver strength register - offset 0x54 */
-
-typedef union {
-       igcsr32 i;
-       struct {
-               /* DRAM timing parameters */
-               unsigned trcd : 2;
-               unsigned tcl : 2;
-               unsigned tras: 3;
-               unsigned trp : 2;
-               unsigned trc : 3;
-               unsigned icl: 2;
-               unsigned ph : 2;
-
-               /* Chipselect driver strength */
-               unsigned adra : 1;
-               unsigned adrb : 1;
-               unsigned ctrl : 3;
-               unsigned dqm : 1;
-               unsigned cs : 1;
-               unsigned clk: 1;
-               unsigned rsrvd:8;
-       } r;
-} ig_dramtm_t;
-
-
-/* DRAM Mode / Status and ECC Register - offset 0x58 */
-
-typedef union {
-       igcsr32 i;
-       struct {
-               unsigned chipsel : 6;           /* failing ECC chip select */
-               unsigned zero1 : 2;             /* always reads zero */
-               unsigned status : 2;            /* ECC Detect logic status */
-               unsigned zero2 : 6;             /* always reads zero */
-
-               unsigned cycles : 2;            /* cycles per refresh, see table */
-               unsigned en : 1;                /* ECC enable */
-               unsigned r : 1;                 /* Large burst enable (=0) */
-               unsigned bre : 1;               /* Burst refresh enable */
-               unsigned zero3 : 2;             /* reserved = 0 */
-               unsigned mwe : 1;               /* Enable writes to DRAM mode reg */
-               unsigned type : 1;              /* SDRAM = 0, default */
-               unsigned sdraminit : 1;         /* SDRAM init - set params first! */
-               unsigned zero4 : 6;             /* reserved = 0 */
-       } r;
-} ig_dramms_t;
+
+typedef struct {
+
+       igcsr32 dev_vendor;             /* 0x00 - Device and Vendor IDs */
+       igcsr32 stat_cmd;               /* 0x04 - Status and Command regs */
+       igcsr32 class;                  /* 0x08 - subclass, baseclass etc */
+       igcsr32 htype;                  /* 0x0C - header type (at 0x0E) */
+       igcsr32 rsrvd0[2];              /* 0x10-0x17 reserved */
+       igcsr32 busnos;                 /* 0x18 - Primary, secondary bus nos */
+       igcsr32 io_baselim_regs;        /* 0x1C - IO base, IO lim, AGP status */
+       igcsr32 mem_baselim;            /* 0x20 - memory base, memory lim */
+       igcsr32 pfmem_baselim;          /* 0x24 - prefetchable base, lim */
+       igcsr32 rsrvd1[2];              /* 0x28-0x2F reserved */
+       igcsr32 io_baselim;             /* 0x30 - IO base, IO limit */
+       igcsr32 rsrvd2[2];              /* 0x34-0x3B - reserved */
+       igcsr32 interrupt;              /* 0x3C - interrupt, PCI bridge ctrl */
+
+} Irongate1;
 
 
 /*
@@ -343,7+120,21 @@ typedef union {
 #define IRONGATE_IO            (IDENT_ADDR | IRONGATE_BIAS | 0x1FC000000UL)
 #define IRONGATE_CONF          (IDENT_ADDR | IRONGATE_BIAS | 0x1FE000000UL)
 
-#define IRONGATE0              ((Irongate0 *) IRONGATE_CONF)
+/*
+ * PCI Configuration space accesses are formed like so:
+ *
+ * 0x1FE << 24 |  : 2 2 2 2 1 1 1 1 : 1 1 1 1 1 1 0 0 : 0 0 0 0 0 0 0 0 :
+ *                : 3 2 1 0 9 8 7 6 : 5 4 3 2 1 0 9 8 : 7 6 5 4 3 2 1 0 :
+ *                  ---bus numer---   -device-- -fun-   ---register----
+ */
+
+#define IGCSR(dev,fun,reg)     ( IRONGATE_CONF | \
+                               ((dev)<<11) | \
+                               ((fun)<<8) | \
+                               (reg) )
+
+#define IRONGATE0              ((Irongate0 *) IGCSR(0, 0, 0))
+#define IRONGATE1              ((Irongate1 *) IGCSR(1, 0, 0))
 
 /*
  * Data structure for handling IRONGATE machine checks:
index 98c4469..eeb5b85 100644 (file)
@@ -79,24+79,6 @@ extern inline int verify_area(int type, const void * addr, unsigned long size)
   __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
   
 /*
- * The "xxx_ret" versions return constant specified in third argument, if
- * something bad happens. These macros can be optimized for the
- * case of just returning from the function xxx_ret is used.
- */
-
-#define put_user_ret(x,ptr,ret) ({ \
-if (put_user(x,ptr)) return ret; })
-
-#define get_user_ret(x,ptr,ret) ({ \
-if (get_user(x,ptr)) return ret; })
-
-#define __put_user_ret(x,ptr,ret) ({ \
-if (__put_user(x,ptr)) return ret; })
-
-#define __get_user_ret(x,ptr,ret) ({ \
-if (__get_user(x,ptr)) return ret; })
-
-/*
  * The "lda %1, 2b-1b(%0)" bits are magic to get the assembler to
  * encode the bits we need for resolving the exception.  See the
  * more extensive comments with fixup_inline_exception below for
@@ -417,16+399,6 @@ copy_from_user(void *to, const void *from, long n)
        return __copy_tofrom_user(to, from, n, from);
 }
 
-#define copy_to_user_ret(to,from,n,retval) ({ \
-if (copy_to_user(to,from,n)) \
-       return retval; \
-})
-
-#define copy_from_user_ret(to,from,n,retval) ({ \
-if (copy_from_user(to,from,n)) \
-       return retval; \
-})
-
 extern void __do_clear_user(void);
 
 extern inline long
index add086e..7e8040d 100644 (file)
@@ -59,9+59,6 @@ extern __inline__ int verify_area(int type, const void * addr, unsigned long siz
  * address space - it must have been done previously with a separate
  * "access_ok()" call.
  *
- * The "xxx_ret" versions return constant specified in the third
- * argument if something bad happens.
- *
  * The "xxx_error" versions set the third argument to EFAULT if an
  * error occurs, and leave it unchanged on success.  Note that these
  * versions are void (ie, don't return a value as such).
@@ -69,14+66,10 @@ extern __inline__ int verify_area(int type, const void * addr, unsigned long siz
 #define get_user(x,p)          __get_user_check((x),(p),sizeof(*(p)))
 #define __get_user(x,p)                __get_user_nocheck((x),(p),sizeof(*(p)))
 #define __get_user_error(x,p,e)        __get_user_nocheck_error((x),(p),sizeof(*(p)),(e))
-#define get_user_ret(x,p,r)    ({ if (get_user(x,p)) return r; })
-#define __get_user_ret(x,p,r)  ({ if (__get_user(x,p)) return r; })
 
 #define put_user(x,p)          __put_user_check((__typeof(*(p)))(x),(p),sizeof(*(p)))
 #define __put_user(x,p)                __put_user_nocheck((__typeof(*(p)))(x),(p),sizeof(*(p)))
 #define __put_user_error(x,p,e)        __put_user_nocheck_error((x),(p),sizeof(*(p)),(e))
-#define put_user_ret(x,p,r)    ({ if (put_user(x,p)) return r; })
-#define __put_user_ret(x,p,r)  ({ if (__put_user(x,p)) return r; })
 
 static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n)
 {
@@ -91,9+84,6 @@ static __inline__ unsigned long __copy_from_user(void *to, const void *from, uns
        return n;
 }
 
-#define copy_from_user_ret(t,f,n,r)                                    \
-       ({ if (copy_from_user(t,f,n)) return r; })
-
 static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n)
 {
        if (access_ok(VERIFY_WRITE, to, n))
@@ -107,9+97,6 @@ static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsig
        return n;
 }
 
-#define copy_to_user_ret(t,f,n,r)                                      \
-       ({ if (copy_to_user(t,f,n)) return r; })
-
 static __inline__ unsigned long clear_user (void *to, unsigned long n)
 {
        if (access_ok(VERIFY_WRITE, to, n))
index 3f3bc50..67347da 100644 (file)
@@ -232,20+232,6 @@ do {                                                                       \
                : "=r"(err), ltype (x)                          \
                : "m"(__m(addr)), "i"(-EFAULT), "0"(err))
 
-/*
- * The "xxx_ret" versions return constant specified in third argument, if
- * something bad happens. These macros can be optimized for the
- * case of just returning from the function xxx_ret is used.
- */
-
-#define put_user_ret(x,ptr,ret) ({ if (put_user(x,ptr)) return ret; })
-
-#define get_user_ret(x,ptr,ret) ({ if (get_user(x,ptr)) return ret; })
-
-#define __put_user_ret(x,ptr,ret) ({ if (__put_user(x,ptr)) return ret; })
-
-#define __get_user_ret(x,ptr,ret) ({ if (__get_user(x,ptr)) return ret; })
-
 
 /*
  * Copy To/From Userspace
@@ -583,10+569,6 @@ __constant_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
         __constant_copy_from_user((to),(from),(n)) :   \
         __generic_copy_from_user((to),(from),(n)))
 
-#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
-
-#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
-
 #define __copy_to_user(to,from,n)                      \
        (__builtin_constant_p(n) ?                      \
         __constant_copy_to_user_nocheck((to),(from),(n)) :     \
index e530e7f..319784a 100644 (file)
@@ -86,16+86,6 @@ verify_area (int type, const void *addr, unsigned long size)
 #define __put_user(x,ptr)      __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
 #define __get_user(x,ptr)      __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
   
-/*
- * The "xxx_ret" versions return constant specified in third argument, if
- * something bad happens. These macros can be optimized for the
- * case of just returning from the function xxx_ret is used.
- */
-#define put_user_ret(x,ptr,ret)                ({ if (put_user(x,ptr)) return ret; })
-#define get_user_ret(x,ptr,ret)                ({ if (get_user(x,ptr)) return ret; })
-#define __put_user_ret(x,ptr,ret)      ({ if (__put_user(x,ptr)) return ret; })
-#define __get_user_ret(x,ptr,ret)      ({ if (__get_user(x,ptr)) return ret; })
-
 extern void __get_user_unknown (void);
 
 #define __get_user_nocheck(x,ptr,size)                         \
@@ -280,18+270,6 @@ extern unsigned long __copy_user (void *to, const void *from, unsigned long coun
        __cu_len;                                                                               \
 })
 
-#define copy_to_user_ret(to,from,n,retval)     \
-({                                             \
-       if (copy_to_user(to,from,n))            \
-               return retval;                  \
-})
-
-#define copy_from_user_ret(to,from,n,retval)   \
-({                                             \
-       if (copy_from_user(to,from,n))          \
-               return retval;                  \
-})
-
 extern unsigned long __do_clear_user (void *, unsigned long);
 
 #define __clear_user(to,n)                     \
index 82897ad..1fe589f 100644 (file)
@@ -759,10+759,6 @@ __constant_copy_to_user(void *to, const void *from, unsigned long n)
 #define __copy_from_user(to, from, n) copy_from_user(to, from, n)
 #define __copy_to_user(to, from, n) copy_to_user(to, from, n)
 
-#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
-
-#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
-
 /*
  * Copy a null terminated string from userspace.
  */
index 2d3cc95..c940065 100644 (file)
@@ -84,24+84,6 @@ extern inline int verify_area(int type, const void * addr, unsigned long size)
 #define __get_user(x,ptr) \
        __get_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
 
-/*
- * The "xxx_ret" versions return constant specified in third argument, if
- * something bad happens. These macros can be optimized for the
- * case of just returning from the function xxx_ret is used.
- */
-
-#define put_user_ret(x,ptr,ret) ({ \
-if (put_user(x,ptr)) return ret; })
-
-#define get_user_ret(x,ptr,ret) ({ \
-if (get_user(x,ptr)) return ret; })
-
-#define __put_user_ret(x,ptr,ret) ({ \
-if (__put_user(x,ptr)) return ret; })
-
-#define __get_user_ret(x,ptr,ret) ({ \
-if (__get_user(x,ptr)) return ret; })
-
 struct __large_struct { unsigned long buf[100]; };
 #define __m(x) (*(struct __large_struct *)(x))
 
@@ -281,16+263,6 @@ extern void __put_user_unknown(void);
        "jal\t" #destination "\n\t"
 #endif
 
-#define copy_to_user_ret(to,from,n,retval) ({ \
-if (copy_to_user(to,from,n)) \
-        return retval; \
-})
-
-#define copy_from_user_ret(to,from,n,retval) ({ \
-if (copy_from_user(to,from,n)) \
-        return retval; \
-})
-
 extern size_t __copy_user(void *__to, const void *__from, size_t __n);
 
 #define __copy_to_user(to,from,n) ({ \
index 2a9f2ee..1727b8d 100644 (file)
@@ -84,18+84,6 @@ extern inline int verify_area(int type, const void * addr, unsigned long size)
 #define __get_user(x,ptr) \
        __get_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
 
-/*
- * The "xxx_ret" versions return constant specified in third argument, if
- * something bad happens. These macros can be optimized for the
- * case of just returning from the function xxx_ret is used.
- */
-
-#define put_user_ret(x,ptr,ret) ({ if (put_user(x,ptr)) return ret; })
-#define get_user_ret(x,ptr,ret) ({ if (get_user(x,ptr)) return ret; })
-
-#define __put_user_ret(x,ptr,ret) ({ if (__put_user(x,ptr)) return ret; })
-#define __get_user_ret(x,ptr,ret) ({ if (__get_user(x,ptr)) return ret; })
-
 struct __large_struct { unsigned long buf[100]; };
 #define __m(x) (*(struct __large_struct *)(x))
 
@@ -213,16+201,6 @@ extern void __put_user_unknown(void);
        "jal\t" #destination "\n\t"
 #endif
 
-#define copy_to_user_ret(to,from,n,retval) ({ \
-if (copy_to_user(to,from,n)) \
-        return retval; \
-})
-
-#define copy_from_user_ret(to,from,n,retval) ({ \
-if (copy_from_user(to,from,n)) \
-        return retval; \
-})
-
 extern size_t __copy_user(void *__to, const void *__from, size_t __n);
 
 #define __copy_to_user(to,from,n) ({ \
index 3eafdbd..fcb2270 100644 (file)
@@ -87,25+87,6 @@ extern unsigned long search_exception_table(unsigned long);
 #define __put_user(x,ptr) \
   __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
 
-/*
- * The "xxx_ret" versions return constant specified in third argument, if
- * something bad happens. These macros can be optimized for the
- * case of just returning from the function xxx_ret is used.
- */
-
-#define put_user_ret(x,ptr,ret) ({ \
-if (put_user(x,ptr)) return ret; })
-
-#define get_user_ret(x,ptr,ret) ({ \
-if (get_user(x,ptr)) return ret; })
-
-#define __put_user_ret(x,ptr,ret) ({ \
-if (__put_user(x,ptr)) return ret; })
-
-#define __get_user_ret(x,ptr,ret) ({ \
-if (__get_user(x,ptr)) return ret; })
-
-
 extern long __put_user_bad(void);
 
 #define __put_user_nocheck(x,ptr,size)                 \
@@ -236,10+217,6 @@ copy_to_user(void *to, const void *from, unsigned long n)
        return n;
 }
 
-#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
-
-#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
-
 #define __copy_from_user(to, from, size) \
        __copy_tofrom_user((to), (from), (size))
 #define __copy_to_user(to, from, size) \
index 9f448fc..a19cfa2 100644 (file)
@@ -407,10+407,6 @@ __copy_from_user_asm(void* to, const void* from,  long n)
         err;                                                    \
 })
 
-#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
-
-#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
-
 /*
  * Copy a null terminated string from userspace.
  */
index 2237d34..5434ccb 100644 (file)
@@ -83,24+83,6 @@ extern inline int verify_area(int type, const void * addr, unsigned long size)
 #define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
 #define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
 
-/*
- * The "xxx_ret" versions return constant specified in third argument, if
- * something bad happens. These macros can be optimized for the
- * case of just returning from the function xxx_ret is used.
- */
-
-#define put_user_ret(x,ptr,ret) ({ \
-if (put_user(x,ptr)) return ret; })
-
-#define get_user_ret(x,ptr,ret) ({ \
-if (get_user(x,ptr)) return ret; })
-
-#define __put_user_ret(x,ptr,ret) ({ \
-if (__put_user(x,ptr)) return ret; })
-
-#define __get_user_ret(x,ptr,ret) ({ \
-if (__get_user(x,ptr)) return ret; })
-
 struct __large_struct { unsigned long buf[100]; };
 #define __m(x) (*(struct __large_struct *)(x))
 
@@ -256,20+238,10 @@ __copy_res = __copy_user(__copy_to, (void *) (from), __copy_size); \
 } else __copy_res = __copy_size; \
 __copy_res; })
 
-#define copy_to_user_ret(to,from,n,retval) ({ \
-if (copy_to_user(to,from,n)) \
-       return retval; \
-})
-
 #define __copy_to_user(to,from,n)              \
        __copy_user((void *)(to),               \
                    (void *)(from), n)
 
-#define __copy_to_user_ret(to,from,n,retval) ({ \
-if (__copy_to_user(to,from,n)) \
-       return retval; \
-})
-
 #define copy_from_user(to,from,n) ({ \
 void *__copy_to = (void *) (to); \
 void *__copy_from = (void *) (from); \
@@ -280,20+252,10 @@ __copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \
 } else __copy_res = __copy_size; \
 __copy_res; })
 
-#define copy_from_user_ret(to,from,n,retval) ({ \
-if (copy_from_user(to,from,n)) \
-       return retval; \
-})
-
 #define __copy_from_user(to,from,n)            \
        __copy_user((void *)(to),               \
                    (void *)(from), n)
 
-#define __copy_from_user_ret(to,from,n,retval) ({ \
-if (__copy_from_user(to,from,n)) \
-       return retval; \
-})
-
 /* XXX: Not sure it works well..
    should be such that: 4byte clear and the rest. */
 extern __inline__ __kernel_size_t
index cfee071..00205d6 100644 (file)
@@ -1,7+1,7 @@
 /* hardirq.h: 32-bit Sparc hard IRQ support.
  *
  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1998-99 Anton Blanchard (anton@progsoc.uts.edu.au)
+ * Copyright (C) 1998-2000 Anton Blanchard (anton@linuxcare.com)
  */
 
 #ifndef __SPARC_HARDIRQ_H
 
 #include <linux/config.h>
 #include <linux/threads.h>
+#include <linux/brlock.h>
+#include <linux/spinlock.h>
 
 /* entry.S is sensitive to the offsets of these fields */
 typedef struct {
        unsigned int __softirq_active;
        unsigned int __softirq_mask;
+#ifndef CONFIG_SMP
        unsigned int __local_irq_count;
+#else
+       unsigned int __unused_on_SMP;   /* DaveM says use brlock for SMP irq. KAO */
+#endif
        unsigned int __local_bh_count;
        unsigned int __syscall_count;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+/* Note that local_irq_count() is replaced by sparc64 specific version for SMP */
+
+#ifndef CONFIG_SMP
+#define irq_enter(cpu, irq)    ((void)(irq), local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)     ((void)(irq), local_irq_count(cpu)--)
+#else
+#undef local_irq_count
+#define local_irq_count(cpu)   (__brlock_array[cpu][BR_GLOBALIRQ_LOCK])
+#define irq_enter(cpu, irq)    br_read_lock(BR_GLOBALIRQ_LOCK)
+#define irq_exit(cpu, irq)     br_read_unlock(BR_GLOBALIRQ_LOCK)
+#endif
 
 /*
  * Are we in an interrupt context? Either doing bottom half
  * or hardware interrupt processing?
  */
-#define in_interrupt() ({ int __cpu = smp_processor_id(); \
-       (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
+#define in_interrupt() ((local_irq_count(smp_processor_id()) + \
+                        local_bh_count(smp_processor_id())) != 0)
 
-#define in_irq() ({ int __cpu = smp_processor_id(); \
-       (local_irq_count(__cpu) != 0); })
+/* This tests only the local processors hw IRQ context disposition.  */
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
 
 #ifndef CONFIG_SMP
 
-#define hardirq_trylock(cpu)   (local_irq_count(cpu) == 0)
-#define hardirq_endlock(cpu)   do { (void)(cpu); } while (0)
-
-#define hardirq_enter(cpu)     (++local_irq_count(cpu))
-#define hardirq_exit(cpu)      (--local_irq_count(cpu))
+#define hardirq_trylock(cpu)   ((void)(cpu), local_irq_count(smp_processor_id()) == 0)
+#define hardirq_endlock(cpu)   do { (void)(cpu); } while(0)
 
 #define synchronize_irq()      barrier()
 
-#else
+#else /* (CONFIG_SMP) */
 
-#include <asm/atomic.h>
-#include <linux/spinlock.h>
-#include <asm/system.h>
-#include <asm/smp.h>
+static __inline__ int irqs_running(void)
+{
+       int i;
+
+       for (i = 0; i < smp_num_cpus; i++)
+               if (local_irq_count(cpu_logical_map(i)))
+                       return 1;
+       return 0;
+}
 
 extern unsigned char global_irq_holder;
-extern spinlock_t global_irq_lock;
-extern atomic_t global_irq_count;
 
 static inline void release_irqlock(int cpu)
 {
-       /* if we didn't own the irq lock, just ignore.. */
-       if (global_irq_holder == (unsigned char) cpu) {
+       /* if we didn't own the irq lock, just ignore... */
+       if(global_irq_holder == (unsigned char) cpu) {
                global_irq_holder = NO_PROC_ID;
-               spin_unlock(&global_irq_lock);
+               br_write_unlock(BR_GLOBALIRQ_LOCK);
        }
 }
 
-static inline void hardirq_enter(int cpu)
-{
-       ++local_irq_count(cpu);
-       atomic_inc(&global_irq_count);
-}
-
-static inline void hardirq_exit(int cpu)
-{
-       atomic_dec(&global_irq_count);
-       --local_irq_count(cpu);
-}
-
 static inline int hardirq_trylock(int cpu)
 {
-       return (! atomic_read(&global_irq_count) &&
-               ! spin_is_locked (&global_irq_lock));
+       spinlock_t *lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock;
+
+       return (!local_irq_count(cpu) && !spin_is_locked(lock));
 }
 
-#define hardirq_endlock(cpu)   do { } while (0)
+#define hardirq_endlock(cpu)   do { (void)(cpu); } while (0)
 
 extern void synchronize_irq(void);
 
index a58a808..6008023 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: irq.h,v 1.31 2000/08/05 10:48:41 davem Exp $
+/* $Id: irq.h,v 1.32 2000/08/26 02:42:28 anton Exp $
  * irq.h: IRQ registers on the Sparc.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -21,18+21,6 @@ BTFIXUPDEF_CALL(char *, __irq_itoa, unsigned int)
 
 #define NR_IRQS    15
 
-/* IRQ handler dispatch entry and exit. */
-#ifdef CONFIG_SMP
-#define irq_enter(cpu, irq)                     \
-do {    hardirq_enter(cpu);                     \
-        spin_unlock_wait(&global_irq_lock);     \
-       } while(0)
-#define irq_exit(cpu, irq)      hardirq_exit(cpu)
-#else
-#define irq_enter(cpu, irq)     (++local_irq_count(cpu))
-#define irq_exit(cpu, irq)      (--local_irq_count(cpu))
-#endif
-
 /* Dave Redman (djhr@tadpole.co.uk)
  * changed these to function pointers.. it saves cycles and will allow
  * the irq dependencies to be split into different files at a later date
index 396f9ef..4e2e601 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: oplib.h,v 1.20 1998/09/17 11:05:25 jj Exp $
+/* $Id: oplib.h,v 1.21 2000/08/26 02:38:04 anton Exp $
  * oplib.h:  Describes the interface and available routines in the
  *           Linux Prom library.
  *
@@ -9,6+9,7 @@
 #define __SPARC_OPLIB_H
 
 #include <asm/openprom.h>
+#include <linux/spinlock.h>
 
 /* The master romvec pointer... */
 extern struct linux_romvec *romvec;
@@ -311,6+312,7 @@ extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nr
 /* Apply ranges of any prom node (and optionally parent node as well) to registers. */
 extern void prom_apply_generic_ranges(int node, int parent, 
                                      struct linux_prom_registers *sbusregs, int nregs);
-                                  
+
+extern spinlock_t prom_lock;
 
 #endif /* !(__SPARC_OPLIB_H) */
index c026a21..1587f92 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: uaccess.h,v 1.21 2000/01/08 16:38:23 anton Exp $
+/* $Id: uaccess.h,v 1.22 2000/08/29 07:01:58 davem Exp $
  * uaccess.h: User space memore access functions.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -94,27+94,17 @@ extern void __ret_efault(void);
 unsigned long __pu_addr = (unsigned long)(ptr); \
 __put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
 
-#define put_user_ret(x,ptr,retval) ({ \
-unsigned long __pu_addr = (unsigned long)(ptr); \
-__put_user_check_ret((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr)),retval); })
-
 #define get_user(x,ptr) ({ \
 unsigned long __gu_addr = (unsigned long)(ptr); \
 __get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
 
-#define get_user_ret(x,ptr,retval) ({ \
-unsigned long __gu_addr = (unsigned long)(ptr); \
-__get_user_check_ret((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr)),retval); })
-
 /*
  * The "__xxx" versions do not do address space checking, useful when
  * doing multiple accesses to the same area (the user has to do the
  * checks by hand with "access_ok()")
  */
 #define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
-#define __put_user_ret(x,ptr,retval) __put_user_nocheck_ret((x),(ptr),sizeof(*(ptr)),retval)
 #define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr)))
-#define __get_user_ret(x,ptr,retval) __get_user_nocheck_ret((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr)),retval)
 
 struct __large_struct { unsigned long buf[100]; };
 #define __m(x) ((struct __large_struct *)(x))
@@ -303,20+293,10 @@ __copy_res = __copy_user(__copy_to, (void *) (from), __copy_size); \
 } else __copy_res = __copy_size; \
 __copy_res; })
 
-#define copy_to_user_ret(to,from,n,retval) ({ \
-if (copy_to_user(to,from,n)) \
-       return retval; \
-})
-
 #define __copy_to_user(to,from,n)              \
        __copy_user((void *)(to),               \
                    (void *)(from), n)
 
-#define __copy_to_user_ret(to,from,n,retval) ({ \
-if (__copy_to_user(to,from,n)) \
-       return retval; \
-})
-
 #define copy_from_user(to,from,n) ({ \
 void *__copy_to = (void *) (to); \
 void *__copy_from = (void *) (from); \
@@ -327,20+307,10 @@ __copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \
 } else __copy_res = __copy_size; \
 __copy_res; })
 
-#define copy_from_user_ret(to,from,n,retval) ({ \
-if (copy_from_user(to,from,n)) \
-       return retval; \
-})
-
 #define __copy_from_user(to,from,n)            \
        __copy_user((void *)(to),               \
                    (void *)(from), n)
 
-#define __copy_from_user_ret(to,from,n,retval) ({ \
-if (__copy_from_user(to,from,n)) \
-       return retval; \
-})
-
 extern __inline__ __kernel_size_t __clear_user(void *addr, __kernel_size_t size)
 {
   __kernel_size_t ret;
@@ -368,11+338,6 @@ __clear_res = __clear_user(__clear_addr, __clear_size); \
 } else __clear_res = __clear_size; \
 __clear_res; })
 
-#define clear_user_ret(addr,size,retval) ({ \
-if (clear_user(addr,size)) \
-       return retval; \
-})
-
 extern int __strncpy_from_user(unsigned long dest, unsigned long src, int count);
 
 #define strncpy_from_user(dest,src,count) ({ \
index 72c2c69..bf60670 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: uaccess.h,v 1.32 1999/11/23 08:56:48 davem Exp $ */
+/* $Id: uaccess.h,v 1.33 2000/08/29 07:01:58 davem Exp $ */
 #ifndef _ASM_UACCESS_H
 #define _ASM_UACCESS_H
 
@@ -102,22+102,12 @@ extern void __ret_efault(void);
 unsigned long __pu_addr = (unsigned long)(ptr); \
 __put_user_nocheck((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
 
-#define put_user_ret(x,ptr,retval) ({ \
-unsigned long __pu_addr = (unsigned long)(ptr); \
-__put_user_nocheck_ret((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr)),retval); })
-
 #define get_user(x,ptr) ({ \
 unsigned long __gu_addr = (unsigned long)(ptr); \
 __get_user_nocheck((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
 
-#define get_user_ret(x,ptr,retval) ({ \
-unsigned long __gu_addr = (unsigned long)(ptr); \
-__get_user_nocheck_ret((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr)),retval); })
-
 #define __put_user(x,ptr) put_user(x,ptr)
-#define __put_user_ret(x,ptr,retval) put_user_ret(x,ptr,retval)
 #define __get_user(x,ptr) get_user(x,ptr)
-#define __get_user_ret(x,ptr,retval) get_user_ret(x,ptr,retval)
 
 struct __large_struct { unsigned long buf[100]; };
 #define __m(x) ((struct __large_struct *)(x))
@@ -288,44+278,14 @@ extern __kernel_size_t __copy_in_user(void *to, const void *from,
        __copy_from_user((void *)(to),  \
                    (void *)(from), (__kernel_size_t)(n))
 
-#define copy_from_user_ret(to,from,n,retval) ({ \
-if (copy_from_user(to,from,n)) \
-       return retval; \
-})
-
-#define __copy_from_user_ret(to,from,n,retval) ({ \
-if (__copy_from_user(to,from,n)) \
-       return retval; \
-})
-
 #define copy_to_user(to,from,n) \
        __copy_to_user((void *)(to), \
        (void *) (from), (__kernel_size_t)(n))
 
-#define copy_to_user_ret(to,from,n,retval) ({ \
-if (copy_to_user(to,from,n)) \
-       return retval; \
-})
-
-#define __copy_to_user_ret(to,from,n,retval) ({ \
-if (__copy_to_user(to,from,n)) \
-       return retval; \
-})
-
 #define copy_in_user(to,from,n) \
        __copy_in_user((void *)(to), \
        (void *) (from), (__kernel_size_t)(n))
 
-#define copy_in_user_ret(to,from,n,retval) ({ \
-if (copy_in_user(to,from,n)) \
-       return retval; \
-})
-
-#define __copy_in_user_ret(to,from,n,retval) ({ \
-if (__copy_in_user(to,from,n)) \
-       return retval; \
-})
-
 extern __inline__ __kernel_size_t __clear_user(void *addr, __kernel_size_t size)
 {
        extern __kernel_size_t __bzero_noasi(void *addr, __kernel_size_t size);
@@ -336,11+296,6 @@ extern __inline__ __kernel_size_t __clear_user(void *addr, __kernel_size_t size)
 #define clear_user(addr,n) \
        __clear_user((void *)(addr), (__kernel_size_t)(n))
 
-#define clear_user_ret(addr,size,retval) ({ \
-if (clear_user(addr,size)) \
-       return retval; \
-})
-
 extern int __strncpy_from_user(unsigned long dest, unsigned long src, int count);
 
 #define strncpy_from_user(dest,src,count) \
index 3ce2c58..6f52059 100644 (file)
@@ -361,7+361,8 @@ struct address_space {
        unsigned long           nrpages;        /* number of pages */
        struct address_space_operations *a_ops; /* methods */
        void                    *host;          /* owner: inode, block_device */
-       struct vm_area_struct   *i_mmap;        /* list of mappings */
+       struct vm_area_struct   *i_mmap;        /* list of private mappings */
+       struct vm_area_struct   *i_mmap_shared; /* list of shared mappings */
        spinlock_t              i_shared_lock;  /* and spinlock protecting it */
 };
 
index f606186..bac6318 100644 (file)
@@ -52,7+52,8 @@ struct vm_area_struct {
        struct vm_area_struct * vm_avl_left;
        struct vm_area_struct * vm_avl_right;
 
-       /* For areas with inode, the list inode->i_mapping->i_mmap, 
+       /* For areas with an address space and backing store,
+        * one of the address_space->i_mmap{,shared} lists,
         * for shm areas, the list of attaches, otherwise unused.
         */
        struct vm_area_struct *vm_next_share;
diff --git a/include/linux/nfsd/interface.h b/include/linux/nfsd/interface.h
new file mode 100644 (file)
index 0000000..afa9edc
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * include/linux/nfsd/interface.h
+ *
+ * defines interface between nfsd and other bits of
+ * the kernel.  Particularly filesystems (eventually).
+ *
+ * Copyright (C) 2000 Neil Brown <neilb@cse.unsw.edu.au>
+ */
+
+#ifndef LINUX_NFSD_INTERFACE_H
+#define LINUX_NFSD_INTERFACE_H
+
+#ifdef CONFIG_NFSD_MODULE
+
+extern struct nfsd_linkage {
+       long (*do_nfsservctl)(int cmd, void *argp, void *resp);
+} * nfsd_linkage;
+
+#endif
+
+#endif /* LINUX_NFSD_INTERFACE_H */
index dacab21..f183f57 100644 (file)
 #include <linux/nfsd/export.h>
 #include <linux/nfsd/auth.h>
 #include <linux/nfsd/stats.h>
-
+#include <linux/nfsd/interface.h>
 /*
  * nfsd version
  */
index 7f68d19..09a5895 100644 (file)
 #define PCI_DEVICE_ID_SI_300           0x0300
 #define PCI_DEVICE_ID_SI_530           0x0530
 #define PCI_DEVICE_ID_SI_540           0x0540
+#define PCI_DEVICE_ID_SI_540_VGA       0x5300
 #define PCI_DEVICE_ID_SI_601           0x0601
 #define PCI_DEVICE_ID_SI_620           0x0620
 #define PCI_DEVICE_ID_SI_630           0x0630
+#define PCI_DEVICE_ID_SI_630_VGA       0x6300
 #define PCI_DEVICE_ID_SI_5107          0x5107
 #define PCI_DEVICE_ID_SI_5300          0x5300
 #define PCI_DEVICE_ID_SI_5511          0x5511
index 50ed518..2d22dd6 100644 (file)
@@ -33,12+33,13 @@ extern unsigned long event;
 #define CLONE_VM       0x00000100      /* set if VM shared between processes */
 #define CLONE_FS       0x00000200      /* set if fs info shared between processes */
 #define CLONE_FILES    0x00000400      /* set if open files shared between processes */
-#define CLONE_SIGHAND  0x00000800      /* set if signal handlers shared */
+#define CLONE_SIGNAL   0x00000800      /* set if signal handlers and blocked signals shared */
 #define CLONE_PID      0x00001000      /* set if pid shared */
 #define CLONE_PTRACE   0x00002000      /* set if we want to let tracing continue on the child too */
 #define CLONE_VFORK    0x00004000      /* set if the parent wants the child to wake it up on mm_release */
 #define CLONE_PARENT   0x00008000      /* set if we want to have the same parent as the cloner */
-#define CLONE_THREAD   0x00010000      /* set if we want to clone the "thread group" */
+
+#define CLONE_SIGHAND  CLONE_SIGNAL    /* Old name */
 
 /*
  * These are the constant used to fake the fixed-point load-average
@@ -233,6+234,7 @@ struct mm_struct {
 struct signal_struct {
        atomic_t                count;
        struct k_sigaction      action[_NSIG];
+       struct sigpending       pending;
        spinlock_t              siglock;
 };
 
@@ -240,6+242,7 @@ struct signal_struct {
 #define INIT_SIGNALS { \
                ATOMIC_INIT(1), \
                { {{0,}}, }, \
+               { NULL, &init_signals.pending.head, }, \
                SPIN_LOCK_UNLOCKED }
 
 /*
@@ -366,8+369,10 @@ struct task_struct {
 /* signal handlers */
        spinlock_t sigmask_lock;        /* Protects signal and blocked */
        struct signal_struct *sig;
-       sigset_t signal, blocked;
-       struct signal_queue *sigqueue, **sigqueue_tail;
+
+       sigset_t blocked;
+       struct sigpending pending;
+
        unsigned long sas_ss_sp;
        size_t sas_ss_size;
        int (*notifier)(void *priv);
@@ -455,10+460,8 @@ struct task_struct {
     files:             &init_files,                                    \
     sigmask_lock:      SPIN_LOCK_UNLOCKED,                             \
     sig:               &init_signals,                                  \
-    signal:            {{0}},                                          \
+    pending:           { NULL, &tsk.pending.head, {{0}}},              \
     blocked:           {{0}},                                          \
-    sigqueue:          NULL,                                           \
-    sigqueue_tail:     &tsk.sigqueue,                                  \
     alloc_lock:                SPIN_LOCK_UNLOCKED                              \
 }
 
@@ -575,11+578,11 @@ static inline int signal_pending(struct task_struct *p)
        return (p->sigpending != 0);
 }
 
-/* Reevaluate whether the task has signals pending delivery.
-   This is required every time the blocked sigset_t changes.
-   All callers should have t->sigmask_lock.  */
-
-static inline void recalc_sigpending(struct task_struct *t)
+/*
+ * Re-calculate pending state from the set of locally pending
+ * signals, globally pending signals, and blocked signals.
+ */
+static inline int has_pending_signals(sigset_t *p1, sigset_t *p2, sigset_t *blocked)
 {
        unsigned long ready;
        long i;
@@ -587,23+590,31 @@ static inline void recalc_sigpending(struct task_struct *t)
        switch (_NSIG_WORDS) {
        default:
                for (i = _NSIG_WORDS, ready = 0; --i >= 0 ;)
-                       ready |= t->signal.sig[i] &~ t->blocked.sig[i];
+                       ready |= (p1->sig[i] | p2->sig[i]) &~ blocked->sig[i];
                break;
 
-       case 4: ready  = t->signal.sig[3] &~ t->blocked.sig[3];
-               ready |= t->signal.sig[2] &~ t->blocked.sig[2];
-               ready |= t->signal.sig[1] &~ t->blocked.sig[1];
-               ready |= t->signal.sig[0] &~ t->blocked.sig[0];
+       case 4: ready  = (p1->sig[3] | p2->sig[3]) &~ blocked->sig[3];
+               ready |= (p1->sig[2] | p2->sig[2]) &~ blocked->sig[2];
+               ready |= (p1->sig[1] | p2->sig[1]) &~ blocked->sig[1];
+               ready |= (p1->sig[0] | p2->sig[0]) &~ blocked->sig[0];
                break;
 
-       case 2: ready  = t->signal.sig[1] &~ t->blocked.sig[1];
-               ready |= t->signal.sig[0] &~ t->blocked.sig[0];
+       case 2: ready  = (p1->sig[1] | p2->sig[1]) &~ blocked->sig[1];
+               ready |= (p1->sig[0] | p2->sig[0]) &~ blocked->sig[0];
                break;
 
-       case 1: ready  = t->signal.sig[0] &~ t->blocked.sig[0];
+       case 1: ready  = (p1->sig[0] | p2->sig[0]) &~ blocked->sig[0];
        }
+       return ready != 0;
+}
+
+/* Reevaluate whether the task has signals pending delivery.
+   This is required every time the blocked sigset_t changes.
+   All callers should have t->sigmask_lock.  */
 
-       t->sigpending = (ready != 0);
+static inline void recalc_sigpending(struct task_struct *t)
+{
+       t->sigpending = has_pending_signals(&t->pending.signal, &t->sig->pending.signal, &t->blocked);
 }
 
 /* True if we are on the alternate signal stack.  */
index d6e82ae..b3c5eb4 100644 (file)
  * Real Time signals may be queued.
  */
 
-struct signal_queue
-{
-       struct signal_queue *next;
+struct sigqueue {
+       struct sigqueue *next;
        siginfo_t info;
 };
 
+struct sigpending {
+       struct sigqueue *head, **tail;
+       sigset_t signal;
+};
+
 /*
  * Define some primitives to manipulate sigset_t.
  */
@@ -207,6+211,13 @@ extern inline void siginitsetinv(sigset_t *set, unsigned long mask)
 
 #endif /* __HAVE_ARCH_SIG_SETOPS */
 
+static inline void init_sigpending(struct sigpending *sig)
+{
+       sigemptyset(&sig->signal);
+       sig->head = NULL;
+       sig->tail = &sig->head;
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_SIGNAL_H */
index c920e3d..c9bdab7 100644 (file)
@@ -1,7+1,7 @@
 /*
  * Definitions for bulk memory services
  *
- * bulkmem.h 1.11 1999/10/25 20:23:16
+ * bulkmem.h 1.12 2000/06/12 21:55:41
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
index 29e1354..bd4c295 100644 (file)
@@ -1,5+1,5 @@
 /*
- * bus_ops.h 1.8 1999/10/25 20:23:16
+ * bus_ops.h 1.10 2000/06/12 21:55:41
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
index e5c3280..d449b42 100644 (file)
@@ -1,5+1,5 @@
 /*
- * ciscode.h 1.40 2000/02/01 19:06:40
+ * ciscode.h 1.45 2000/08/12 02:08:23
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
 
 #define MANFID_NEW_MEDIA               0x0057
 
+#define MANFID_NOKIA                   0x0124
+#define PRODID_NOKIA_CARDPHONE         0x0900
+
 #define MANFID_OLICOM                  0x0121
 #define PRODID_OLICOM_OC2231           0x3122
 #define PRODID_OLICOM_OC2232           0x3222
 #define MANFID_PIONEER                 0x000b
 
 #define MANFID_PSION                   0x016c
+#define PRODID_PSION_NET100            0x0023
 
 #define MANFID_QUATECH                 0x0137
 #define PRODID_QUATECH_SPP100          0x0003
 
 #define MANFID_SOCKET                  0x0104
 #define PRODID_SOCKET_DUAL_RS232       0x0006
+#define PRODID_SOCKET_EIO              0x000a
 #define PRODID_SOCKET_LPE              0x000d
 
 #define MANFID_SUNDISK                 0x0045
 
 #define MANFID_TDK                     0x0105
 
+#define MANFID_TOSHIBA                 0x0098
+
 #define MANFID_XIRCOM                  0x0105
 
 #endif /* _LINUX_CISCODE_H */
index 8036605..884d46d 100644 (file)
@@ -1,5+1,5 @@
 /*
- * cisreg.h 1.16 2000/01/16 19:19:14
+ * cisreg.h 1.17 2000/06/12 21:55:41
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
index d53e446..5f9701f 100644 (file)
@@ -1,5+1,5 @@
 /*
- * cistpl.h 1.32 2000/01/11 19:06:50
+ * cistpl.h 1.34 2000/06/19 23:18:12
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
 #define CISTPL_BYTEORDER       0x43
 #define CISTPL_DATE            0x44
 #define CISTPL_BATTERY         0x45
+#define CISTPL_FORMAT_A                0x47
 /* Layer 3 tuples */
 #define CISTPL_ORG             0x46
 #define CISTPL_SPCL            0x90
@@ -530,6+531,21 @@ typedef struct cistpl_org_t {
 #define CISTPL_ORG_APPSPEC     0x01
 #define CISTPL_ORG_XIP         0x02
 
+typedef struct cistpl_format_t {
+    u_char     type;
+    u_char     edc;
+    u_int      offset;
+    u_int      length;
+} cistpl_format_t;
+
+#define CISTPL_FORMAT_DISK     0x00
+#define CISTPL_FORMAT_MEM      0x01
+
+#define CISTPL_EDC_NONE                0x00
+#define CISTPL_EDC_CKSUM       0x01
+#define CISTPL_EDC_CRC         0x02
+#define CISTPL_EDC_PCC         0x03
+
 typedef union cisparse_t {
     cistpl_device_t            device;
     cistpl_checksum_t          checksum;
@@ -548,6+564,7 @@ typedef union cisparse_t {
     cistpl_device_geo_t                device_geo;
     cistpl_vers_2_t            vers_2;
     cistpl_org_t               org;
+    cistpl_format_t            format;
 } cisparse_t;
 
 typedef struct tuple_t {
index 669de1e..bfbf3d7 100644 (file)
@@ -1,5+1,5 @@
 /*
- * cs.h 1.69 1999/10/25 20:23:17
+ * cs.h 1.71 2000/08/29 00:54:20
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
@@ -251,11+251,6 @@ typedef struct eventmask_t {
 #define PRESENT_IOBASE_3       0x100
 #define PRESENT_IOSIZE         0x200
 
-/* Attributes for Request/GetConfiguration */
-#define CONF_ENABLE_IRQ                0x01
-#define EXCLUSIVE_USE          0x02
-#define VALID_CLIENT           0x04
-
 /* For GetMemPage, MapMemPage */
 typedef struct memreq_t {
     u_int      CardOffset;
index 92feb63..186ce9f 100644 (file)
@@ -1,5+1,5 @@
 /*
- * cs_types.h 1.17 2000/01/18 01:14:36
+ * cs_types.h 1.18 2000/06/12 21:55:40
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
index 337076a..bb95644 100644 (file)
@@ -1,5+1,5 @@
 /*
- * driver_ops.h 1.14 1999/10/25 20:23:17
+ * driver_ops.h 1.15 2000/06/12 21:55:40
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
index ddb271e..e50033b 100644 (file)
@@ -1,5+1,5 @@
 /*
- * ds.h 1.55 1999/10/25 20:23:17
+ * ds.h 1.56 2000/06/12 21:55:40
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
index 0fb5278..deab295 100644 (file)
@@ -1,5+1,5 @@
 /*
- * ftl.h 1.7 1999/10/25 20:23:17
+ * ftl.h 1.8 2000/06/12 21:55:40
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
index 38101ab..d7f7059 100644 (file)
@@ -1,5+1,5 @@
 /*
- * mem_op.h 1.12 1999/10/25 20:23:17
+ * mem_op.h 1.13 2000/06/12 21:55:40
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
index 5c0cdb6..c87a364 100644 (file)
@@ -1,5+1,5 @@
 /*
- * memory.h 1.6 1999/10/25 20:23:17
+ * memory.h 1.7 2000/06/12 21:55:40
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
index b53657f..e00757c 100644 (file)
@@ -1,5+1,5 @@
 /*
- * ss.h 1.26 2000/02/04 20:35:21
+ * ss.h 1.28 2000/06/12 21:55:40
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * limitations under the License. 
  *
  * The initial developer of the original code is David A. Hinds
- * <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
@@ -61,6+61,7 @@ typedef struct socket_cap_t {
 #define SS_CAP_PAGE_REGS       0x0001
 #define SS_CAP_VIRTUAL_BUS     0x0002
 #define SS_CAP_MEM_ALIGN       0x0004
+#define SS_CAP_STATIC_MAP      0x0008
 #define SS_CAP_PCCARD          0x4000
 #define SS_CAP_CARDBUS         0x8000
 
index 4f6ffc7..70f3d8a 100644 (file)
@@ -1,4+1,4 @@
-/* version.h 1.83 2000/02/03 02:16:14 (David Hinds) */
+/* version.h 1.92 2000/07/21 18:26:56 (David Hinds) */
 
-#define CS_RELEASE "3.1.11"
-#define CS_RELEASE_CODE 0x310b
+#define CS_RELEASE "3.1.20"
+#define CS_RELEASE_CODE 0x3115
index 049815f..ab9fd08 100644 (file)
@@ -584,7+584,7 @@ asmlinkage void __init start_kernel(void)
         *      make syscalls (and thus be locked).
         */
        smp_init();
-       kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+       kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
        unlock_kernel();
        current->need_resched = 1;
        cpu_idle();
index 580c021..2554468 100644 (file)
@@ -267,26+267,6 @@ void exit_fs(struct task_struct *tsk)
        __exit_fs(tsk);
 }
 
-static inline void __exit_sighand(struct task_struct *tsk)
-{
-       struct signal_struct * sig = tsk->sig;
-
-       if (sig) {
-               spin_lock_irq(&tsk->sigmask_lock);
-               tsk->sig = NULL;
-               spin_unlock_irq(&tsk->sigmask_lock);
-               if (atomic_dec_and_test(&sig->count))
-                       kmem_cache_free(sigact_cachep, sig);
-       }
-
-       flush_signals(tsk);
-}
-
-void exit_sighand(struct task_struct *tsk)
-{
-       __exit_sighand(tsk);
-}
-
 /*
  * We can use these to temporarily drop into
  * "lazy TLB" mode and back.
@@ -461,7+441,7 @@ fake_volatile:
        __exit_mm(tsk);
        __exit_files(tsk);
        __exit_fs(tsk);
-       __exit_sighand(tsk);
+       exit_sighand(tsk);
        exit_thread();
        tsk->state = TASK_ZOMBIE;
        tsk->exit_code = code;
index 64dd0f9..8ef76f1 100644 (file)
@@ -500,15+500,21 @@ out_release:
 
 static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
 {
-       if (clone_flags & CLONE_SIGHAND) {
+       struct signal_struct *sig;
+
+       if (clone_flags & CLONE_SIGNAL) {
                atomic_inc(&current->sig->count);
                return 0;
        }
-       tsk->sig = kmem_cache_alloc(sigact_cachep, GFP_KERNEL);
-       if (!tsk->sig)
+       sig = kmem_cache_alloc(sigact_cachep, GFP_KERNEL);
+       tsk->sig = sig;
+       if (!sig)
                return -1;
-       spin_lock_init(&tsk->sig->siglock);
-       atomic_set(&tsk->sig->count, 1);
+       spin_lock_init(&sig->siglock);
+       atomic_set(&sig->count, 1);
+
+       init_sigpending(&sig->pending);
+
        memcpy(tsk->sig->action, current->sig->action, sizeof(tsk->sig->action));
        return 0;
 }
@@ -591,9+597,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
        spin_lock_init(&p->alloc_lock);
 
        p->sigpending = 0;
-       sigemptyset(&p->signal);
-       p->sigqueue = NULL;
-       p->sigqueue_tail = &p->sigqueue;
+       init_sigpending(&p->pending);
 
        p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
        p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
@@ -664,7+668,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
        p->tgid = retval;
        INIT_LIST_HEAD(&p->thread_group);
        write_lock_irq(&tasklist_lock);
-       if (clone_flags & CLONE_THREAD) {
+       if (clone_flags & CLONE_SIGNAL) {
                p->tgid = current->tgid;
                list_add(&p->thread_group, &current->thread_group);
        }
index 660d492..35c089c 100644 (file)
 
 extern int console_loglevel;
 extern void set_device_ro(kdev_t dev,int flag);
-#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
-extern long (*do_nfsservctl)(int, void *, void *);
-#endif
 
 extern void *sys_call_table;
 
@@ -265,10+262,6 @@ EXPORT_SYMBOL(filemap_swapout);
 EXPORT_SYMBOL(filemap_sync);
 EXPORT_SYMBOL(lock_page);
 
-#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
-EXPORT_SYMBOL(do_nfsservctl);
-#endif
-
 /* device registration */
 EXPORT_SYMBOL(register_chrdev);
 EXPORT_SYMBOL(unregister_chrdev);
index 8b47b55..6ad8f4c 100644 (file)
@@ -213,7+213,9 @@ static inline int preemption_goodness(struct task_struct * prev, struct task_str
  * This function must be inline as anything that saves and restores
  * flags has to do so within the same register window on sparc (Anton)
  */
-static inline void reschedule_idle(struct task_struct * p, unsigned long flags)
+static FASTCALL(void reschedule_idle(struct task_struct * p));
+
+static void reschedule_idle(struct task_struct * p)
 {
 #ifdef CONFIG_SMP
        int this_cpu = smp_processor_id();
@@ -284,7+286,6 @@ static inline void reschedule_idle(struct task_struct * p, unsigned long flags)
                goto preempt_now;
        }
 
-       spin_unlock_irqrestore(&runqueue_lock, flags);
        return;
                
 send_now_idle:
@@ -296,12+297,10 @@ send_now_idle:
        if ((tsk->processor != current->processor) && !tsk->need_resched)
                smp_send_reschedule(tsk->processor);
        tsk->need_resched = 1;
-       spin_unlock_irqrestore(&runqueue_lock, flags);
        return;
 
 preempt_now:
        tsk->need_resched = 1;
-       spin_unlock_irqrestore(&runqueue_lock, flags);
        /*
         * the APIC stuff can go outside of the lock because
         * it uses no task information, only CPU#.
@@ -316,7+315,6 @@ preempt_now:
        tsk = cpu_curr(this_cpu);
        if (preemption_goodness(tsk, p, this_cpu) > 1)
                tsk->need_resched = 1;
-       spin_unlock_irqrestore(&runqueue_lock, flags);
 #endif
 }
 
@@ -365,9+363,7 @@ inline void wake_up_process(struct task_struct * p)
        if (task_on_runqueue(p))
                goto out;
        add_to_runqueue(p);
-       reschedule_idle(p, flags); // spin_unlocks runqueue
-
-       return;
+       reschedule_idle(p);
 out:
        spin_unlock_irqrestore(&runqueue_lock, flags);
 }
@@ -480,10+476,9 @@ out_unlock:
         * current process as well.)
         */
 running_again:
-       if (prev == idle_task(smp_processor_id()))
-               goto out_unlock;
-       reschedule_idle(prev, flags); // spin_unlocks runqueue
-       return;
+       if (prev != idle_task(smp_processor_id()))
+               reschedule_idle(prev);
+       goto out_unlock;
 #endif /* CONFIG_SMP */
 }
 
@@ -656,6+651,9 @@ still_running_back:
 
 same_process:
        reacquire_kernel_lock(current);
+       if (current->need_resched)
+               goto tq_scheduler_back;
+
        return;
 
 recalculate:
@@ -1142,13+1140,13 @@ static void show_task(struct task_struct * p)
                printk("\n");
 
        {
-               struct signal_queue *q;
+               struct sigqueue *q;
                char s[sizeof(sigset_t)*2+1], b[sizeof(sigset_t)*2+1]; 
 
-               render_sigset_t(&p->signal, s);
+               render_sigset_t(&p->pending.signal, s);
                render_sigset_t(&p->blocked, b);
                printk("   sig: %d %s %s :", signal_pending(p), s, b);
-               for (q = p->sigqueue; q ; q = q->next)
+               for (q = p->pending.head; q ; q = q->next)
                        printk(" %d", q->info.si_signo);
                printk(" X\n");
        }
index 77a9b8e..caa59d5 100644 (file)
 #define SIG_SLAB_DEBUG 0
 #endif
 
-static kmem_cache_t *signal_queue_cachep;
+static kmem_cache_t *sigqueue_cachep;
 
 atomic_t nr_queued_signals;
 int max_queued_signals = 1024;
 
 void __init signals_init(void)
 {
-       signal_queue_cachep =
-               kmem_cache_create("signal_queue",
-                                 sizeof(struct signal_queue),
-                                 __alignof__(struct signal_queue),
+       sigqueue_cachep =
+               kmem_cache_create("sigqueue",
+                                 sizeof(struct sigqueue),
+                                 __alignof__(struct sigqueue),
                                  SIG_SLAB_DEBUG, NULL, NULL);
-       if (!signal_queue_cachep)
-               panic("signals_init(): cannot create signal_queue SLAB cache");
+       if (!sigqueue_cachep)
+               panic("signals_init(): cannot create sigueue SLAB cache");
 }
 
 
 /* Given the mask, find the first available signal that should be serviced. */
 
 static int
-next_signal(sigset_t *signal, sigset_t *mask)
+next_signal(struct task_struct *tsk, sigset_t *mask)
 {
-       unsigned long i, *s, *m, x;
+       unsigned long i, *s1, *s2, *m, x;
        int sig = 0;
        
-       s = signal->sig;
+       s1 = tsk->pending.signal.sig;
+       s2 = tsk->sig->pending.signal.sig;
        m = mask->sig;
        switch (_NSIG_WORDS) {
        default:
-               for (i = 0; i < _NSIG_WORDS; ++i, ++s, ++m)
-                       if ((x = *s &~ *m) != 0) {
+               for (i = 0; i < _NSIG_WORDS; ++i, ++s1, ++s2, ++m)
+                       if ((x = (*s1 | *s2) &~ *m) != 0) {
                                sig = ffz(~x) + i*_NSIG_BPW + 1;
                                break;
                        }
                break;
 
-       case 2: if ((x = s[0] &~ m[0]) != 0)
+       case 2: if ((x = (s1[0] | s2[0]) &~ m[0]) != 0)
                        sig = 1;
-               else if ((x = s[1] &~ m[1]) != 0)
+               else if ((x = (s1[1] | s2[1]) &~ m[1]) != 0)
                        sig = _NSIG_BPW + 1;
                else
                        break;
                sig += ffz(~x);
                break;
 
-       case 1: if ((x = *s &~ *m) != 0)
+       case 1: if ((x = (*s1 | *s2) &~ *m) != 0)
                        sig = ffz(~x) + 1;
                break;
        }
@@ -81,6+82,23 @@ next_signal(sigset_t *signal, sigset_t *mask)
        return sig;
 }
 
+static void flush_sigqueue(struct sigpending *queue)
+{
+       struct sigqueue *q, *n;
+
+       sigemptyset(&queue->signal);
+       q = queue->head;
+       queue->head = NULL;
+       queue->tail = &queue->head;
+
+       while (q) {
+               n = q->next;
+               kmem_cache_free(sigqueue_cachep, q);
+               atomic_dec(&nr_queued_signals);
+               q = n;
+       }
+}
+
 /*
  * Flush all pending signals for a task.
  */
@@ -88,20+106,26 @@ next_signal(sigset_t *signal, sigset_t *mask)
 void
 flush_signals(struct task_struct *t)
 {
-       struct signal_queue *q, *n;
-
        t->sigpending = 0;
-       sigemptyset(&t->signal);
-       q = t->sigqueue;
-       t->sigqueue = NULL;
-       t->sigqueue_tail = &t->sigqueue;
+       flush_sigqueue(&t->pending);
+       flush_sigqueue(&t->pending);
+}
 
-       while (q) {
-               n = q->next;
-               kmem_cache_free(signal_queue_cachep, q);
-               atomic_dec(&nr_queued_signals);
-               q = n;
+void exit_sighand(struct task_struct *tsk)
+{
+       struct signal_struct * sig = tsk->sig;
+
+       spin_lock_irq(&tsk->sigmask_lock);
+       if (sig) {
+               tsk->sig = NULL;
+               if (atomic_dec_and_test(&sig->count)) {
+                       flush_sigqueue(&sig->pending);
+                       kmem_cache_free(sigact_cachep, sig);
+               }
        }
+       tsk->sigpending = 0;
+       flush_sigqueue(&tsk->pending);
+       spin_unlock_irq(&tsk->sigmask_lock);
 }
 
 /*
@@ -148,6+172,53 @@ unblock_all_signals(void)
        recalc_sigpending(current);
 }
 
+static int collect_signal(int sig, struct sigpending *list, siginfo_t *info)
+{
+       if (sigismember(&list->signal, sig)) {
+               /* Collect the siginfo appropriate to this signal.  */
+               struct sigqueue *q, **pp;
+               pp = &list->head;
+               while ((q = *pp) != NULL) {
+                       if (q->info.si_signo == sig)
+                               goto found_it;
+                       pp = &q->next;
+               }
+
+               /* Ok, it wasn't in the queue.  We must have
+                  been out of queue space.  So zero out the
+                  info.  */
+               info->si_signo = sig;
+               info->si_errno = 0;
+               info->si_code = 0;
+               info->si_pid = 0;
+               info->si_uid = 0;
+               return 1;
+
+found_it:
+               if ((*pp = q->next) == NULL)
+                       list->tail = pp;
+
+               /* Copy the sigqueue information and free the queue entry */
+               copy_siginfo(info, &q->info);
+               kmem_cache_free(sigqueue_cachep,q);
+               atomic_dec(&nr_queued_signals);
+
+               /* Non-RT signals can exist multiple times.. */
+               if (sig >= SIGRTMIN) {
+                       while ((q = *pp) != NULL) {
+                               if (q->info.si_signo == sig)
+                                       goto found_another;
+                               pp = &q->next;
+                       }
+               }
+
+               sigdelset(&list->signal, sig);
+found_another:
+               return 1;
+       }
+       return 0;
+}
+
 /*
  * Dequeue a signal and return the element to the caller, which is 
  * expected to free it.
@@ -165,7+236,7 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid,
        signal_pending(current));
 #endif
 
-       sig = next_signal(&current->signal, mask);
+       sig = next_signal(current, mask);
        if (current->notifier) {
                sigset_t merged;
                int i;
@@ -174,7+245,7 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid,
                for (i = 0; i < _NSIG_WORDS; i++)
                        merged.sig[i] = mask->sig[i]
                            | current->notifier_mask->sig[i];
-               altsig = next_signal(&current->signal, &merged);
+               altsig = next_signal(current, &merged);
                if (sig != altsig) {
                        if (!(current->notifier)(current->notifier_data)) {
                                current->sigpending = 0;
@@ -184,63+255,14 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid,
        }
 
        if (sig) {
-               int reset = 1;
-
-               /* Collect the siginfo appropriate to this signal.  */
-               struct signal_queue *q, **pp;
-               pp = &current->sigqueue;
-               q = current->sigqueue;
-
-               /* Find the one we're interested in ... */
-               for ( ; q ; pp = &q->next, q = q->next)
-                       if (q->info.si_signo == sig)
-                               break;
-               if (q) {
-                       if ((*pp = q->next) == NULL)
-                               current->sigqueue_tail = pp;
-                       copy_siginfo(info, &q->info);
-                       kmem_cache_free(signal_queue_cachep,q);
-                       atomic_dec(&nr_queued_signals);
-
-                       /* Then see if this signal is still pending.
-                          (Non rt signals may not be queued twice.)
-                        */
-                       if (sig >= SIGRTMIN)
-                               for (q = *pp; q; q = q->next)
-                                       if (q->info.si_signo == sig) {
-                                               reset = 0;
-                                               break;
-                                       }
-                                       
-               } else {
-                       /* Ok, it wasn't in the queue.  We must have
-                          been out of queue space.  So zero out the
-                          info.  */
-                       info->si_signo = sig;
-                       info->si_errno = 0;
-                       info->si_code = 0;
-                       info->si_pid = 0;
-                       info->si_uid = 0;
-               }
-
-               if (reset) {
-                       sigdelset(&current->signal, sig);
-                       recalc_sigpending(current);
-               }
-
+               if (!collect_signal(sig, &current->pending, info))
+                       if (!collect_signal(sig, &current->sig->pending, info))
+                               sig = 0;
+                               
                /* XXX: Once POSIX.1b timers are in, if si_code == SI_TIMER,
                   we need to xchg out the timer overrun values.  */
-       } else {
-               /* XXX: Once CLONE_PID is in to join those "threads" that are
-                  part of the same "process", look for signals sent to the
-                  "process" as well.  */
-
-               /* Sanity check... */
-               if (mask == &current->blocked && signal_pending(current)) {
-                       printk(KERN_CRIT "SIG: sigpending lied\n");
-                       current->sigpending = 0;
-               }
        }
+       recalc_sigpending(current);
 
 #if DEBUG_SIG
 printk(" %d -> %d\n", signal_pending(current), sig);
@@ -249,44+271,42 @@ printk(" %d -> %d\n", signal_pending(current), sig);
        return sig;
 }
 
-/*
- * Remove signal sig from queue and from t->signal.
- * Returns 1 if sig was found in t->signal.
- *
- * All callers must be holding t->sigmask_lock.
- */
-static int rm_sig_from_queue(int sig, struct task_struct *t)
+static int rm_from_queue(int sig, struct sigpending *s)
 {
-       struct signal_queue *q, **pp;
+       struct sigqueue *q, **pp;
 
-       if (sig >= SIGRTMIN) {
-               printk(KERN_CRIT "SIG: rm_sig_from_queue() doesn't support rt signals\n");
+       if (!sigismember(&s->signal, sig))
                return 0;
-       }
 
-       if (!sigismember(&t->signal, sig))
-               return 0;
-
-       sigdelset(&t->signal, sig);
+       sigdelset(&s->signal, sig);
 
-       pp = &t->sigqueue;
-       q = t->sigqueue;
+       pp = &s->head;
 
-       /* Find the one we're interested in ...
-          It may appear only once. */
-       for ( ; q ; pp = &q->next, q = q->next)
-               if (q->info.si_signo == sig)
-                       break;
-       if (q) {
-               if ((*pp = q->next) == NULL)
-                       t->sigqueue_tail = pp;
-               kmem_cache_free(signal_queue_cachep,q);
-               atomic_dec(&nr_queued_signals);
+       while ((q = *pp) != NULL) {
+               if (q->info.si_signo == sig) {
+                       if ((*pp = q->next) == NULL)
+                               s->tail = pp;
+                       kmem_cache_free(sigqueue_cachep,q);
+                       atomic_dec(&nr_queued_signals);
+                       continue;
+               }
+               pp = &q->next;
        }
        return 1;
 }
 
 /*
+ * Remove signal sig from t->pending.
+ * Returns 1 if sig was found.
+ *
+ * All callers must be holding t->sigmask_lock.
+ */
+static int rm_sig_from_queue(int sig, struct task_struct *t)
+{
+       return rm_from_queue(sig, &t->pending) | rm_from_queue(sig, &t->sig->pending);
+}
+
+/*
  * Bad permissions for sending the signal
  */
 int bad_signal(int sig, struct siginfo *info, struct task_struct *t)
@@ -299,6+319,46 @@ int bad_signal(int sig, struct siginfo *info, struct task_struct *t)
 }
 
 /*
+ * Signal type:
+ *    < 0 : global action (kill - spread to all non-blocked threads)
+ *    = 0 : ignored
+ *    > 0 : wake up.
+ */
+static int signal_type(int sig, struct signal_struct *signals)
+{
+       unsigned long handler;
+
+       if (!signals)
+               return 0;
+       
+       handler = (unsigned long) signals->action[sig-1].sa.sa_handler;
+       if (handler > 1)
+               return 1;
+
+       /* "Ignore" handler.. Illogical, but that has an implicit handler for SIGCHLD */
+       if (handler == 1)
+               return sig == SIGCHLD;
+
+       /* Default handler. Normally lethal, but.. */
+       switch (sig) {
+
+       /* Ignored */
+       case SIGCONT: case SIGWINCH:
+       case SIGCHLD: case SIGURG:
+               return 0;
+
+       /* Implicit behaviour */
+       case SIGTSTP: case SIGTTIN: case SIGTTOU:
+               return 1;
+
+       /* Implicit actions (kill or do special stuff) */
+       default:
+               return -1;
+       }
+}
+               
+
+/*
  * Determine whether a signal should be posted or not.
  *
  * Signals with SIG_IGN can be ignored, except for the
@@ -308,41+368,18 @@ int bad_signal(int sig, struct siginfo *info, struct task_struct *t)
  */
 static int ignored_signal(int sig, struct task_struct *t)
 {
-       struct signal_struct *signals;
-       struct k_sigaction *ka;
-
        /* Don't ignore traced or blocked signals */
        if ((t->ptrace & PT_PTRACED) || sigismember(&t->blocked, sig))
                return 0;
-       
-       signals = t->sig;
-       if (!signals)
-               return 1;
-
-       ka = &signals->action[sig-1];
-       switch ((unsigned long) ka->sa.sa_handler) {
-       case (unsigned long) SIG_DFL:
-               if (sig == SIGCONT ||
-                   sig == SIGWINCH ||
-                   sig == SIGCHLD ||
-                   sig == SIGURG)
-                       break;
-               return 0;
 
-       case (unsigned long) SIG_IGN:
-               if (sig != SIGCHLD)
-                       break;
-       /* fallthrough */
-       default:
-               return 0;
-       }
-       return 1;
+       return signal_type(sig, t->sig) == 0;
 }
 
 /*
- * Handle TASK_STOPPED.
- * Also, return true for the unblockable signals that we
- * should deliver to all threads..
+ * Handle TASK_STOPPED cases etc implicit behaviour
+ * of certain magical signals.
+ *
+ * SIGKILL gets spread out to every thread. 
  */
 static void handle_stop_signal(int sig, struct task_struct *t)
 {
@@ -352,24+389,23 @@ static void handle_stop_signal(int sig, struct task_struct *t)
                if (t->state == TASK_STOPPED)
                        wake_up_process(t);
                t->exit_code = 0;
-               if (rm_sig_from_queue(SIGSTOP, t) || rm_sig_from_queue(SIGTSTP, t) ||
-                   rm_sig_from_queue(SIGTTOU, t) || rm_sig_from_queue(SIGTTIN, t))
-                       recalc_sigpending(t);
+               rm_sig_from_queue(SIGSTOP, t);
+               rm_sig_from_queue(SIGTSTP, t);
+               rm_sig_from_queue(SIGTTOU, t);
+               rm_sig_from_queue(SIGTTIN, t);
                break;
 
        case SIGSTOP: case SIGTSTP:
        case SIGTTIN: case SIGTTOU:
                /* If we're stopping again, cancel SIGCONT */
-               if (rm_sig_from_queue(SIGCONT, t))
-                       recalc_sigpending(t);
+               rm_sig_from_queue(SIGCONT, t);
                break;
        }
-       return 0;
 }
 
-static int deliver_signal(int sig, struct siginfo *info, struct task_struct *t)
+static int send_signal(int sig, struct siginfo *info, struct sigpending *signals)
 {
-       struct signal_queue * q = NULL;
+       struct sigqueue * q = NULL;
 
        /* Real-time signals must be queued if sent by sigqueue, or
           some other real-time mechanism.  It is implementation
@@ -380,14+416,14 @@ static int deliver_signal(int sig, struct siginfo *info, struct task_struct *t)
           pass on the info struct.  */
 
        if (atomic_read(&nr_queued_signals) < max_queued_signals) {
-               q = kmem_cache_alloc(signal_queue_cachep, GFP_ATOMIC);
+               q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);
        }
 
        if (q) {
                atomic_inc(&nr_queued_signals);
                q->next = NULL;
-               *t->sigqueue_tail = q;
-               t->sigqueue_tail = &q->next;
+               *signals->tail = q;
+               signals->tail = &q->next;
                switch ((unsigned long) info) {
                        case 0:
                                q->info.si_signo = sig;
@@ -416,46+452,57 @@ static int deliver_signal(int sig, struct siginfo *info, struct task_struct *t)
                return -EAGAIN;
        }
 
-       sigaddset(&t->signal, sig);
-       if (!sigismember(&t->blocked, sig)) {
-               t->sigpending = 1;
-#ifdef CONFIG_SMP
-               /*
-                * If the task is running on a different CPU 
-                * force a reschedule on the other CPU - note that
-                * the code below is a tad loose and might occasionally
-                * kick the wrong CPU if we catch the process in the
-                * process of changing - but no harm is done by that
-                * other than doing an extra (lightweight) IPI interrupt.
-                *
-                * note that we rely on the previous spin_lock to
-                * lock interrupts for us! No need to set need_resched
-                * since signal event passing goes through ->blocked.
-                */
-               spin_lock(&runqueue_lock);
-               if (t->has_cpu && t->processor != smp_processor_id())
-                       smp_send_reschedule(t->processor);
-               spin_unlock(&runqueue_lock);
-#endif /* CONFIG_SMP */
-       }
+       sigaddset(&signals->signal, sig);
        return 0;
 }
 
-
 /*
- * Send a thread-group-wide signal.
+ * Tell a process that it has a new active signal..
  *
- * Rule: SIGSTOP and SIGKILL get delivered to _everybody_.
+ * NOTE! we rely on the previous spin_lock to
+ * lock interrupts for us! We can only be called with
+ * "sigmask_lock" held, and the local interrupt must
+ * have been disabled when that got aquired!
  *
- * Others get delivered to the thread that doesn't have them
- * blocked (just one such thread).
+ * No need to set need_resched since signal event passing
+ * goes through ->blocked
+ */
+static inline void signal_wake_up(struct task_struct *t)
+{
+       t->sigpending = 1;
+
+       if (t->state & TASK_INTERRUPTIBLE) {
+               wake_up_process(t);
+               return;
+       }
+
+#ifdef CONFIG_SMP
+       /*
+        * If the task is running on a different CPU 
+        * force a reschedule on the other CPU to make
+        * it notice the new signal quickly.
+        *
+        * The code below is a tad loose and might occasionally
+        * kick the wrong CPU if we catch the process in the
+        * process of changing - but no harm is done by that
+        * other than doing an extra (lightweight) IPI interrupt.
+        */
+       spin_lock(&runqueue_lock);
+       if (t->has_cpu && t->processor != smp_processor_id())
+               smp_send_reschedule(t->processor);
+       spin_unlock(&runqueue_lock);
+#endif /* CONFIG_SMP */
+}
+
+/*
+ * Send a thread-group-wide signal.
  *
- * If all threads have it blocked, it gets delievered to the
- * thread group leader.
+ * Just add it to the shared signal queue. And
+ * make sure to inform everybody.
  */
 static int send_tg_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 {
-       int retval = 0;
+       int retval, type;
        struct task_struct *tsk;
 
        if (sig < 0 || sig > _NSIG)
@@ -464,13+511,24 @@ static int send_tg_sig_info(int sig, struct siginfo *info, struct task_struct *p
        if (bad_signal(sig, info, p))
                return -EPERM;
 
-       if (!sig)
+       if (!sig || !p->sig)
                return 0;
 
+       /* Have we already delivered this non-queued signal? */
+       if (sig < SIGRTMIN && sigismember(&p->sig->pending.signal, sig))
+               return 0;
+
+       /* Add the signal to the global queue */
+       retval = send_signal(sig, info, &p->sig->pending);
+       if (retval < 0)
+               return retval;
+
+       type = signal_type(sig, p->sig);
+
+       /* Inform all threads about it.. */
        tsk = p;
        do {
                unsigned long flags;
-               tsk = next_thread(tsk);
 
                /* Zombie? Ignore */
                if (!tsk->sig)
@@ -479,30+537,35 @@ static int send_tg_sig_info(int sig, struct siginfo *info, struct task_struct *p
                spin_lock_irqsave(&tsk->sigmask_lock, flags);
                handle_stop_signal(sig, tsk);
 
-               /* Is the signal ignored by this thread? */
-               if (ignored_signal(sig, tsk))
+               /* Blocked? */
+               if (sigismember(&tsk->blocked, sig))
                        goto next;
 
-               /* Have we already delivered this non-queued signal? */
-               if (sig < SIGRTMIN && sigismember(&tsk->signal, sig))
+               /* Is the signal ignored by this thread? */
+               switch (type) {
+               case 0:
                        goto next;
-
-               /* Not blocked? Go, girl, go! */
-               if (tsk == p || !sigismember(&tsk->blocked, sig)) {
-                       retval = deliver_signal(sig, info, tsk);
-
-                       /* Signals other than SIGKILL and SIGSTOP have "once" semantics */
-                       if (sig != SIGKILL && sig != SIGSTOP)
-                               tsk = p;
+               case -1:        /* affects all threads? */
+                       sigaddset(&tsk->pending.signal, sig);
                }
+
+               /* Go, girl, go! */
+               signal_wake_up(tsk);
 next:
                spin_unlock_irqrestore(&tsk->sigmask_lock, flags);
-               if ((tsk->state & TASK_INTERRUPTIBLE) && signal_pending(tsk))
-                       wake_up_process(tsk);
-       } while (tsk != p);
-       return retval;
+       } while ((tsk = next_thread(tsk)) != p);
+       return 0;
 }
 
+static int deliver_signal(int sig, struct siginfo *info, struct task_struct *t)
+{
+       int retval = send_signal(sig, info, &t->pending);
+
+       if (!retval && !sigismember(&t->blocked, sig))
+               signal_wake_up(t);
+
+       return retval;
+}
 
 int
 send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
@@ -542,7+605,7 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
        /* Support queueing exactly one non-rt signal, so that we
           can get more detailed information about the cause of
           the signal. */
-       if (sig < SIGRTMIN && sigismember(&t->signal, sig))
+       if (sig < SIGRTMIN && sigismember(&t->pending.signal, sig))
                goto out;
 
        ret = deliver_signal(sig, info, t);
@@ -669,9+732,11 @@ static int kill_tg_info(int sig, struct siginfo *info, pid_t pid)
        error = -ESRCH;
        if (p) {
                /* Is it the leader? Otherwise it degenerates into a per-thread thing */
-               if (p->tgid == pid)
+               if (p->tgid == pid) {
+                       spin_lock(&p->sig->siglock);
                        error = send_tg_sig_info(sig, info, p);
-               else
+                       spin_unlock(&p->sig->siglock);
+               } else
                        error = send_sig_info(sig, info, p);
        }
        read_unlock(&tasklist_lock);
@@ -921,7+986,8 @@ sys_rt_sigpending(sigset_t *set, size_t sigsetsize)
                goto out;
 
        spin_lock_irq(&current->sigmask_lock);
-       sigandsets(&pending, &current->blocked, &current->signal);
+       sigorsets(&pending, &current->pending.signal, &current->sig->pending.signal);
+       sigandsets(&pending, &current->blocked, &pending);
        spin_unlock_irq(&current->sigmask_lock);
 
        error = -EFAULT;
@@ -1032,7+1098,7 @@ sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo)
        info.si_signo = sig;
 
        /* POSIX.1b doesn't mention process groups.  */
-       return kill_proc_info(sig, &info, pid);
+       return kill_tg_info(sig, &info, pid);
 }
 
 int
@@ -1044,10+1110,12 @@ do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact)
            (act && (sig == SIGKILL || sig == SIGSTOP)))
                return -EINVAL;
 
-       spin_lock_irq(&current->sigmask_lock);
        k = &current->sig->action[sig-1];
 
-       if (oact) *oact = *k;
+       spin_lock(&current->sig->siglock);
+
+       if (oact)
+               *oact = *k;
 
        if (act) {
                *k = *act;
@@ -1075,33+1143,14 @@ do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact)
                        && (sig == SIGCONT ||
                            sig == SIGCHLD ||
                            sig == SIGWINCH))) {
-                       /* So dequeue any that might be pending.
-                          XXX: process-wide signals? */
-                       if (sig >= SIGRTMIN &&
-                           sigismember(&current->signal, sig)) {
-                               struct signal_queue *q, **pp;
-                               pp = &current->sigqueue;
-                               q = current->sigqueue;
-                               while (q) {
-                                       if (q->info.si_signo != sig)
-                                               pp = &q->next;
-                                       else {
-                                               if ((*pp = q->next) == NULL)
-                                                       current->sigqueue_tail = pp;
-                                               kmem_cache_free(signal_queue_cachep, q);
-                                               atomic_dec(&nr_queued_signals);
-                                       }
-                                       q = *pp;
-                               }
-                               
-                       }
-                       sigdelset(&current->signal, sig);
-                       recalc_sigpending(current);
+                       spin_lock_irq(&current->sigmask_lock);
+                       if (rm_sig_from_queue(sig, current))
+                               recalc_sigpending(current);
+                       spin_unlock_irq(&current->sigmask_lock);
                }
        }
 
-       spin_unlock_irq(&current->sigmask_lock);
-
+       spin_unlock(&current->sig->siglock);
        return 0;
 }
 
@@ -1228,7+1277,7 @@ sys_sigpending(old_sigset_t *set)
        old_sigset_t pending;
 
        spin_lock_irq(&current->sigmask_lock);
-       pending = current->blocked.sig[0] & current->signal.sig[0];
+       pending = current->blocked.sig[0] & (current->pending.signal.sig[0] | current->sig->pending.signal.sig[0]);
        spin_unlock_irq(&current->sigmask_lock);
 
        error = -EFAULT;
index 9772254..750421a 100644 (file)
@@ -1074,6+1074,13 @@ found_page:
                        goto page_not_up_to_date;
                generic_file_readahead(reada_ok, filp, inode, page);
 page_ok:
+               /* If users can be writing to this page using arbitrary
+                * virtual addresses, take care about potential aliasing
+                * before reading the page on the kernel side.
+                */
+               if (page->mapping->i_mmap_shared != NULL)
+                       flush_dcache_page(page);
+
                /*
                 * Ok, we have the page, and it's up-to-date, so
                 * now we can copy it to user space...
index 07708bc..0a23e5e 100644 (file)
@@ -924,33+924,9 @@ static void partial_clear(struct vm_area_struct *vma, unsigned long address)
        memclear_highpage_flush(page, offset, PAGE_SIZE - offset);
 }
 
-/*
- * Handle all mappings that got truncated by a "truncate()"
- * system call.
- *
- * NOTE! We have to be ready to update the memory sharing
- * between the file and the memory map for a potential last
- * incomplete page.  Ugly, but necessary.
- */
-void vmtruncate(struct inode * inode, loff_t offset)
+static void vmtruncate_list(struct vm_area_struct *mpnt,
+                           unsigned long pgoff, unsigned long partial)
 {
-       unsigned long partial, pgoff;
-       struct vm_area_struct * mpnt;
-       struct address_space *mapping = inode->i_mapping;
-       unsigned long limit;
-
-       if (inode->i_size < offset)
-               goto do_expand;
-       inode->i_size = offset;
-       truncate_inode_pages(mapping, offset);
-       spin_lock(&mapping->i_shared_lock);
-       if (!mapping->i_mmap)
-               goto out_unlock;
-
-       pgoff = (offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-       partial = (unsigned long)offset & (PAGE_CACHE_SIZE - 1);
-
-       mpnt = mapping->i_mmap;
        do {
                struct mm_struct *mm = mpnt->vm_mm;
                unsigned long start = mpnt->vm_start;
@@ -983,6+959,39 @@ void vmtruncate(struct inode * inode, loff_t offset)
                zap_page_range(mm, start, len);
                flush_tlb_range(mm, start, end);
        } while ((mpnt = mpnt->vm_next_share) != NULL);
+}
+                             
+
+/*
+ * Handle all mappings that got truncated by a "truncate()"
+ * system call.
+ *
+ * NOTE! We have to be ready to update the memory sharing
+ * between the file and the memory map for a potential last
+ * incomplete page.  Ugly, but necessary.
+ */
+void vmtruncate(struct inode * inode, loff_t offset)
+{
+       unsigned long partial, pgoff;
+       struct address_space *mapping = inode->i_mapping;
+       unsigned long limit;
+
+       if (inode->i_size < offset)
+               goto do_expand;
+       inode->i_size = offset;
+       truncate_inode_pages(mapping, offset);
+       spin_lock(&mapping->i_shared_lock);
+       if (!mapping->i_mmap && !mapping->i_mmap_shared)
+               goto out_unlock;
+
+       pgoff = (offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+       partial = (unsigned long)offset & (PAGE_CACHE_SIZE - 1);
+
+       if (mapping->i_mmap != NULL)
+               vmtruncate_list(mapping->i_mmap, pgoff, partial);
+       if (mapping->i_mmap_shared != NULL)
+               vmtruncate_list(mapping->i_mmap_shared, pgoff, partial);
+
 out_unlock:
        spin_unlock(&mapping->i_shared_lock);
        /* this should go into ->truncate */
@@ -1095,15+1104,12 @@ static int do_swap_page(struct mm_struct * mm,
  */
 static int do_anonymous_page(struct mm_struct * mm, struct vm_area_struct * vma, pte_t *page_table, int write_access, unsigned long addr)
 {
-       int high = 0;
        struct page *page = NULL;
        pte_t entry = pte_wrprotect(mk_pte(ZERO_PAGE(addr), vma->vm_page_prot));
        if (write_access) {
                page = alloc_page(GFP_HIGHUSER);
                if (!page)
                        return -1;
-               if (PageHighMem(page))
-                       high = 1;
                clear_user_highpage(page, addr);
                entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
                mm->rss++;
index 9667d19..9c00275 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -906,15+906,21 @@ void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp)
        if (file) {
                struct inode * inode = file->f_dentry->d_inode;
                struct address_space *mapping = inode->i_mapping;
+               struct vm_area_struct **head;
+
                if (vmp->vm_flags & VM_DENYWRITE)
                        atomic_dec(&inode->i_writecount);
+
+               head = &mapping->i_mmap;
+               if (vmp->vm_flags & VM_SHARED)
+                       head = &mapping->i_mmap_shared;
       
                /* insert vmp into inode's share list */
                spin_lock(&mapping->i_shared_lock);
-               if((vmp->vm_next_share = mapping->i_mmap) != NULL)
-                       mapping->i_mmap->vm_pprev_share = &vmp->vm_next_share;
-               mapping->i_mmap = vmp;
-               vmp->vm_pprev_share = &mapping->i_mmap;
+               if((vmp->vm_next_share = *head) != NULL)
+                       (*head)->vm_pprev_share = &vmp->vm_next_share;
+               *head = vmp;
+               vmp->vm_pprev_share = head;
                spin_unlock(&mapping->i_shared_lock);
        }
 }
index 95098e4..6e327e6 100644 (file)
@@ -646,7+646,7 @@ static int __init kswapd_init(void)
 {
        printk("Starting kswapd v1.7\n");
        swap_setup();
-       kernel_thread(kswapd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+       kernel_thread(kswapd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
        return 0;
 }
 
index 1c79056..bc04ecc 100644 (file)
@@ -155,7+155,10 @@ static ssize_t proc_mpc_read(struct file *file, char *buff,
        if (*pos >= length) length = 0;
        else {
          if ((count + *pos) > length) count = length - *pos;
-         copy_to_user(buff, (char *)page , count);
+         if (copy_to_user(buff, (char *)page , count)) {
+                 free_page(page);
+                 return -EFAULT;
+          }
          *pos += count;
        }
 
@@ -198,7+201,7 @@ static ssize_t proc_mpc_write(struct file *file, const char *buff,
         *ppos += incoming;
 
         page[incoming] = '\0';
-       retval = parse_qos(buff, incoming);
+       retval = parse_qos(page, incoming);
         if (retval == 0)
                 printk("mpoa: proc_mpc_write: could not parse '%s'\n", page);
 
index 57718cf..8723b12 100644 (file)
  *                                             with only 6 digipeaters and sockaddr_ax25 in ax25_bind(),
  *                                             ax25_connect() and ax25_sendmsg()
  *                     Joerg(DL1BKE)           Added support for SO_BINDTODEVICE
+ *                     Arnaldo C. Melo         s/suser/capable(CAP_NET_ADMIN)/, some more cleanups
  */
 
 #include <linux/config.h>
@@ -817,10+818,7 @@ static int ax25_getsockopt(struct socket *sock, int level, int optname, char *op
        if (put_user(length, optlen))
                return -EFAULT;
 
-       if (copy_to_user(optval, valptr, length))
-               return -EFAULT;
-
-       return 0;
+       return copy_to_user(optval, valptr, length) ? -EFAULT : 0;
 }
 
 static int ax25_listen(struct socket *sock, int backlog)
@@ -1070,7+1068,7 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                return -EINVAL;
 
        call = ax25_findbyuid(current->euid);
-       if (call == NULL && ax25_uid_policy && !suser())
+       if (call == NULL && ax25_uid_policy && !capable(CAP_NET_ADMIN))
                return -EACCES;
 
        if (call == NULL)
@@ -1584,9+1582,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
                        if (amount < 0)
                                amount = 0;
-                       if (put_user(amount, (int *)arg))
-                               return -EFAULT;
-                       return 0;
+                       return put_user(amount, (int *)arg);
                }
 
                case TIOCINQ: {
@@ -1595,18+1591,14 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        /* These two are safe on a single CPU system as only user tasks fiddle here */
                        if ((skb = skb_peek(&sk->receive_queue)) != NULL)
                                amount = skb->len;
-                       if (put_user(amount, (int *)arg))
-                               return -EFAULT;
-                       return 0;
+                       return put_user(amount, (int *)arg);
                }
 
                case SIOCGSTAMP:
                        if (sk != NULL) {
                                if (sk->stamp.tv_sec == 0)
                                        return -ENOENT;
-                               if (copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)))
-                                       return -EFAULT;
-                               return 0;
+                               return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) : -EFAULT : 0;
                        }
                        return -EINVAL;
 
@@ -1621,7+1613,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
                case SIOCAX25NOUID: {   /* Set the default policy (default/bar) */
                        long amount;
-                       if (!suser())
+                       if (!capable(CAP_NET_ADMIN))
                                return -EPERM;
                        if (get_user(amount, (long *)arg))
                                return -EFAULT;
@@ -1634,12+1626,12 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                case SIOCADDRT:
                case SIOCDELRT:
                case SIOCAX25OPTRT:
-                       if (!suser())
+                       if (!capable(CAP_NET_ADMIN))
                                return -EPERM;
                        return ax25_rt_ioctl(cmd, (void *)arg);
 
                case SIOCAX25CTLCON:
-                       if (!suser())
+                       if (!capable(CAP_NET_ADMIN))
                                return -EPERM;
                        return ax25_ctl_ioctl(cmd, (void *)arg);
 
@@ -1688,7+1680,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                case SIOCAX25ADDFWD:
                case SIOCAX25DELFWD: {
                        struct ax25_fwd_struct ax25_fwd;
-                       if (!suser())
+                       if (!capable(CAP_NET_ADMIN))
                                return -EPERM;
                        if (copy_from_user(&ax25_fwd, (void *)arg, sizeof(ax25_fwd)))
                                return -EFAULT;
index 6d58c5d..32a7ab5 100644 (file)
  *                     Joerg(DL1BKE)   Moved BPQ Ethernet driver to separate device.
  *     AX.25 035       Frederic(F1OAT) Support for pseudo-digipeating.
  *                     Jonathan(G4KLX) Support for packet forwarding.
+ *                     Arnaldo C. Melo s/suser/capable/
  */
 
 #include <linux/config.h>
@@ -363,7+364,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
                return -EHOSTUNREACH;
 
        if ((call = ax25_findbyuid(current->euid)) == NULL) {
-               if (ax25_uid_policy && !suser())
+               if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE))
                        return -EPERM;
                call = (ax25_address *)ax25->ax25_dev->dev->dev_addr;
        }
index 1cce0dd..eb226b1 100644 (file)
@@ -78,7+78,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)
                        return -ENOENT;
 
                case SIOCAX25ADDUID:
-                       if (!suser())
+                       if (!capable(CAP_NET_ADMIN))
                                return -EPERM;
                        if (ax25_findbyuid(sax->sax25_uid))
                                return -EEXIST;
@@ -95,7+95,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)
                        return 0;
 
                case SIOCAX25DELUID:
-                       if (!suser())
+                       if (!capable(CAP_NET_ADMIN))
                                return -EPERM;
                        for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) {
                                if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0)
index 5322b3a..348c30f 100644 (file)
  *       Patrick Caulfield: Fixes to delayed acceptance logic.
  *         David S. Miller: New socket locking
  *        Steve Whitehouse: Socket list hashing/locking
+ *         Arnaldo C. Melo: use capable, not suser
  */
 
 
@@ -688,7+689,7 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        if (dn_ntohs(saddr->sdn_nodeaddrl) && (dn_ntohs(saddr->sdn_nodeaddrl) != 2))
                return -EINVAL;
 
-       if (saddr->sdn_objnum && !suser())
+       if (saddr->sdn_objnum && !capable(CAP_NET_BIND_SERVICE))
                return -EPERM;
 
        if (dn_ntohs(saddr->sdn_objnamel) > DN_MAXOBJL)
@@ -698,7+699,7 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                return -EINVAL;
 
        if (saddr->sdn_flags & SDF_WILD) {
-               if (!suser())
+               if (!capable(CAP_NET_BIND_SERVICE))
                        return -EPERM;
        } else {
                if (dn_ntohs(saddr->sdn_nodeaddrl)) {
@@ -1101,7+1102,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
 #if 0
        case SIOCSIFADDR:
-               if (!suser())    return -EPERM;
+               if (!capable(CAP_NET_ADMIN))    return -EPERM;
 
                if ((err = copy_from_user(devname, ioarg->devname, 5)) != 0)
                        break;
@@ -1143,7+1144,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
 #if 0
        case SIOCSNETADDR:
-               if (!suser()) {
+               if (!capable(CAP_NET_ADMIN)) {
                        err = -EPERM;
                        break;
                }
@@ -1174,7+1175,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                break;
 #endif
        case OSIOCSNETADDR:
-               if (!suser()) {
+               if (!capable(CAP_NET_ADMIN)) {
                        err = -EPERM;
                        break;
                }
@@ -1189,8+1190,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                break;
 
        case OSIOCGNETADDR:
-               if ((err = put_user(decnet_address, (unsigned short *)arg)) != 0)
-                       break;
+               err = put_user(decnet_address, (unsigned short *)arg);
                break;
         case SIOCGIFCONF:
         case SIOCGIFFLAGS:
index cb9b3d1..7a2a815 100644 (file)
@@ -641,17+641,15 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void *arg)
 static int econet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
-       int err;
        int pid;
 
        switch(cmd) 
        {
                case FIOSETOWN:
                case SIOCSPGRP:
-                       err = get_user(pid, (int *) arg);
-                       if (err)
-                               return err; 
-                       if (current->pid != pid && current->pgrp != -pid && !suser())
+                       if (get_user(pid, (int *) arg))
+                               return -EFAULT; 
+                       if (current->pid != pid && current->pgrp != -pid && !capable(CAP_NET_ADMIN))
                                return -EPERM;
                        sk->proc = pid;
                        return(0);
@@ -661,10+659,7 @@ static int econet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg
                case SIOCGSTAMP:
                        if(sk->stamp.tv_sec==0)
                                return -ENOENT;
-                       err = -EFAULT;
-                       if (!copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)))
-                               err = 0;
-                       return err;
+                       return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0;
                case SIOCGIFFLAGS:
                case SIOCSIFFLAGS:
                case SIOCGIFCONF:
index ef7fc36..cf39195 100644 (file)
@@ -5,7+5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_minisocks.c,v 1.1 2000/08/09 11:59:04 davem Exp $
+ * Version:    $Id: tcp_minisocks.c,v 1.2 2000/08/28 04:32:52 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -742,7+742,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
                /* Back to base struct sock members. */
                newsk->err = 0;
                newsk->priority = 0;
-               atomic_set(&newsk->refcnt, 1);
+               atomic_set(&newsk->refcnt, 2);
 #ifdef INET_REFCNT_DEBUG
                atomic_inc(&inet_sock_nr);
 #endif
@@ -966,5+966,6 @@ int tcp_child_process(struct sock *parent, struct sock *child,
        }
 
        bh_unlock_sock(child);
+       sock_put(child);
        return ret;
 }
index d4e4802..27d9570 100644 (file)
  *                     Jonathan(G4KLX) Removed hdrincl.
  *     NET/ROM 007     Jonathan(G4KLX) New timer architecture.
  *                                     Impmented Idle timer.
+ *                     Arnaldo C. Melo s/suser/capable/, micro cleanups
  */
 
 #include <linux/config.h>
@@ -437,10+438,7 @@ static int nr_getsockopt(struct socket *sock, int level, int optname,
        if (put_user(len, optlen))
                return -EFAULT;
 
-       if (copy_to_user(optval, &val, len))
-               return -EFAULT;
-
-       return 0;
+       return copy_to_user(optval, &val, len) ? -EFAULT : 0;
 }
 
 static int nr_listen(struct socket *sock, int backlog)
@@ -616,7+614,7 @@ full_sockaddr_ax25))
         * Only the super user can set an arbitrary user callsign.
         */
        if (addr->fsa_ax25.sax25_ndigis == 1) {
-               if (!suser())
+               if (!capable(CAP_NET_BIND_SERVICE))
                        return -EACCES;
                sk->protinfo.nr->user_addr   = addr->fsa_digipeater[0];
                sk->protinfo.nr->source_addr = addr->fsa_ax25.sax25_call;
@@ -624,7+622,7 @@ full_sockaddr_ax25))
                source = &addr->fsa_ax25.sax25_call;
 
                if ((user = ax25_findbyuid(current->euid)) == NULL) {
-                       if (ax25_uid_policy && !suser())
+                       if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE))
                                return -EPERM;
                        user = source;
                }
@@ -680,7+678,7 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
                source = (ax25_address *)dev->dev_addr;
 
                if ((user = ax25_findbyuid(current->euid)) == NULL) {
-                       if (ax25_uid_policy && !suser())
+                       if (ax25_uid_policy && !capable(CAP_NET_ADMIN))
                                return -EPERM;
                        user = source;
                }
@@ -1111,9+1109,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
                        if (amount < 0)
                                amount = 0;
-                       if (put_user(amount, (int *)arg))
-                               return -EFAULT;
-                       return 0;
+                       return put_user(amount, (int *)arg);
                }
 
                case TIOCINQ: {
@@ -1122,18+1118,14 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        /* These two are safe on a single CPU system as only user tasks fiddle here */
                        if ((skb = skb_peek(&sk->receive_queue)) != NULL)
                                amount = skb->len;
-                       if (put_user(amount, (int *)arg))
-                               return -EFAULT;
-                       return 0;
+                       return put_user(amount, (int *)arg);
                }
 
                case SIOCGSTAMP:
                        if (sk != NULL) {
                                if (sk->stamp.tv_sec == 0)
                                        return -ENOENT;
-                               if (copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)))
-                                       return -EFAULT;
-                               return 0;
+                               return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0;
                        }
                        return -EINVAL;
 
@@ -1152,7+1144,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                case SIOCADDRT:
                case SIOCDELRT:
                case SIOCNRDECOBS:
-                       if (!suser()) return -EPERM;
+                       if (!capable(CAP_NET_ADMIN)) return -EPERM;
                        return nr_rt_ioctl(cmd, (void *)arg);
 
                default:
index 990431e..b7827f0 100644 (file)
@@ -5,7+5,7 @@
  *
  *             PACKET - implements raw packet sockets.
  *
- * Version:    $Id: af_packet.c,v 1.41 2000/08/10 01:21:14 davem Exp $
+ * Version:    $Id: af_packet.c,v 1.42 2000/08/29 03:44:56 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
index 1bf9f7a..f61d9cd 100644 (file)
  *                                     Implemented idle timer.
  *                                     Added use count to neighbour.
  *                      Tomi(OH2BNS)    Fixed rose_getname().
+ *                      Arnaldo C. Melo s/suser/capable/ + micro cleanups
  */
 
 #include <linux/config.h>
@@ -510,10+511,7 @@ static int rose_getsockopt(struct socket *sock, int level, int optname,
        if (put_user(len, optlen))
                return -EFAULT;
 
-       if (copy_to_user(optval, &val, len))
-               return -EFAULT;
-
-       return 0;
+       return copy_to_user(optval, &val, len) ? -EFAULT : 0;
 }
 
 static int rose_listen(struct socket *sock, int backlog)
@@ -695,7+693,7 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        source = &addr->srose_call;
 
        if ((user = ax25_findbyuid(current->euid)) == NULL) {
-               if (ax25_uid_policy && !suser())
+               if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE))
                        return -EACCES;
                user = source;
        }
@@ -1236,9+1234,7 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
                        if (amount < 0)
                                amount = 0;
-                       if (put_user(amount, (unsigned int *)arg))
-                               return -EFAULT;
-                       return 0;
+                       return put_user(amount, (unsigned int *)arg);
                }
 
                case TIOCINQ: {
@@ -1247,18+1243,14 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        /* These two are safe on a single CPU system as only user tasks fiddle here */
                        if ((skb = skb_peek(&sk->receive_queue)) != NULL)
                                amount = skb->len;
-                       if (put_user(amount, (unsigned int *)arg))
-                               return -EFAULT;
-                       return 0;
+                       return put_user(amount, (unsigned int *)arg);
                }
 
                case SIOCGSTAMP:
                        if (sk != NULL) {
                                if (sk->stamp.tv_sec == 0)
                                        return -ENOENT;
-                               if (copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)))
-                                       return -EFAULT;
-                               return 0;
+                               return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0;
                        }
                        return -EINVAL;
 
@@ -1284,9+1276,7 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        struct rose_cause_struct rose_cause;
                        rose_cause.cause      = sk->protinfo.rose->cause;
                        rose_cause.diagnostic = sk->protinfo.rose->diagnostic;
-                       if (copy_to_user((void *)arg, &rose_cause, sizeof(struct rose_cause_struct)))
-                               return -EFAULT;
-                       return 0;
+                       return copy_to_user((void *)arg, &rose_cause, sizeof(struct rose_cause_struct)) ? -EFAULT : 0;
                }
 
                case SIOCRSSCAUSE: {
@@ -1299,7+1289,7 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                }
 
                case SIOCRSSL2CALL:
-                       if (!suser()) return -EPERM;
+                       if (!capable(CAP_NET_ADMIN)) return -EPERM;
                        if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
                                ax25_listen_release(&rose_callsign, NULL);
                        if (copy_from_user(&rose_callsign, (void *)arg, sizeof(ax25_address)))
@@ -1309,9+1299,7 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        return 0;
 
                case SIOCRSGL2CALL:
-                       if (copy_to_user((void *)arg, &rose_callsign, sizeof(ax25_address)))
-                               return -EFAULT;
-                       return 0;
+                       return copy_to_user((void *)arg, &rose_callsign, sizeof(ax25_address)) ? -EFAULT : 0;
 
                case SIOCRSACCEPT:
                        if (sk->protinfo.rose->state == ROSE_STATE_5) {
index ebaaa72..7988059 100644 (file)
  *     2000-22-03      Daniela Squassoni Allowed disabling/enabling of 
  *                                       facilities negotiation and increased 
  *                                       the throughput upper limit.
+ *     2000-27-08      Arnaldo C. Melo s/suser/capable/ + micro cleanups
  */
 
 #include <linux/config.h>
@@ -402,10+403,7 @@ static int x25_getsockopt(struct socket *sock, int level, int optname,
        if (put_user(len, optlen))
                return -EFAULT;
 
-       if (copy_to_user(optval, &val, len))
-               return -EFAULT;
-
-       return 0;
+       return copy_to_user(optval, &val, len) ? -EFAULT : 0;
 }
 
 static int x25_listen(struct socket *sock, int backlog)
@@ -1067,9+1065,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
                        if (amount < 0)
                                amount = 0;
-                       if (put_user(amount, (unsigned int *)arg))
-                               return -EFAULT;
-                       return 0;
+                       return put_user(amount, (unsigned int *)arg);
                }
 
                case TIOCINQ: {
@@ -1078,18+1074,14 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        /* These two are safe on a single CPU system as only user tasks fiddle here */
                        if ((skb = skb_peek(&sk->receive_queue)) != NULL)
                                amount = skb->len;
-                       if (put_user(amount, (unsigned int *)arg))
-                               return -EFAULT;
-                       return 0;
+                       return put_user(amount, (unsigned int *)arg);
                }
 
                case SIOCGSTAMP:
                        if (sk != NULL) {
                                if (sk->stamp.tv_sec == 0)
                                        return -ENOENT;
-                               if (copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)))
-                                       return -EFAULT;
-                               return 0;
+                               return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0;
                        }
                        return -EINVAL;
 
@@ -1114,15+1106,13 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        return x25_subscr_ioctl(cmd, (void *)arg);
 
                case SIOCX25SSUBSCRIP:
-                       if (!suser()) return -EPERM;
+                       if (!capable(CAP_NET_ADMIN)) return -EPERM;
                        return x25_subscr_ioctl(cmd, (void *)arg);
 
                case SIOCX25GFACILITIES: {
                        struct x25_facilities facilities;
                        facilities = sk->protinfo.x25->facilities;
-                       if (copy_to_user((void *)arg, &facilities, sizeof(facilities)))
-                               return -EFAULT;
-                       return 0;
+                       return copy_to_user((void *)arg, &facilities, sizeof(facilities)) ? -EFAULT : 0;
                }
 
                case SIOCX25SFACILITIES: {
@@ -1148,9+1138,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                case SIOCX25GCALLUSERDATA: {
                        struct x25_calluserdata calluserdata;
                        calluserdata = sk->protinfo.x25->calluserdata;
-                       if (copy_to_user((void *)arg, &calluserdata, sizeof(calluserdata)))
-                               return -EFAULT;
-                       return 0;
+                       return copy_to_user((void *)arg, &calluserdata, sizeof(calluserdata)) ? -EFAULT : 0;
                }
 
                case SIOCX25SCALLUSERDATA: {
@@ -1166,9+1154,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                case SIOCX25GCAUSEDIAG: {
                        struct x25_causediag causediag;
                        causediag = sk->protinfo.x25->causediag;
-                       if (copy_to_user((void *)arg, &causediag, sizeof(causediag)))
-                               return -EFAULT;
-                       return 0;
+                       return copy_to_user((void *)arg, &causediag, sizeof(causediag)) ? -EFAULT : 0;
                }
 
                default:
close