# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet v2.5.60 -> 1.1060 # drivers/net/8139too.c 1.49 -> 1.50 # drivers/acpi/namespace/nsxfobj.c 1.16 -> 1.17 # drivers/media/video/saa7110.c 1.7 -> 1.8 # net/ipv4/netfilter/ip_conntrack_core.c 1.15 -> 1.16 # arch/ppc64/kernel/signal.c 1.25 -> 1.26 # include/acpi/acpixf.h 1.16 -> 1.17 # drivers/net/3c59x.c 1.28 -> 1.29 # drivers/acpi/resources/rsio.c 1.11 -> 1.12 # arch/sparc64/kernel/signal32.c 1.26 -> 1.27 # arch/i386/kernel/timers/Makefile 1.5 -> 1.6 # arch/i386/kernel/cpu/cpufreq/speedstep.c 1.10 -> 1.11 # include/asm-x86_64/smp.h 1.4 -> 1.5 # drivers/input/keyboard/sunkbd.c 1.8 -> 1.10 # net/ipv4/netfilter/arptable_filter.c 1.1 -> 1.2 # drivers/media/dvb/av7110/av7110.c 1.3 -> 1.5 # drivers/input/keyboard/newtonkbd.c 1.6 -> 1.7 # drivers/media/video/saa7134/saa7134-tvaudio.c 1.3 -> 1.4 # drivers/usb/input/hid.h 1.21 -> 1.23 # drivers/acpi/namespace/nsdumpdv.c 1.6 -> 1.7 # drivers/input/joystick/stinger.c 1.8 -> 1.9 # drivers/net/irda/smc-ircc.c 1.15 -> 1.16 # drivers/scsi/ips.c 1.43 -> 1.47 # drivers/scsi/scsi_error.c 1.33 -> 1.34 # drivers/acpi/executer/exoparg3.c 1.8 -> 1.9 # include/asm-sparc64/system.h 1.23 -> 1.24 # fs/jffs2/background.c 1.16 -> 1.18 # net/bluetooth/rfcomm/core.c 1.8 -> 1.9 # drivers/acpi/hardware/hwacpi.c 1.13 -> 1.14 # drivers/acpi/event.c 1.3 -> 1.4 # arch/x86_64/kernel/traps.c 1.15 -> 1.16 # fs/nfsd/nfssvc.c 1.32 -> 1.33 # drivers/scsi/aic7xxx/aic79xx_osm.c 1.17 -> 1.19 # arch/x86_64/kernel/process.c 1.12 -> 1.13 # arch/x86_64/mm/fault.c 1.9 -> 1.10 # drivers/acpi/sleep.c 1.11 -> 1.20 drivers/acpi/sleep/main.c (moved) # sound/pci/korg1212/korg1212.c 1.16 -> 1.17 # drivers/char/n_tty.c 1.10 -> 1.11 # kernel/ksyms.c 1.181 -> 1.183 # fs/sysv/inode.c 1.25 -> 1.26 # include/asm-i386/msr.h 1.11 -> 1.12 # drivers/acpi/blacklist.c 1.5 -> 1.6 # drivers/input/joystick/magellan.c 1.10 -> 1.11 # drivers/input/joystick/iforce/iforce-serio.c 1.2 -> 1.3 # net/rxrpc/krxiod.c 1.3 -> 1.4 # include/asm-x86_64/signal.h 1.5 -> 1.6 # include/acpi/acpiosxf.h 1.20 -> 1.21 # arch/x86_64/ia32/fpu32.c 1.4 -> 1.5 # drivers/oprofile/cpu_buffer.c 1.4 -> 1.5 # include/net/sctp/user.h 1.4 -> 1.5 # arch/arm/kernel/signal.c 1.19 -> 1.20 # net/ipv4/proc.c 1.9 -> 1.10 # drivers/net/tulip/de4x5.c 1.21 -> 1.23 # include/linux/jiffies.h 1.5 -> 1.6 # drivers/acpi/dispatcher/dsobject.c 1.21 -> 1.22 # drivers/acpi/hardware/hwgpe.c 1.13 -> 1.14 # drivers/input/serio/serio.c 1.12 -> 1.14 # include/linux/buffer_head.h 1.37 -> 1.38 # drivers/pnp/pnpbios/core.c 1.21 -> 1.22 # drivers/mtd/devices/blkmtd.c 1.24 -> 1.25 # fs/xfs/pagebuf/page_buf.c 1.37 -> 1.38 # drivers/net/3c509.c 1.30 -> 1.31 # net/sctp/associola.c 1.18 -> 1.26 # drivers/input/serio/ct82c710.c 1.4 -> 1.5 # drivers/acpi/button.c 1.16 -> 1.17 # drivers/acpi/executer/exconvrt.c 1.18 -> 1.19 # arch/x86_64/kernel/setup.c 1.8 -> 1.9 # drivers/input/serio/parkbd.c 1.3 -> 1.4 # include/asm-x86_64/page.h 1.7 -> 1.8 # drivers/char/agp/sis-agp.c 1.13 -> 1.14 # drivers/input/serio/rpckbd.c 1.7 -> 1.8 # drivers/input/joystick/spaceball.c 1.10 -> 1.11 # arch/cris/kernel/signal.c 1.9 -> 1.10 # arch/i386/kernel/apm.c 1.43 -> 1.46 # arch/x86_64/vmlinux.lds.S 1.12 -> 1.13 # arch/i386/kernel/cpu/cpufreq/longhaul.c 1.8 -> 1.9 # drivers/ide/pci/amd74xx.h 1.5 -> 1.6 # drivers/acpi/parser/psscope.c 1.9 -> 1.10 # drivers/acpi/executer/exfield.c 1.16 -> 1.17 # drivers/usb/input/wacom.c 1.25 -> 1.27 # include/asm-i386/fixmap.h 1.10 -> 1.11 # net/sctp/objcnt.c 1.4 -> 1.5 # include/asm-x86_64/current.h 1.2 -> 1.3 # net/sctp/input.c 1.14.1.1 -> 1.20 # arch/parisc/oprofile/timer_int.c 1.1 -> 1.3 # drivers/acpi/toshiba_acpi.c 1.5 -> 1.7 # drivers/acpi/fan.c 1.10 -> 1.11 # net/x25/x25_link.c 1.8 -> 1.9 # net/sunrpc/sysctl.c 1.2 -> 1.3 # net/sctp/sm_statefuns.c 1.27 -> 1.31 # drivers/char/ftape/lowlevel/ftape-read.c 1.2 -> 1.3 # drivers/scsi/aic7xxx/aic7xxx_osm.c 1.16 -> 1.17 # fs/ext2/inode.c 1.61 -> 1.62 # drivers/char/watchdog/pcwd.c 1.16 -> 1.19 # drivers/acpi/utilities/uteval.c 1.15 -> 1.16 # drivers/acpi/dispatcher/dswload.c 1.20 -> 1.21 # drivers/acpi/resources/rsutils.c 1.12 -> 1.13 # net/ipv6/netfilter/ip6table_filter.c 1.3 -> 1.4 # include/asm-ppc/signal.h 1.5 -> 1.6 # drivers/acpi/utilities/utmisc.c 1.20 -> 1.21 # net/ipv6/sysctl_net_ipv6.c 1.4 -> 1.5 # include/linux/ext3_jbd.h 1.8 -> 1.9 # drivers/acpi/events/evrgnini.c 1.13 -> 1.14 # drivers/acpi/hardware/hwsleep.c 1.14 -> 1.15 # drivers/input/serio/i8042.c 1.22 -> 1.23 # drivers/input/joystick/twidjoy.c 1.5 -> 1.6 # drivers/acpi/pci_link.c 1.11 -> 1.12 # drivers/acpi/executer/exdump.c 1.17 -> 1.18 # drivers/char/agp/i7x05-agp.c 1.7 -> 1.8 # drivers/net/wan/comx-hw-comx.c 1.8 -> 1.9 # include/linux/sched.h 1.128 -> 1.131 # kernel/sys.c 1.40 -> 1.42 # drivers/block/ll_rw_blk.c 1.149 -> 1.151 # drivers/net/Space.c 1.16 -> 1.17 # drivers/acpi/namespace/nsparse.c 1.5 -> 1.6 # Makefile 1.370 -> 1.372 # drivers/acpi/dispatcher/dsfield.c 1.15 -> 1.16 # drivers/acpi/events/evregion.c 1.14 -> 1.15 # include/linux/hfs_sysdep.h 1.8 -> 1.9 # include/asm-x86_64/e820.h 1.3 -> 1.4 # drivers/acpi/executer/exstoren.c 1.15 -> 1.16 # drivers/acpi/utilities/utglobal.c 1.21 -> 1.22 # net/rxrpc/krxtimod.c 1.3 -> 1.4 # include/net/tcp.h 1.29 -> 1.30 # drivers/acpi/hardware/hwtimer.c 1.12 -> 1.13 # drivers/s390/net/lcs.c 1.9 -> 1.10 # include/asm-ia64/signal.h 1.8 -> 1.9 # drivers/acpi/utilities/utalloc.c 1.13 -> 1.14 # fs/ext3/xattr_user.c 1.2 -> 1.3 # include/asm-i386/module.h 1.4 -> 1.5 # drivers/acpi/utilities/utxface.c 1.14 -> 1.15 # arch/x86_64/kernel/acpi.c 1.3 -> 1.4 # drivers/oprofile/event_buffer.h 1.2 -> 1.3 # net/sctp/endpointola.c 1.10 -> 1.13 # include/linux/keyboard.h 1.3 -> 1.4 # mm/vmscan.c 1.146 -> 1.148 # arch/i386/kernel/cpu/cpufreq/powernow-k6.c 1.9 -> 1.10 # drivers/char/agp/frontend.c 1.26 -> 1.28 # drivers/acpi/executer/exregion.c 1.13 -> 1.14 # arch/sparc/Makefile 1.19 -> 1.20 # drivers/scsi/sym53c416.c 1.10 -> 1.11 # drivers/input/mouse/amimouse.c 1.6 -> 1.7 # net/sctp/sm_make_chunk.c 1.20 -> 1.25 # drivers/i2c/i2c-core.c 1.15 -> 1.16 # arch/x86_64/kernel/apic.c 1.9 -> 1.10 # drivers/char/agp/generic-3.0.c 1.5 -> 1.7 # arch/i386/Kconfig 1.36 -> 1.38 # drivers/acpi/parser/psopcode.c 1.17 -> 1.18 # fs/jfs/jfs_imap.c 1.19 -> 1.20 # drivers/acpi/events/evxfregn.c 1.12 -> 1.13 # drivers/sbus/char/envctrl.c 1.10 -> 1.11 # drivers/oprofile/oprof.h 1.2 -> 1.3 # fs/jbd/journal.c 1.25 -> 1.28 # include/asm-i386/signal.h 1.5 -> 1.6 # drivers/acpi/parser/psparse.c 1.19 -> 1.20 # arch/x86_64/kernel/msr.c 1.5 -> 1.6 # net/sctp/ulpevent.c 1.7 -> 1.10 # fs/devfs/base.c 1.69 -> 1.70 # arch/i386/kernel/Makefile 1.33 -> 1.34 # include/linux/signal.h 1.7 -> 1.8 # kernel/pm.c 1.6 -> 1.7 # drivers/char/watchdog/machzwd.c 1.14 -> 1.15 # net/bluetooth/af_bluetooth.c 1.11 -> 1.12 # arch/i386/kernel/acpi_wakeup.S 1.11 -> 1.13 arch/i386/kernel/acpi/wakeup.S (moved) # drivers/char/watchdog/sc1200wdt.c 1.3 -> 1.7 # drivers/acpi/executer/exprep.c 1.15 -> 1.16 # drivers/acpi/executer/exutils.c 1.17 -> 1.18 # fs/ufs/inode.c 1.18 -> 1.19 # net/sctp/transport.c 1.11 -> 1.15 # drivers/serial/sunsu.c 1.28 -> 1.29 # arch/x86_64/mm/init.c 1.15 -> 1.16 # net/sctp/Kconfig 1.1.1.1 -> 1.3 # net/sctp/output.c 1.12 -> 1.17 # arch/parisc/kernel/signal32.c 1.3 -> 1.4 # kernel/cpufreq.c 1.14 -> 1.15 # kernel/time.c 1.9 -> 1.10 # include/acpi/platform/acenv.h 1.14 -> 1.15 # lib/radix-tree.c 1.12 -> 1.13 # drivers/i2c/i2c-adap-ite.c 1.8 -> 1.9 # drivers/net/fc/iph5526.c 1.14 -> 1.15 # arch/i386/oprofile/op_x86_model.h 1.1 -> 1.2 # drivers/block/nbd.c 1.49 -> 1.50 # drivers/acpi/tables/tbinstal.c 1.16 -> 1.17 # drivers/input/mouse/psmouse.c 1.19 -> 1.21 # drivers/acpi/namespace/nsxfname.c 1.13 -> 1.14 # drivers/acpi/executer/exresnte.c 1.18 -> 1.19 # drivers/media/dvb/dvb-core/dvb_frontend.c 1.2 -> 1.3 # net/rxrpc/krxsecd.c 1.4 -> 1.5 # drivers/scsi/ips.h 1.22 -> 1.25 # kernel/softirq.c 1.32 -> 1.33 # net/key/af_key.c 1.12 -> 1.20 # drivers/net/starfire.c 1.23 -> 1.24 # arch/x86_64/kernel/smp.c 1.10 -> 1.11 # drivers/oprofile/oprof.c 1.3 -> 1.4 # include/linux/hiddev.h 1.7 -> 1.8 # arch/x86_64/boot/tools/build.c 1.1 -> 1.2 # include/asm-sparc64/signal.h 1.6 -> 1.7 # arch/mips64/kernel/signal.c 1.7 -> 1.8 # drivers/usb/storage/usb.c 1.56 -> 1.57 # fs/jfs/jfs_mount.c 1.13 -> 1.14 # drivers/input/serio/q40kbd.c 1.6 -> 1.7 # arch/alpha/kernel/init_task.c 1.2 -> 1.3 # drivers/acpi/pci_root.c 1.12 -> 1.13 # net/rxrpc/internal.h 1.3 -> 1.4 # drivers/acpi/resources/rsmisc.c 1.9 -> 1.10 # drivers/oprofile/buffer_sync.c 1.6 -> 1.7 # fs/sysv/itree.c 1.18 -> 1.19 # drivers/hotplug/ibmphp_hpc.c 1.8 -> 1.9 # include/asm-sparc/page.h 1.7 -> 1.8 # include/net/sctp/sctp.h 1.16 -> 1.21 # arch/x86_64/kernel/e820.c 1.2 -> 1.3 # arch/i386/kernel/ptrace.c 1.18 -> 1.19 # net/ipv6/netfilter/ip6_queue.c 1.5 -> 1.6 # arch/x86_64/kernel/setup64.c 1.8 -> 1.9 # drivers/acpi/events/evxfevnt.c 1.12 -> 1.13 # drivers/md/md.c 1.134 -> 1.135 # kernel/kmod.c 1.20 -> 1.22 # drivers/acpi/parser/pstree.c 1.11 -> 1.12 # include/net/sctp/ulpqueue.h 1.4 -> 1.5 # fs/jbd/transaction.c 1.25 -> 1.28 # net/sunrpc/rpc_pipe.c 1.3 -> 1.5 # drivers/acpi/parser/psargs.c 1.14 -> 1.15 # drivers/scsi/u14-34f.c 1.22 -> 1.23 # arch/ppc64/kernel/rtasd.c 1.8 -> 1.9 # drivers/acpi/executer/exnames.c 1.11 -> 1.12 # drivers/input/misc/gsc_ps2.c 1.1 -> 1.2 # drivers/char/agp/Makefile 1.15 -> 1.17 # drivers/acpi/executer/exfldio.c 1.19 -> 1.20 # arch/x86_64/kernel/mpparse.c 1.5 -> 1.6 # net/irda/ircomm/ircomm_tty.c 1.15 -> 1.16 # sound/oss/rme96xx.h 1.2 -> 1.3 # arch/cris/drivers/usb-host.c 1.10 -> 1.11 # net/sctp/outqueue.c 1.11 -> 1.17 # include/asm-mips/signal.h 1.2 -> 1.3 # drivers/media/video/tvaudio.c 1.12 -> 1.13 # arch/i386/kernel/io_apic.c 1.41 -> 1.43 # include/asm-sparc/cacheflush.h 1.1 -> 1.2 # drivers/input/mouse/pc110pad.c 1.5 -> 1.6 # fs/ext3/acl.c 1.2 -> 1.3 # net/sctp/debug.c 1.6 -> 1.8 # include/net/sctp/constants.h 1.5 -> 1.9 # drivers/acpi/acpi_ksyms.c 1.20 -> 1.21 # fs/reiserfs/resize.c 1.10 -> 1.11 # drivers/acpi/resources/rscreate.c 1.15 -> 1.16 # arch/i386/oprofile/timer_int.c 1.2 -> 1.4 # drivers/input/touchscreen/gunze.c 1.5 -> 1.6 # drivers/hotplug/cpqphp_ctrl.c 1.8 -> 1.9 # drivers/char/agp/generic.c 1.15 -> 1.19 # drivers/acorn/char/keyb_arc.c 1.4 -> 1.5 # arch/i386/Makefile 1.43 -> 1.44 # arch/x86_64/kernel/entry.S 1.8 -> 1.9 # kernel/user.c 1.5 -> 1.6 # drivers/acpi/namespace/nsinit.c 1.18 -> 1.19 # net/ipv4/netfilter/iptable_filter.c 1.3 -> 1.4 # fs/ncpfs/sock.c 1.13 -> 1.14 # drivers/char/agp/sworks-agp.c 1.21 -> 1.22 # drivers/acpi/dispatcher/dsmthdat.c 1.17 -> 1.18 # sound/oss/rme96xx.c 1.9 -> 1.10 # net/core/sysctl_net_core.c 1.2 -> 1.3 # drivers/oprofile/oprofilefs.c 1.2 -> 1.4 # net/sctp/sysctl.c 1.5 -> 1.6 # include/asm-x86_64/pda.h 1.6 -> 1.7 # fs/exec.c 1.69 -> 1.70 # drivers/mtd/mtdblock.c 1.36 -> 1.37 # fs/ext2/balloc.c 1.26 -> 1.27 # arch/x86_64/boot/Makefile 1.13 -> 1.14 # arch/i386/mach-voyager/voyager_smp.c 1.5 -> 1.6 # net/unix/sysctl_net_unix.c 1.3 -> 1.4 # net/sunrpc/clnt.c 1.30 -> 1.31 # include/asm-v850/signal.h 1.2 -> 1.3 # fs/eventpoll.c 1.13 -> 1.14 # drivers/net/pcmcia/xirc2ps_cs.c 1.13 -> 1.14 # drivers/acpi/namespace/nsobject.c 1.15 -> 1.16 # drivers/acpi/executer/exresolv.c 1.17 -> 1.18 # net/ipv6/netfilter/ip6table_mangle.c 1.4 -> 1.5 # drivers/char/nvram.c 1.16 -> 1.17 # mm/fadvise.c 1.1 -> 1.2 # arch/parisc/kernel/binfmt_elf32.c 1.2 -> 1.3 # net/irda/irsysctl.c 1.8 -> 1.9 # kernel/signal.c 1.67 -> 1.71 # scripts/Makefile.modver 1.11 -> 1.12 # fs/afs/internal.h 1.3 -> 1.4 # drivers/char/keyboard.c 1.24 -> 1.28 # drivers/acpi/tables/tbconvrt.c 1.17 -> 1.18 # arch/x86_64/kernel/head64.c 1.4 -> 1.5 # net/ipv4/netfilter/ip_nat_rule.c 1.5 -> 1.6 # net/netsyms.c 1.46 -> 1.48 # arch/i386/kernel/cpu/cpufreq/elanfreq.c 1.8 -> 1.9 # drivers/acpi/namespace/nseval.c 1.17 -> 1.18 # drivers/char/sx.c 1.17 -> 1.18 # drivers/sbus/char/bbc_envctrl.c 1.3 -> 1.4 # drivers/acpi/scan.c 1.14 -> 1.16 # include/asm-x86_64/io.h 1.5 -> 1.6 # drivers/input/joystick/iforce/iforce.h 1.2 -> 1.3 # drivers/acpi/ac.c 1.13 -> 1.14 # drivers/usb/input/hid-input.c 1.13 -> 1.15 # include/asm-ppc64/signal.h 1.3 -> 1.4 # drivers/char/agp/agp.h 1.38 -> 1.41 # drivers/acpi/utilities/utcopy.c 1.20 -> 1.21 # drivers/usb/input/hiddev.c 1.26 -> 1.27 # include/linux/pc_keyb.h 1.1 -> (deleted) # drivers/input/misc/Kconfig 1.3 -> 1.4 # arch/sparc64/kernel/systbls.S 1.29 -> 1.30 # arch/x86_64/ia32/sys_ia32.c 1.16 -> 1.17 # drivers/acpi/executer/exstore.c 1.21 -> 1.22 # arch/x86_64/kernel/irq.c 1.7 -> 1.8 # drivers/net/sis900.c 1.30 -> 1.31 # drivers/hotplug/cpci_hotplug_core.c 1.3 -> 1.4 # include/asm-i386/mach-summit/mach_mpparse.h 1.3 -> 1.4 # drivers/scsi/aacraid/aachba.c 1.9 -> 1.10 # arch/sparc/mm/init.c 1.16 -> 1.17 # mm/swap_state.c 1.55 -> 1.56 # arch/x86_64/ia32/ipc32.c 1.5 -> 1.6 # include/linux/input.h 1.25 -> 1.26 # arch/i386/kernel/cpu/cpufreq/Makefile 1.4 -> 1.5 # drivers/input/mouse/rpcmouse.c 1.12 -> 1.13 # include/linux/eventpoll.h 1.6 -> 1.7 # drivers/input/joystick/spaceorb.c 1.9 -> 1.10 # arch/x86_64/ia32/ia32entry.S 1.9 -> 1.11 # drivers/char/ec3104_keyb.c 1.2 -> 1.3 # drivers/acpi/pci_irq.c 1.14 -> 1.15 # include/net/sctp/sm.h 1.16 -> 1.19 # arch/i386/kernel/signal.c 1.27 -> 1.28 # include/asm-x86_64/mpspec.h 1.3 -> 1.4 # arch/s390x/kernel/signal32.c 1.13 -> 1.14 # drivers/scsi/aic7xxx/aic7xxx_core.c 1.20 -> 1.21 # arch/x86_64/kernel/nmi.c 1.6 -> 1.7 # drivers/char/riscom8.c 1.8 -> 1.9 # fs/afs/cmservice.c 1.3 -> 1.4 # drivers/usb/core/hub.c 1.54 -> 1.55 # drivers/usb/input/hid-ff.c 1.3 -> 1.4 # drivers/block/genhd.c 1.68 -> 1.70 # drivers/scsi/aic7xxx/aic79xx_pci.c 1.3 -> 1.4 # drivers/acpi/dispatcher/dsutils.c 1.17 -> 1.18 # arch/alpha/kernel/signal.c 1.15 -> 1.17 # drivers/char/watchdog/sc520_wdt.c 1.3 -> 1.4 # arch/i386/kernel/smpboot.c 1.47 -> 1.50 # drivers/media/video/bttv-cards.c 1.13 -> 1.14 # arch/i386/kernel/cpu/cpufreq/gx-suspmod.c 1.2 -> 1.3 # drivers/acpi/utilities/utdelete.c 1.15 -> 1.16 # drivers/input/serio/sa1111ps2.c 1.5 -> 1.6 # drivers/char/agp/intel-agp.c 1.21 -> 1.22 # drivers/acpi/dispatcher/dsmethod.c 1.14 -> 1.15 # scripts/fixdep.c 1.11 -> 1.12 # include/linux/hugetlb.h 1.10 -> 1.11 # fs/nfs/nfs3proc.c 1.24 -> 1.25 # drivers/net/tokenring/smctr.c 1.15 -> 1.16 # drivers/isdn/hardware/eicon/i4l_idi.c 1.1 -> 1.2 # include/linux/spinlock.h 1.21 -> 1.22 # drivers/input/joydev.c 1.13 -> 1.14 # net/econet/af_econet.c 1.12 -> 1.13 # fs/ufs/truncate.c 1.15 -> 1.16 # scripts/Makefile.lib 1.13 -> 1.15 # arch/parisc/oprofile/init.c 1.1 -> 1.2 # net/irda/ircomm/ircomm_param.c 1.8 -> 1.9 # drivers/usb/input/xpad.c 1.12 -> 1.13 # drivers/acpi/namespace/nsutils.c 1.19 -> 1.20 # drivers/oprofile/oprofile_files.c 1.2 -> 1.3 # include/acpi/acpi.h 1.7 -> 1.8 # include/asm-x86_64/i387.h 1.5 -> 1.6 # drivers/input/mouse/logibm.c 1.7 -> 1.8 # arch/i386/oprofile/op_counter.h 1.1 -> 1.2 # fs/jfs/jfs_logmgr.c 1.43 -> 1.44 # include/asm-alpha/signal.h 1.5 -> 1.6 # drivers/acpi/executer/exoparg2.c 1.19 -> 1.20 # arch/mips64/kernel/signal32.c 1.8 -> 1.9 # fs/ext2/ialloc.c 1.28 -> 1.29 # drivers/input/mouse/inport.c 1.6 -> 1.7 # drivers/char/watchdog/wdt.c 1.16 -> 1.17 # drivers/acpi/namespace/nsalloc.c 1.14 -> 1.15 # arch/ia64/mm/hugetlbpage.c 1.7 -> 1.8 # fs/minix/inode.c 1.32 -> 1.33 # drivers/acpi/power.c 1.14 -> 1.15 # arch/x86_64/mm/hugetlbpage.c 1.5 -> 1.8 # include/asm-x86_64/pgalloc.h 1.5 -> 1.6 # drivers/acpi/resources/rsaddr.c 1.10 -> 1.11 # drivers/input/keyboard/xtkbd.c 1.6 -> 1.7 # drivers/input/joystick/iforce/iforce-packets.c 1.3 -> 1.4 # drivers/acpi/resources/rscalc.c 1.14 -> 1.15 # include/net/irda/wrapper.h 1.2 -> 1.3 # include/asm-m68knommu/signal.h 1.2 -> 1.3 # net/sunrpc/sched.c 1.21 -> 1.22 # include/asm-x86_64/dma-mapping.h 1.1 -> 1.2 # arch/i386/kernel/nmi.c 1.14 -> 1.15 # arch/x86_64/kernel/init_task.c 1.3 -> 1.4 # drivers/acpi/ec.c 1.19 -> 1.20 # include/asm-sh/signal.h 1.3 -> 1.4 # drivers/net/tg3.c 1.58 -> 1.59 # sound/oss/vwsnd.c 1.7 -> 1.8 # drivers/char/rio/rioroute.c 1.3 -> 1.4 # net/ipv6/tcp_ipv6.c 1.36 -> 1.37 # drivers/acpi/resources/rsdump.c 1.12 -> 1.13 # arch/um/kernel/signal_kern.c 1.12 -> 1.13 # fs/ext3/xattr.c 1.4 -> 1.5 # arch/sparc64/kernel/signal.c 1.24 -> 1.25 # drivers/net/amd8111e.c 1.1 -> 1.2 # drivers/char/agp/Kconfig 1.8 -> 1.10 # arch/ia64/kernel/signal.c 1.19 -> 1.20 # drivers/block/loop.c 1.80 -> 1.81 # fs/buffer.c 1.182 -> 1.184 # arch/i386/oprofile/init.c 1.2 -> 1.3 # include/asm-x86_64/timex.h 1.5 -> 1.6 # fs/jffs/intrep.c 1.21 -> 1.22 # drivers/usb/input/hid-core.c 1.47 -> 1.49 # drivers/acpi/events/evxface.c 1.15 -> 1.16 # drivers/acpi/utilities/utinit.c 1.13 -> 1.14 # drivers/acpi/parser/psutils.c 1.14 -> 1.15 # fs/nfsd/export.c 1.68 -> 1.69 # arch/ppc64/oprofile/init.c 1.1 -> 1.2 # drivers/acpi/events/evmisc.c 1.16 -> 1.17 # include/linux/serio.h 1.11 -> 1.13 # fs/afs/kafstimod.c 1.3 -> 1.4 # drivers/acpi/events/evgpe.c 1.5 -> 1.6 # include/asm-sparc/signal.h 1.3 -> 1.4 # drivers/char/tty_io.c 1.56 -> 1.57 # drivers/char/agp/i460-agp.c 1.13 -> 1.14 # include/linux/sunrpc/clnt.h 1.12 -> 1.13 # drivers/acpi/executer/exconfig.c 1.14 -> 1.15 # drivers/acpi/system.c 1.26 -> 1.27 # drivers/usb/input/powermate.c 1.11 -> 1.13 # arch/sparc/kernel/init_task.c 1.6 -> 1.7 # fs/proc/array.c 1.41 -> 1.42 # fs/jfs/jfs_txnmgr.c 1.37 -> 1.38 # arch/parisc/kernel/sys32.h 1.2 -> 1.3 # MAINTAINERS 1.117 -> 1.119 # net/sctp/protocol.c 1.25 -> 1.30 # include/linux/oprofile.h 1.2 -> 1.5 # net/sctp/ipv6.c 1.15 -> 1.19 # fs/reiserfs/journal.c 1.60 -> 1.61 # drivers/acpi/bus.c 1.29 -> 1.30 # drivers/input/misc/Makefile 1.4 -> 1.5 # include/linux/cpufreq.h 1.12 -> 1.13 # drivers/ieee1394/nodemgr.c 1.17 -> 1.18 # arch/sparc64/oprofile/init.c 1.1 -> 1.2 # net/irda/irlap_event.c 1.15 -> 1.16 # include/asm-s390x/signal.h 1.5 -> 1.6 # sound/oss/ad1848.c 1.16 -> 1.17 # drivers/media/video/msp3400.c 1.12 -> 1.13 # drivers/usb/input/Makefile 1.12 -> 1.13 # mm/mmap.c 1.69 -> 1.71 # drivers/acpi/tables/tbrsdt.c 1.8 -> 1.9 # arch/i386/kernel/cpu/centaur.c 1.3 -> 1.5 # arch/s390x/kernel/signal.c 1.16 -> 1.17 # drivers/char/watchdog/w83877f_wdt.c 1.13 -> 1.14 # drivers/char/watchdog/acquirewdt.c 1.17 -> 1.18 # fs/ext2/xattr.c 1.4 -> 1.5 # fs/ufs/balloc.c 1.15 -> 1.16 # fs/lockd/svc.c 1.19 -> 1.20 # drivers/acpi/utilities/utdebug.c 1.14 -> 1.15 # drivers/message/i2o/i2o_core.c 1.13 -> 1.15 # drivers/net/arlan.c 1.12 -> 1.14 # arch/sparc64/kernel/sys_sparc32.c 1.61 -> 1.63 # include/asm-i386/mach-summit/mach_apic.h 1.17 -> 1.18 # net/sctp/command.c 1.5 -> 1.6 # arch/m68knommu/kernel/signal.c 1.4 -> 1.5 # drivers/scsi/st.c 1.53 -> 1.54 # arch/mips/baget/vacserial.c 1.6 -> 1.7 # drivers/acpi/tables/tbget.c 1.16 -> 1.17 # drivers/char/agp/ali-agp.c 1.13 -> 1.14 # fs/ext2/super.c 1.44 -> 1.45 # fs/smbfs/smbiod.c 1.6 -> 1.7 # drivers/acpi/utilities/utobject.c 1.15 -> 1.16 # arch/x86_64/kernel/sys_x86_64.c 1.6 -> 1.7 # drivers/input/joystick/amijoy.c 1.9 -> 1.10 # drivers/char/watchdog/Kconfig 1.6 -> 1.7 # arch/x86_64/kernel/head.S 1.8 -> 1.9 # drivers/i2c/i2c-algo-ibm_ocp.c 1.2 -> 1.3 # fs/jfs/resize.c 1.7 -> 1.8 # net/sctp/sm_sideeffect.c 1.18 -> 1.24 # drivers/input/serio/ambakmi.c 1.2 -> 1.3 # fs/ext3/inode.c 1.59 -> 1.60 # arch/sparc64/mm/hugetlbpage.c 1.5 -> 1.6 # drivers/acpi/events/evsci.c 1.10 -> 1.11 # arch/i386/mach-voyager/voyager_thread.c 1.1 -> 1.2 # include/asm-x86_64/acpi.h 1.1 -> 1.2 # drivers/char/agp/amd-k8-agp.c 1.21 -> 1.24 # net/ipv4/netfilter/ip_nat_ftp.c 1.6 -> 1.7 # arch/i386/kernel/timers/timer_tsc.c 1.9 -> 1.11 # arch/i386/oprofile/op_model_ppro.c 1.3 -> 1.4 # net/sunrpc/xprt.c 1.49 -> 1.50 # drivers/acpi/executer/exsystem.c 1.10 -> 1.11 # include/asm-x86_64/unistd.h 1.10 -> 1.11 # drivers/acpi/processor.c 1.32 -> 1.33 # arch/x86_64/kernel/time.c 1.10 -> 1.11 # net/ipv4/tcp_output.c 1.21 -> 1.23 # include/net/ip.h 1.14 -> 1.15 # arch/x86_64/defconfig 1.18 -> 1.19 # arch/i386/kernel/timers/timer_cyclone.c 1.3 -> 1.4 # drivers/char/mxser.c 1.17 -> 1.18 # net/bluetooth/bnep/core.c 1.9 -> 1.10 # drivers/input/joystick/warrior.c 1.9 -> 1.10 # drivers/char/watchdog/sbc60xxwdt.c 1.19 -> 1.20 # drivers/acpi/resources/rsxface.c 1.10 -> 1.11 # fs/ntfs/super.c 1.122 -> 1.123 # arch/x86_64/kernel/signal.c 1.12 -> 1.14 # drivers/char/agp/backend.c 1.66 -> 1.71 # drivers/input/mouse/sermouse.c 1.8 -> 1.9 # include/asm-x86_64/topology.h 1.1 -> 1.2 # drivers/acpi/debug.c 1.4 -> 1.5 # include/asm-x86_64/thread_info.h 1.6 -> 1.7 # arch/sparc/kernel/signal.c 1.19 -> 1.20 # include/asm-sparc/system.h 1.15 -> 1.16 # arch/x86_64/kernel/early_printk.c 1.5 -> 1.6 # arch/m68k/kernel/signal.c 1.10 -> 1.11 # arch/sparc64/oprofile/timer_int.c 1.1 -> 1.3 # drivers/message/i2o/i2o_block.c 1.48 -> 1.49 # drivers/scsi/aacraid/commsup.c 1.1 -> 1.2 # arch/i386/kernel/cpu/cpufreq/longrun.c 1.6 -> 1.8 # include/acpi/acpi_drivers.h 1.13 -> 1.14 # drivers/char/watchdog/Makefile 1.5 -> 1.6 # net/ipv6/ipv6_syms.c 1.4 -> 1.6 # arch/s390x/kernel/linux32.c 1.34 -> 1.35 # drivers/acpi/parser/pswalk.c 1.10 -> 1.11 # include/asm-x86_64/pgtable.h 1.11 -> 1.12 # net/ipv4/xfrm_state.c 1.8 -> 1.9 # include/asm-s390/signal.h 1.4 -> 1.5 # net/ipv4/sysctl_net_ipv4.c 1.7 -> 1.8 # include/net/af_unix.h 1.2 -> 1.3 # include/asm-mips64/signal.h 1.3 -> 1.4 # arch/x86_64/kernel/Makefile 1.15 -> 1.16 # drivers/acpi/executer/exoparg6.c 1.6 -> 1.7 # arch/i386/oprofile/op_model_athlon.c 1.3 -> 1.4 # net/irda/wrapper.c 1.4 -> 1.5 # drivers/net/hamradio/yam.c 1.12 -> 1.13 # arch/x86_64/mm/Makefile 1.7 -> 1.8 # drivers/char/watchdog/alim7101_wdt.c 1.4 -> 1.5 # drivers/acpi/tables/tbxfroot.c 1.15 -> 1.16 # sound/oss/nec_vrc5477.c 1.7 -> 1.8 # arch/x86_64/kernel/aperture.c 1.1 -> 1.2 # drivers/media/video/saa5249.c 1.11 -> 1.12 # drivers/acpi/tables/tbgetall.c 1.7 -> 1.8 # sound/oss/es1371.c 1.18 -> 1.19 # drivers/usb/input/Kconfig 1.3 -> 1.4 # drivers/acpi/battery.c 1.14 -> 1.15 # fs/reiserfs/hashes.c 1.5 -> 1.6 # drivers/usb/input/aiptek.c 1.13 -> 1.15 # drivers/usb/input/fixp-arith.h 1.2 -> 1.3 # net/ipv6/Makefile 1.7 -> 1.8 # arch/x86_64/boot/bootsect.S 1.1 -> 1.2 # drivers/block/DAC960.c 1.51 -> 1.52 # arch/arm/kernel/ecard.c 1.19 -> 1.20 # fs/jfs/namei.c 1.24 -> 1.25 # drivers/char/agp/via-kt400.c 1.6 -> (deleted) # arch/mips/kernel/signal.c 1.10 -> 1.11 # drivers/acpi/numa.c 1.3 -> 1.4 # include/acpi/platform/aclinux.h 1.17 -> 1.18 # arch/x86_64/kernel/vsyscall.c 1.7 -> 1.8 # fs/nfs/inode.c 1.71 -> 1.72 # drivers/scsi/cpqfcTSworker.c 1.13 -> 1.15 # drivers/isdn/hardware/eicon/diva.c 1.2 -> 1.3 # arch/s390/kernel/signal.c 1.17 -> 1.18 # drivers/acpi/pci_bind.c 1.5 -> 1.7 # drivers/acpi/tables/tbutils.c 1.15 -> 1.16 # arch/x86_64/Kconfig 1.13 -> 1.14 # include/linux/kbd_kern.h 1.6 -> 1.7 # kernel/sched.c 1.156 -> 1.158 # include/linux/agp_backend.h 1.23 -> 1.25 # drivers/acpi/executer/exmutex.c 1.9 -> 1.10 # drivers/net/irda/sir_kthread.c 1.3 -> 1.4 # fs/jbd/recovery.c 1.9 -> 1.10 # drivers/char/agp/hp-agp.c 1.13 -> 1.14 # drivers/acpi/parser/psxface.c 1.14 -> 1.15 # drivers/input/keyboard/atkbd.c 1.26 -> 1.28 # net/sctp/adler32.c 1.5 -> 1.6 # drivers/char/watchdog/wdt977.c 1.11 -> 1.12 # include/linux/jbd.h 1.15 -> 1.16 # drivers/acpi/osl.c 1.22 -> 1.24 # scripts/Makefile.build 1.27 -> 1.28 # net/sctp/crc32c.c 1.4 -> 1.5 # drivers/scsi/dpt_i2o.c 1.24 -> 1.25 # sound/pci/ens1370.c 1.24 -> 1.25 # include/asm-cris/signal.h 1.2 -> 1.3 # fs/ufs/dir.c 1.12 -> 1.13 # drivers/acpi/resources/rsmemory.c 1.9 -> 1.10 # drivers/input/gameport/ns558.c 1.14 -> 1.15 # drivers/acpi/dispatcher/dsopcode.c 1.17 -> 1.18 # include/asm-x86_64/system.h 1.10 -> 1.11 # include/net/xfrm.h 1.12 -> 1.13 # fs/sysfs/inode.c 1.80 -> 1.81 # drivers/char/agp/via-agp.c 1.20 -> 1.27 # drivers/acpi/events/evevent.c 1.20 -> 1.21 # drivers/acpi/executer/exmisc.c 1.18 -> 1.19 # drivers/input/joystick/iforce/iforce-usb.c 1.6 -> 1.7 # drivers/acpi/hardware/hwregs.c 1.16 -> 1.17 # drivers/input/touchscreen/h3600_ts_input.c 1.5 -> 1.6 # arch/mips/kernel/irixsig.c 1.4 -> 1.5 # drivers/net/hamradio/scc.c 1.19 -> 1.20 # drivers/char/hvc_console.c 1.11 -> 1.12 # drivers/media/dvb/av7110/av7110.h 1.2 -> 1.3 # drivers/net/Kconfig 1.12 -> 1.13 # drivers/scsi/eata.c 1.26 -> 1.27 # net/irda/qos.c 1.10 -> 1.11 # net/sched/sch_gred.c 1.8 -> 1.9 # arch/i386/kernel/acpi.c 1.19 -> 1.21 arch/i386/kernel/acpi/boot.c (moved) # drivers/acpi/dispatcher/dswstate.c 1.17 -> 1.18 # drivers/acpi/thermal.c 1.19 -> 1.21 # fs/qnx4/inode.c 1.28 -> 1.29 # net/ipv4/netfilter/iptable_mangle.c 1.7 -> 1.8 # kernel/exit.c 1.88 -> 1.92 # arch/i386/oprofile/Makefile 1.3 -> 1.4 # include/asm-x86_64/proto.h 1.6 -> 1.7 # arch/x86_64/Makefile 1.22 -> 1.23 # fs/jbd/commit.c 1.14 -> 1.15 # fs/ufs/ialloc.c 1.10 -> 1.11 # arch/sparc64/kernel/power.c 1.9 -> 1.10 # drivers/acpi/executer/exresop.c 1.18 -> 1.19 # lib/vsprintf.c 1.13 -> 1.14 # drivers/char/specialix.c 1.8 -> 1.9 # include/asm-x86_64/ia32.h 1.9 -> 1.10 # arch/x86_64/kernel/bluesmoke.c 1.5 -> 1.6 # fs/hugetlbfs/inode.c 1.18 -> 1.20 # arch/x86_64/kernel/module.c 1.6 -> 1.7 # arch/sparc64/kernel/ioctl32.c 1.49 -> 1.50 # drivers/input/serio/serport.c 1.9 -> 1.10 # drivers/acpi/tables/tbxface.c 1.14 -> 1.15 # fs/ext3/super.c 1.49 -> 1.51 # fs/cifs/connect.c 1.6 -> 1.7 # arch/ppc64/kernel/signal32.c 1.35 -> 1.36 # arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 1.9 -> 1.10 # drivers/acpi/executer/exoparg1.c 1.19 -> 1.20 # drivers/acpi/namespace/nsdump.c 1.17 -> 1.18 # drivers/input/keyboard/amikbd.c 1.10 -> 1.11 # fs/partitions/check.c 1.94 -> 1.95 # drivers/input/mousedev.c 1.19 -> 1.20 # net/ax25/sysctl_net_ax25.c 1.5 -> 1.6 # arch/sparc/boot/Makefile 1.11 -> 1.12 # include/asm-x86_64/msr.h 1.3 -> 1.4 # arch/i386/mm/hugetlbpage.c 1.29 -> 1.31 # drivers/acpi/namespace/nsload.c 1.16 -> 1.17 # net/irda/irsyms.c 1.11 -> 1.12 # drivers/acpi/dispatcher/dsinit.c 1.6 -> 1.7 # include/asm-x86_64/segment.h 1.5 -> 1.6 # drivers/char/misc.c 1.13 -> 1.14 # arch/sparc64/kernel/irq.c 1.23 -> 1.24 # drivers/usb/input/usbmouse.c 1.21 -> 1.22 # drivers/char/moxa.c 1.13 -> 1.14 # fs/lockd/clntlock.c 1.6 -> 1.7 # drivers/char/watchdog/wafer5823wdt.c 1.3 -> 1.4 # drivers/acpi/executer/excreate.c 1.15 -> 1.16 # arch/i386/oprofile/nmi_int.c 1.5 -> 1.7 # arch/x86_64/mm/ioremap.c 1.6 -> 1.7 # net/sctp/ulpqueue.c 1.6 -> 1.8 # fs/ext3/xattr.h 1.2 -> 1.3 # drivers/oprofile/cpu_buffer.h 1.2 -> 1.3 # drivers/acpi/Makefile 1.29 -> 1.33 # drivers/acpi/executer/exstorob.c 1.16 -> 1.17 # drivers/acpi/utilities/utmath.c 1.6 -> 1.7 # fs/afs/kafsasyncd.c 1.3 -> 1.4 # arch/i386/kernel/timers/timer.c 1.4 -> 1.5 # drivers/usb/input/usbkbd.c 1.24 -> 1.25 # include/asm-x86_64/vsyscall.h 1.3 -> 1.4 # drivers/acpi/namespace/nsaccess.c 1.15 -> 1.16 # drivers/acpi/namespace/nssearch.c 1.16 -> 1.17 # include/asm-x86_64/spinlock.h 1.6 -> 1.7 # drivers/block/cciss.c 1.66 -> 1.67 # drivers/isdn/hardware/eicon/i4lididrv.c 1.4 -> 1.5 # drivers/net/wan/comx-hw-mixcom.c 1.7 -> 1.8 # arch/x86_64/ia32/ia32_signal.c 1.9 -> 1.10 # arch/parisc/kernel/signal.c 1.7 -> 1.8 # drivers/acpi/dispatcher/dswexec.c 1.16 -> 1.17 # include/asm-x86_64/processor.h 1.10 -> 1.11 # arch/ppc/kernel/signal.c 1.20 -> 1.21 # net/sctp/sm_statetable.c 1.11 -> 1.15 # net/ipv4/ip_output.c 1.26 -> 1.27 # drivers/acpi/namespace/nsxfeval.c 1.8 -> 1.9 # kernel/workqueue.c 1.5 -> 1.6 # drivers/serial/sunzilog.c 1.21 -> 1.24 # include/net/sctp/command.h 1.6 -> 1.8 # arch/sparc64/kernel/init_task.c 1.7 -> 1.8 # drivers/acpi/dispatcher/dswscope.c 1.11 -> 1.12 # drivers/scsi/imm.c 1.16 -> 1.17 # drivers/acpi/resources/rsirq.c 1.12 -> 1.13 # sound/oss/es1370.c 1.18 -> 1.19 # include/net/sctp/structs.h 1.24 -> 1.33 # drivers/acpi/utils.c 1.6 -> 1.7 # fs/nfs/nfs4xdr.c 1.13 -> 1.14 # drivers/acpi/Kconfig 1.4 -> 1.5 # net/sctp/Makefile 1.5 -> 1.6 # fs/proc/generic.c 1.19 -> 1.20 # drivers/ide/pci/amd74xx.c 1.11 -> 1.12 # drivers/acpi/namespace/nswalk.c 1.10 -> 1.11 # arch/v850/kernel/signal.c 1.6 -> 1.7 # drivers/acpi/resources/rslist.c 1.11 -> 1.12 # arch/i386/kernel/apic.c 1.30 -> 1.31 # drivers/macintosh/adb.c 1.15 -> 1.16 # drivers/char/nwflash.c 1.10 -> 1.11 # net/sctp/primitive.c 1.7 -> 1.8 # kernel/ptrace.c 1.25 -> 1.26 # arch/x86_64/kernel/smpboot.c 1.11 -> 1.12 # drivers/acpi/namespace/nsnames.c 1.15 -> 1.16 # fs/nfs/nfs3xdr.c 1.24 -> 1.25 # arch/ppc64/oprofile/timer_int.c 1.1 -> 1.3 # drivers/pcmcia/i82092.c 1.9 -> 1.10 # drivers/net/wireless/orinoco.c 1.18 -> 1.19 # drivers/char/agp/amd-k7-agp.c 1.17 -> 1.18 # drivers/macintosh/adbhid.c 1.12 -> 1.13 # mm/pdflush.c 1.15 -> 1.16 # net/core/rtnetlink.c 1.8 -> 1.9 # net/ipv4/netfilter/ip_queue.c 1.9 -> 1.10 # include/asm-x86_64/desc.h 1.6 -> 1.7 # fs/udf/inode.c 1.30 -> 1.31 # net/sctp/socket.c 1.29 -> 1.36 # include/net/irda/irda_device.h 1.3 -> 1.4 # arch/sh/kernel/signal.c 1.9 -> 1.10 # (new) -> 1.1 include/asm-x86_64/numa.h # (new) -> 1.2 arch/i386/kernel/cpu/cpufreq/powernow-k7.c # (new) -> 1.1 Documentation/sound/rme96xx # (new) -> 1.2 arch/i386/oprofile/op_model_p4.c # (new) -> 1.1 drivers/input/misc/98spkr.c # (new) -> 1.2 drivers/char/watchdog/cpu5wdt.c # (new) -> 1.1 include/asm-x86_64/numnodes.h # (new) -> 1.1 arch/i386/kernel/acpi/sleep.c # (new) -> 1.1 arch/i386/kernel/acpi/Makefile # (new) -> 1.1 include/asm-x86_64/mmsegment.h # (new) -> 1.1 drivers/usb/input/hid-tmff.c # (new) -> 1.2 drivers/char/agp/alpha-agp.c # (new) -> 1.3 drivers/acpi/sleep/proc.c # (new) -> 1.2 drivers/acpi/sleep/sleep.h # (new) -> 1.1 net/ipv6/xfrm_policy.c # (new) -> 1.4 drivers/acpi/sleep/Makefile # (new) -> 1.1 net/sctp/ssnmap.c # (new) -> 1.1 arch/x86_64/boot/mtools.conf.in # (new) -> 1.1 arch/x86_64/kernel/wakeup.S # (new) -> 1.1 arch/x86_64/mm/numa.c # (new) -> 1.1 include/asm-x86_64/mmzone.h # (new) -> 1.1 arch/i386/kernel/cpu/cpufreq/powernow-k7.h # (new) -> 1.1 drivers/acpi/sleep/poweroff.c # (new) -> 1.1 arch/x86_64/mm/k8topology.c # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/02/10 torvalds@home.transmeta.com 1.989.2.3 # Linux v2.5.60 # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.1 # [AGPGART] Fix up lots of 'comparison between signed and unsigned' warnings # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.2 # [AGPGART] Fix same logic bug in KT400 mode determination. # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.3 # [AGPGART] Don't oops when deregistering failed to init agp modules. # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.4 # [AGPGART] Handle the "KT400 in disguise as a KT266" case. # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.5 # [AGPGART] Handle failure during initialisation more gracefully. # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.6 # [AGPGART] Add ident for VIA KT400 in disguise as a KT266 # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.7 # [AGPGART] More failure path sanity checking. # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.8 # [AGPGART] VIA KT400 Aperture size is 12 bit in AGP3 mode. # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.9 # [AGPGART] kt400's enable routine can't be __init # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.10 # [AGPGART] alpha agp infrastructure # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.11 # [AGPGART] First step towards multiple AGP buses. # # The AGP3 spec allows for >1 AGP bus. This is the first of several patches # from Jeff Hartmann towards a context-using agp_bridge, by replacing # agp_bridge.foo accesses with agp_bridge->foo accesses. For now, there # should be no functional differences, as there is still only a single # agp_bridge_data struct defined. # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.12 # [AGPGART] Add extra VIA GART IDs. # # Based upon information from VIA, this also adds a bunch of placeholder # entries that will get filled in over time when they have been proven # to work with the code with no extra modification. # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.13 # [AGPGART] Additional VIA ids. # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.14 # [AGPGART] Fix missed agp_bridge conversion that caused oops. # -------------------------------------------- # 03/02/10 davej@codemonkey.org.uk 1.989.3.15 # [AGPGART] Merge VIA KT400 AGP3 support into main via-agp module. # # This removes lots of annoying problems trying to prevent both modules # from being loaded, and also shares quite a bit of code. # CONFIG_AGP3 will disable AGP3 mode operation of KT400s. # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.16 # [AGPGART] Remove pointless enums from VIA GART driver. # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.3.17 # [AGPGART] Enable support for VIA PLE133 chipset # -------------------------------------------- # 03/02/10 davej@tetrachloride.(none) 1.989.2.4 # Merge tetrachloride.(none):/mnt/stuff/kernel/2.5/bk-linus # into tetrachloride.(none):/mnt/stuff/kernel/2.5/agpgart-respin # -------------------------------------------- # 03/02/10 agrover@groveronline.com 1.989.4.1 # Merge groveronline.com:/root/bk/linux-2.5 # into groveronline.com:/root/bk/linux-acpi # -------------------------------------------- # 03/02/10 sri@us.ibm.com 1.989.5.1 # Merge us.ibm.com:/home/sridhar/BK/linux-2.5.60 # into us.ibm.com:/home/sridhar/BK/lksctp-2.5.60 # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.2.5 # [PATCH] Fix synchronous writers to wait properly for the result # # Mikulas Patocka points out a bug in # ll_rw_block() usage. # # Typical usage is: # # mark_buffer_dirty(bh); # ll_rw_block(WRITE, 1, &bh); # wait_on_buffer(bh); # # the problem is that if the buffer was locked on entry to this code sequence # (due to in-progress I/O), ll_rw_block() will not wait, and start new I/O. So # this code will wait on the _old_ I/O, and will then continue execution, # leaving the buffer dirty. # # It turns out that all callers were only writing one buffer, and they were all # waiting on that writeout. So I added a new sync_dirty_buffer() function: # # void sync_dirty_buffer(struct buffer_head *bh) # { # lock_buffer(bh); # if (test_clear_buffer_dirty(bh)) { # get_bh(bh); # bh->b_end_io = end_buffer_io_sync; # submit_bh(WRITE, bh); # } else { # unlock_buffer(bh); # } # } # # which allowed a fair amount of code to be removed, while adding the desired # data-integrity guarantees. # # UFS has its own wrappers around ll_rw_block() which got in the way, so this # operation was open-coded in that case. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.2.6 # [PATCH] ncpfs compile fix # # Patch from Joel Becker # # The task_struct->sig -> task_struct->signal bits. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.2.7 # [PATCH] de4x5 compile fix # # Move the definition of version[] down to where __initdata has been defined. # -------------------------------------------- # 03/02/10 rddunlap@osdl.org 1.989.2.8 # [PATCH] checker bounds/limits fixes # # Part of the bounds checking bugs found by the Stanford checker. # # The 4 fixes below have been acked by their maintainers. # -------------------------------------------- # 03/02/10 kai@tp1.ruhr-uni-bochum.de 1.989.2.9 # kbuild: sed compatibility fixes # # Some versions of sed seem to think \w, as in word, doesn't include # digits, which breaks the build with CONFIG_MODVERSIONS. So we # just use the more compatible []*. # -------------------------------------------- # 03/02/10 kai@tp1.ruhr-uni-bochum.de 1.989.2.10 # kbuild: Handle the "no modules" case # # When the user selects CONFIG_MODVERSIONS but doesn't build anything # modular, the post-processing step does nothing (right, as there is # nothing to be done), but it also gave an error, which it shouldn't. # -------------------------------------------- # 03/02/10 kai@tp1.ruhr-uni-bochum.de 1.989.2.11 # kbuild: cosmetics # # From ram : # # > Appended below is a small patch to the top-level makefile; it # > -- replaces a call to $(shell/echo/sed) with $(subst) and adds a # > comment # > -- fixes some typos. # -------------------------------------------- # 03/02/10 kai@tp1.ruhr-uni-bochum.de 1.989.2.12 # kbuild: Customflags for cmd_objcopy # # From Konrad Eisele: # # > like with cmd_ld in scripts/Makefile.lib having possibility to add # > customflags with cmd_objcopy would be nice. When building a # > ROMKernel I'd like to use: # > OBJCOPYFLAGS_rompiggydata := --remove-section=.text # > OBJCOPYFLAGS_$(MODEL)piggytext := --only-section=.text # -------------------------------------------- # 03/02/10 kai@tp1.ruhr-uni-bochum.de 1.989.2.13 # kbuild: Allow for ',$ in commands # # Quote ',$ before passing them to the shell - ' must be escaped for # echo, $$ will be converted to $ by make. # # This allows to use e.g. perl commands in the build with support # from the generic $(call if_changed,...). # # by Konrad Eisele # -------------------------------------------- # 03/02/11 davej@codemonkey.org.uk 1.989.6.1 # [WATCHDOG] PNP API conversion. # Done by Adam Belay. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.1 # [PATCH] uninline get_jiffies_64() for 32-bit architectures # # uninline get_jiffies_64() for 32-bit architectures # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.2 # [PATCH] use per-cpu data for ia32 profiler # # Patch from Ravikiran G Thirumalai # # Converts the ia32 kernel profiler to use use the percpu area infrastructure. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.3 # [PATCH] NUMAQ io_apic programming fix # # Patch from William Lee Irwin III # # Don't touch IO-APIC physid's on NUMA-Q. The BIOS pre-programs them. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.4 # [PATCH] ext3: Remove journal_try_start() # # journal_try_start() is a function which nonblockingly attempts to open a JBD # transaction handle. It was added a long time ago when there were concerns # that ext3_writepage() could block kswapd for too long. # # It was never clearly necessary. # # So the patch throws it all away and just calls the blocking journal_start() # from ext3_writepage(). # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.5 # [PATCH] DAC960 Stanford Checker fix # # Patch from Dave Olien # # This was found by the Standford Checker. # The LogicalDeviceNumber bad range test was changed from > to >= # I also replaced a couple of panic() calls with error messages, # since panic-ing seemed a little extreme. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.6 # [PATCH] Add David Olien MAINTAINERs for DAC960 # # (I asked Dave for this...) # # From: Dave Olien # # Add me as maintainer for DAC960 driver. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.7 # [PATCH] nforce2 IDE support for the amd74xx driver # # Patch from James Curbo # # The amd74xx IDE driver in 2.5.59 has support for the nforce IDE controller, # but not explicitly for the nforce2 IDE controller (which has a different PCI # ID, which is in the kernel already). I'm not sure if the nforce and nforce2 # controllers are identical, but I made a small patch that made the amd74xx # driver recognize the nforce2 IDE, and it boots for me, seems to work fine, as # my drives were tuned to their highest transfer rate automatically (udma5). # # I don't know if this patch is proper or correct, but it Works for Me [tm]. # Patch is attached. # # Vojtech has acked this change. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.8 # [PATCH] hugetlbpage MAP_FIXED fix # # We need to validate that the address and length of a MAP_FIXED request are # suitable for hugetlb pages. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.9 # [PATCH] remove unneeded test from radix_tree_extend() # # Patch from: Szabolcs Berecz # # No need to check root->rnode in the loop. In the loop it remains nonzero. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.10 # [PATCH] ext3 commenting cleanup # # Redo the (strange) layout of some of Roger's comments. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.11 # [PATCH] Don't run unlock_super() in ext3_fill_super() # # A very long time ago ext3_fill_super() was beng called under the VFS's # lock_super(), and it had to drop that lock for deadlock avoidance reasons. # # But the VFS was later changed to not take lock_super() across ->fill_super(), # so we're upping a non-downed semaphore. # # Just take it out. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.12 # [PATCH] remove the buffer_head mempool # # mempools have the wrong semantics for use by buffer_heads. The problem # scenario: # # - Process A calls mempool_alloc(), asking for a buffer_head. # # - While process A sleeps, process B frees up a ton of memory. # # That's it. There is no longer any memory pressure, so nobody frees any # buffer_heads, so process A does not get woken up. I managed to trigger this # in some testing recently. # # One approach would be to use a schedule_timeout(2) in mempool_alloc(). # # Anyway, the importance of buffer_head allocation was lessened when swapout # stopped using them, so let's just drop the mempool out of it for now. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.13 # [PATCH] fix current->user->processes leak # # Patch from: Eric Lammerts # # Every time you do a loop mount, a kernel thread is started (those # processes are called "loop0", "loop1", etc.). The problem is that when # it starts, it's counted as one of your processes. Then, it's # changed to be a root-owned process without correcting that count. # # Patch below fixes the problem. It moves the bookkeeping of changing # current->user to a new function switch_uid() (which is now also used # by exec_usermodehelper() in kmod.c). The patch is tested. # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.14 # [PATCH] 3c509 compile fix # # Patch from Marc Zyngier # # Fix compilation of 3c509.c # -------------------------------------------- # 03/02/10 akpm@digeo.com 1.989.7.15 # [PATCH] Get 3c59x to compile on non-PCI systems # # Patch from Marc Zyngier # # My previous round of EISA hacking left the 3c59x driver unable to # compile on non-PCI systems (that is, EISA only...). # # This small patch fixes it. # -------------------------------------------- # 03/02/11 rusty@rustcorp.com.au 1.989.1.5 # [AF_UNIX] Cleanup forall_unix_sockets. # -------------------------------------------- # 03/02/11 rusty@rustcorp.com.au 1.989.1.6 # [X25]: Fix improper | precendence, pointed out by Joern Engel. # -------------------------------------------- # 03/02/11 rusty@rustcorp.com.au 1.989.1.7 # [ECONET]: Add comment to point out a bug spotted by Joern Engel. # -------------------------------------------- # 03/02/11 rob@osinvestor.com 1.993 # [SPARC]: HEAD --> HEAD_Y # -------------------------------------------- # 03/02/11 rob@osinvestor.com 1.994 # [SPARC]: ADd init_sighand. # -------------------------------------------- # 03/02/11 davem@nuts.ninka.net 1.995 # [TULIP DE4X5]: Cannot use initdata before including linux/init.h # -------------------------------------------- # 03/02/11 davem@nuts.ninka.net 1.989.1.8 # [TCP]: Do not bump backoff too high during 0-window probes. # -------------------------------------------- # 03/02/11 davem@nuts.ninka.net 1.996 # [SIGNAL]: Allow more platforms to use generic get_signal_to_deliver. # # The few platforms that cannot use the generic # get_signal_to_deliver implementation cannot do # so because they do special things for ptraced # children. This can be easily avoided and thus # all of the signal handling code duplication can # be eliminated. # # This is the first part, which adds a platform hook # right before the parent of the ptraced child is woken. # Data can be passed in via a cookie argument. # # The next part will be dealing with platforms # that need to muck with breakpoints in the child # in this same code block. # -------------------------------------------- # 03/02/11 davem@nuts.ninka.net 1.997 # Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5 # into nuts.ninka.net:/home/davem/src/BK/sparc-2.5 # -------------------------------------------- # 03/02/11 randy.dunlap@verizon.net 1.989.7.16 # [PATCH] ftape divide-by-zero found by Stanford Checker # # This fixes a potential divide-by-zero found by the Stanford Checker. # -------------------------------------------- # 03/02/11 randy.dunlap@verizon.net 1.989.7.17 # [PATCH] bounds/limits fixes (Stanford Checker) # # This fixes several trivial bounds/limits errors that were pointed out by # the Stanford Checker. # -------------------------------------------- # 03/02/11 akpm@digeo.com 1.989.7.18 # [PATCH] sched_init enables interrupts too early # # wake_up_forked_process() unconditionally enables interrupts. It is called # from sched_init(). Enabling interrupts that early makes Anton's ppc64 # machine lock up. # -------------------------------------------- # 03/02/11 Andries.Brouwer@cwi.nl 1.989.7.19 # [PATCH] signal error return fix # -------------------------------------------- # 03/02/11 Andries.Brouwer@cwi.nl 1.989.7.20 # [PATCH] genhd device unregistration fix # -------------------------------------------- # 03/02/11 torvalds@home.transmeta.com 1.989.7.21 # If we set TIF_SIGPENDING for SIGCONT, we have to wake up any sleeping # tasks (even if we don't otherwise need to wake anything up), since # otherwise later signals would see that signals are already pending and # wouldn't cause wakeups. # -------------------------------------------- # 03/02/11 torvalds@home.transmeta.com 1.989.6.2 # Merge bk://linux-dj.bkbits.net/watchdog # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/11 levon@movementarian.org 1.989.6.3 # [PATCH] oprofile: Pentium IV support # # The below patch implements a P4 driver for OProfile, mostly written # by Graydon Hoare. # -------------------------------------------- # 03/02/11 levon@movementarian.org 1.989.6.4 # [PATCH] oprofile: CPU type as string # # This patch updates the horrible enum for the logical CPU type with a # string instead. # -------------------------------------------- # 03/02/11 levon@movementarian.org 1.989.6.5 # [PATCH] oprofile: fix oprofilefs integer files base # # This patch allows the oprofilefs files to take entry in any base # instead of just base 10 # -------------------------------------------- # 03/02/11 levon@movementarian.org 1.989.6.6 # [PATCH] oprofile: kernel/user addresses fix # # This patch replaces the assumption that > PAGE_OFFSET == kernel address # with testing for user_mode(regs) and inserting switch codes instead. # -------------------------------------------- # 03/02/11 kai@tp1.ruhr-uni-bochum.de 1.989.2.14 # kbuild: scripts/fixdep.c doesn't close files when finished # # From Chris Wedgwood: # # > fixdep doesn't close files when finished with them... normally this # > doesn't matter unless you have strict ulimits in place. # > # > Trivial fix is: # -------------------------------------------- # 03/02/11 agrover@groveronline.com 1.989.8.1 # Merge groveronline.com:/root/bk/linux-2.5 # into groveronline.com:/root/bk/linux-acpi # -------------------------------------------- # 03/02/11 torvalds@penguin.transmeta.com 1.989.6.7 # Report shared pending signals in /proc//status # # Patch from Roland McGrath. # -------------------------------------------- # 03/02/11 torvalds@penguin.transmeta.com 1.989.6.8 # Sanitize kernel daemon signal handling and process naming. # # Add a name argument to daemonize() (va_arg) to avoid all the # kernel threads having to duplicate the name setting over and # over again. # # Make daemonize() disable all signals by default, and add a # "allow_signal()" function to let daemons say they explicitly # want to support a signal. # # Make flush_signal() take the signal lock, so that callers do # not need to. # -------------------------------------------- # 03/02/11 kai@tp1.ruhr-uni-bochum.de 1.989.2.15 # Merge tp1.ruhr-uni-bochum.de:/scratch/kai/kernel/v2.5/linux-2.5 # into tp1.ruhr-uni-bochum.de:/scratch/kai/kernel/v2.5/linux-2.5.make # -------------------------------------------- # 03/02/11 torvalds@penguin.transmeta.com 1.989.6.9 # Add macthing 'va_end()' to the 'va_start()' in daemonize(). # # Not that it makes any difference on x86, but there may be # architectures that actually need it. # -------------------------------------------- # 03/02/11 davem@kernel.bkbits.net 1.998 # Merge davem@nuts.ninka.net:/home/davem/src/BK/sparc-2.5 # into kernel.bkbits.net:/home/davem/sparc-2.5 # -------------------------------------------- # 03/02/11 davem@kernel.bkbits.net 1.989.1.9 # Merge davem@nuts.ninka.net:/home/davem/src/BK/net-2.5 # into kernel.bkbits.net:/home/davem/net-2.5 # -------------------------------------------- # 03/02/11 Andries.Brouwer@cwi.nl 1.989.6.10 # [PATCH] nfs fix # # nfs must not use MINORBITS - that fails with 32-bit dev_t # -------------------------------------------- # 03/02/11 torvalds@home.transmeta.com 1.989.2.16 # Merge http://linux-isdn.bkbits.net/linux-2.5.make # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/11 torvalds@home.transmeta.com 1.989.1.10 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/11 torvalds@home.transmeta.com 1.999 # Merge bk://kernel.bkbits.net/davem/sparc-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/12 davej@codemonkey.org.uk 1.989.9.1 # [AGPGART] Remove unneeded AMD8151 shadowing in the K8 GART driver. # The 8151 GART registers aren't actually necessary to poke, and are # only there for 'legacy reasons' aparently. # -------------------------------------------- # 03/02/12 davej@codemonkey.org.uk 1.989.9.2 # [AGPGART] Cache K8 northbridges pci_devs instead of scanning whole PCI bus # -------------------------------------------- # 03/02/11 sfr@canb.auug.org.au 1.1000 # [PATCH] apm daemonize # # Since daemonize now blocks all signals, this simplification is trivially # correct. # -------------------------------------------- # 03/02/11 ak@muc.de 1.1001 # [PATCH] x86-64 merge # # This brings the x86-64 port uptodate in 2.5.60. Unfortunately I cannot # test too much because i constantly get deadlocks in exit/wait in initscripts # on SMP bootup. The kernel seems to still lose a lot of SIGCHLD. 2.5.59/SMP # had the same problem. Uniprocessor and SMP kernel on UP seems to work. # # This patch only touches x86-64 specific files. It requires a few simple # changes to arch independent files that I will send separately. # # - Fixed a lot of obsolete/misleading configure help texts. # - Remove old bootblock disk loader and support fdimage target for syslinux # instead (H. Peter Anvin) # - Fix potential fpu signal restore problem on 32bit emulation. # - Merge with 2.5.60 i386 (hugetlbfs, acpi etc.) # - Some fixes for local apic disabled modus. # - Beginngs of S3 ACPI wakeup from real-mode (not working yet, don't use) # - Beginnings of NUMA/CONFIG_DISCONTIGMEM support for AMD K8 (work in progress, # port from 2.4): clean up memory mapping at bootup, generalize bootmem etc. # - Fix 64bit GS base reload problem and reenable (Karsten Keil) # - Fix race with vmalloc accesses from interrupt handlers disturbing page fault/ # similar race for the debug handler (thanks to Andrew Morton) # - Merge cpu access primitives with i386 # - Revert to private module list for now because putting modules # nto vmlist triggered too many problems. # - Some cleanups, removal of unneeded code. # - Let early __get_free_pages see consistent pda # - Preempt disabled for now because it is too broken right now # - Signal handler fixes # - Fix do_gettimeofday to be completely lockless and reenable vsyscalls # - Optimize context switch path a bit (should be ported to i386) # - Get thread_info via stack for better code # - Don't leak pmd pages # - Clean up hardcoded task stack sizes. # -------------------------------------------- # 03/02/11 sfr@canb.auug.org.au 1.999.1.1 # [SPARC64]: sigprocmask/sigpending compat layer conversion. # -------------------------------------------- # 03/02/11 sfr@canb.auug.org.au 1.1002 # [PATCH] parisc compatibility layer update # # At Linux Conf AU, Willy asked me to send any further parisc compatibility # changes directly to you, so this is what I have outstanding. Basically, # it is just the uses of compat_sigset_t that seemed to have been missed in # the previous merges. # -------------------------------------------- # 03/02/11 sfr@canb.auug.org.au 1.1003 # [PATCH] x86_64 compatibility layer update # # Andi has asked that I send these straight forward compatibility patches # to you and he will fix up any merge problems later. These are the # outstanding patches for x86_64 against 2.5.60. # -------------------------------------------- # 03/02/11 ahaas@airmail.net 1.999.2.1 # [PATCH]: C99 initializers for net/ipv6/sysctl_net_ipv6.c # -------------------------------------------- # 03/02/11 ahaas@airmail.net 1.999.2.2 # [PATCH]: C99 initializers for net/core/sysctl_net_core.c # -------------------------------------------- # 03/02/11 ahaas@airmail.net 1.999.2.3 # [PATCH]: C99 initializers for net/ipv4/sysctl_net_ipv4.c # -------------------------------------------- # 03/02/11 davem@nuts.ninka.net 1.999.2.4 # Merge http://linux-lksctp.bkbits.net/lksctp-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/02/12 vojtech@suse.cz 1.1004 # input: Update AT+PS/2 mouse and keyboard drivers: # - Fix a possible deadlock with 0xfe resend command (atkbd) # - Make ->ack variables volatile (they're updated from irq) # - Fix the GETID one/two byte command to avoid any races # - Fix Logitech PS2++ extended packet detection # - Use RESET_BAT on reboot to make notebooks happy # -------------------------------------------- # 03/02/12 jsimmons@maxwell.earthlink.net 1.1005 # input: Remove include/linux/pc_keyb.h and old PS/2 code # from drivers/char/misc.c # -------------------------------------------- # 03/02/12 vojtech@suse.cz 1.1006 # input: Only generate rawmode warnings if the event we cannot handle # is a real key and not just a button or something. # -------------------------------------------- # 03/02/12 zaitcev@redhat.com 1.1007 # input: Let newly connected keyboards pickup the LED state. # -------------------------------------------- # 03/02/12 vojtech@suse.cz 1.1008 # input: Get rid of the kbd_pt_regs variable, and instead pass the # value all the way from an interrupt handler to keyboard.c # that can display it. # -------------------------------------------- # 03/02/12 tomita@cinet.co.jp 1.1009 # input: Support for NEC PC-9800 beeper and support for Kana Lock LED. # -------------------------------------------- # 03/02/12 vojtech@suse.cz 1.1010 # input: HID update # - Fix a bad #define for HID_QUIRK_BADPAD # - Set absfuzz and absflat for joysticks/gamepads only # - Add TangTop quirk # -------------------------------------------- # 03/02/12 vojtech@suse.cz 1.1011 # input.c: joydev/mousedev update # - relax requirements on devices, joydev now allows joysticks # without buttons to work with throttles and pedals, mousedev # allows a separate mouse wheel # - remove a stray semicolon in joydev # -------------------------------------------- # 03/02/12 vojtech@suse.cz 1.1012 # input: Give preferential treatment to gameport at 0x201, and use # the odd addresses for access. # -------------------------------------------- # 03/02/12 zinx@epicsol.org 1.1013 # input: Add support for ThrustMaster ForceFeedback USB HID devices. # -------------------------------------------- # 03/02/12 will@sowerbutts.com 1.1014 # input: PowerMate driver update # - work around an undocumented firmware bug # - fix handling of LED brightness # -------------------------------------------- # 03/02/12 vojtech@suse.cz 1.1015 # input: Resurrect usb_set_report for Aiptek and Wacom tablets. # -------------------------------------------- # 03/02/12 vojtech@suse.cz 1.1016 # input: Add two new serio type #defines # -------------------------------------------- # 03/02/12 vojtech@suse.cz 1.1017 # input: sunkbd.c - fix reading beyond end of keycode array. # -------------------------------------------- # 03/02/12 szepe@pinerecords.com 1.1003.1.1 # [PATCH] export allow_signal() # # Export allow_signal(). It's needed by lockd, sunrpc and other modules. # -------------------------------------------- # 03/02/12 ink@jurassic.park.msu.ru 1.1003.1.2 # [PATCH] alpha: Add missing sighand bits # -------------------------------------------- # 03/02/12 torvalds@penguin.transmeta.com 1.1003.1.3 # Don't wake up processes unnecessarily for ignored signals # -------------------------------------------- # 03/02/12 pavel@ucw.cz 1.1003.1.4 # [PATCH] Fix stack handling in acpi_wakeup.S # # This fixes stack handling in acpi_wakeup.S, and makes stack smaller so # that wakeup code actually fits inside memory allocated for it. Plus # someone renamed .L1432 to something meaningful. # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.1 # sleep: fix /proc/acpi/sleep write handling. # # - Prevent users from screwing themselves by removing support for entering # S5 from the proc file. S5 is 'soft-off' and the state the system enters # when powering down. It needs to be preceded by a proper shutdown sequence # and should not be triggered manually. # - Fix a potential unchecked array reference using the written value as the # index. # -------------------------------------------- # 03/02/12 davej@codemonkey.org.uk 1.1003.3.1 # [CPUFREQ] Properly set memory allocated by x86 cpufreq drivers to zero. # From Dominik Brodowski # -------------------------------------------- # 03/02/12 davej@codemonkey.org.uk 1.1003.3.2 # [CPUFREQ] add support for cpufreq governors. # More bits from Dominik. # # Most cpufreq drivers (in fact, all except one, longrun) or even most # cpu frequency scaling algorithms only offer the CPU to be set to one # frequency. In order to offer dynamic frequency scaling, the cpufreq # core must be able to tell these drivers of a "target frequency". So # these specific drivers will be transformed to offer a "->target" # call instead of the existing "->setpolicy" call. For "longrun", all # stays the same, though. # # How to decide what frequency within the CPUfreq policy should be used? # That's done using "cpufreq governors". Two are already in this patch # -- they're the already existing "powersave" and "performance" which # set the frequency statically to the lowest or highest frequency, # respectively. At least two more such governors will be ready for # addition in the near future, but likely many more as there are various # different theories and models about dynamic frequency scaling # around. Using such a generic interface as cpufreq offers to scaling # governors, these can be tested extensively, and the best one can be # selected for each specific use. # # Basically, it's the following flow graph: # # CPU can be set to switch independetly | CPU can only be set # within specific "limits" | to specific frequencies # # "CPUfreq policy" # consists of frequency limits (policy->{min,max}) # and CPUfreq governor to be used # / \ # / \ # / the cpufreq governor decides # / (dynamically or statically) # / what target_freq to set within # / the limits of policy->{min,max} # / \ # / \ # Using the ->setpolicy call, Using the ->target call, # the limits and the the frequency closest # "policy" is set. to target_freq is set. # It is assured that it # is within policy->{min,max} # # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.2 # acpi sleep: move sleep support into own subdirectory. # -------------------------------------------- # 03/02/12 davej@codemonkey.org.uk 1.1003.3.3 # [CPUFREQ] fix longrun min/max confusion. # -------------------------------------------- # 03/02/12 torvalds@penguin.transmeta.com 1.1003.1.5 # Merge bk://linux-dj.bkbits.net/cpufreq # into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.6 # [PATCH] genhd warnings fix # # I have a whole bunch of silly compile warning fixes here, arising from # building the kernel for a 64-bit target. Some are trivial, some are genuine # printk bugs. # # assuming dev_t is unsigned generates a warning on ppc64. Cast it. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.7 # [PATCH] kill warning in vmscan.c # # Make the "duplicate const" warning go away. Arguably a compiler bug... # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.8 # [PATCH] kill some ppc64 warnings in knfsd # # Don't assume that dev_t is an unsigned. Cast it. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.9 # [PATCH] fix ppc64 wanings in fs/partitions/check.c # # cast dev_t when printing # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.10 # [PATCH] fix ppc64 nfs warning # # Don't assume that dev_t is unsigned. Cast it. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.11 # [PATCH] fs/reiserfs/hashes.c warning fix # # printk needs kernel.h # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.12 # [PATCH] fix drivers/scsi/st.c warning # # kdev_t.value is not an int. Code looks fishy. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.13 # [PATCH] provide uniproc write_trylock() # # Patch from Oleg Drokin , Nikita Danilov # # There is no uniprocessor definition of _raw_write_trylock(), so # write_trylock() doesn't work on UP. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.14 # [PATCH] disassociate_ctty SMP fix # # Patch from Rik van Riel # # the following patch, against today's BK tree, fixes a small # SMP race in disassociate_ctty. This function gets called # from do_exit, without the BKL held. # # However, it sets the *tty variable before grabbing the bkl, # then makes decisions on what the variable was set to before # the lock was grabbed, despite the fact that another process # could modify its ->tty pointer in this same function. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.15 # [PATCH] make the adaptec driver compile # # make the adaptec driver compile # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.16 # [PATCH] sunrpc dcache cleanup # # Patch from Dipankar Sarma # # All fs should be using dcache APIs to manipulate dcache hash lists. This is # in line with the dcache cleanup patch (dcache_rcu-1) from Maneesh that Linus # accepted. This seems like a reasonable cleanup. One change though, we don't # need to grab dcache_lock while deleting dentries from the private list and # __d_drop() should suffice here. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.17 # [PATCH] jiffies wrap fixes # # Patch from Tim Schmielau # # Converts many open-coded jiffy comparisons to use time_after/before/etc. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.18 # [PATCH] EATA driver fix # # This driver is calling down into scsi_register with local interrupts # disabled. scsi_register performs blocking allocations, starts kernel # threads, etc. slab debugging gets offended by someone performing blocking # operations with local interrupts disabled. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.19 # [PATCH] make drivers/net/arlan.c compile again # # Someone typed `config' when they meant `conf'. # # Also fix a function-defined-but-not-used warning. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.20 # [PATCH] Allow summit kernels to boot on normal systems # # Patch from: john stultz # # This patch simply fixes the summit subarch to allow summit kernels to # boot on normal systems. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.21 # [PATCH] Make drivers/media/video/saa7110.c compile # # Patch from: Frank Davis # # The following patch addresses bugzilla bug # 341. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.22 # [PATCH] drivers/media/video/saa5249.c compile fix # # Patch from: Frank Davis # # The following addresses bugzilla bug # 340. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.23 # [PATCH] fix fadvise64() return type # # Patch from: David Mosberger # # Please remember to declare the return-type of syscall stubs as "long". # On 64-bit platforms, it's generally necessary to ensure that the # entire 64-bit return value is valid (and can be checked against # negative values). # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.24 # [PATCH] OSS CS4232 locking fixes # # Patch from: Peter Waechtler # # Addresses BUGME bug #331. "OSS CS4232 nasty spinlock printks on boot" # # The locking in some OSS modules is really lousy. # Because save_flags/cli/restore_flags could be used recursivly - the # programmers pushed the locking too far the lower level. # # Because on ISA cards the register sets are usually multiplexed # you had to write to an address latch and then access the data port # in an "atomic" manner. # # I suggest removing the locking from ad_read/ad_write + # ad_{enter|leave}_MCE and clamping the locks wherever the functions # are called. I hope the attached patch does that correctly. # # Yes, I don't like all the timeout loops while holding the locks: # high chances that a cpu is spinning in interrupt context :( # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.25 # [PATCH] epoll timeout and syscall return types # # Patch from Davide Libenzi # # Changes : # - Timeout overflow check # - Ceil()ing of ms->jif conversion # - Syscalls return type int->long # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.26 # [PATCH] MAP_FIXED|MAP_ANON crash fix # # An anonymous fixed mmap with CONFIG_HUGETLB_PAGE=y will dereference NULL. We # recur into the pagefault handler with mmap_sem held and lock up. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.27 # [PATCH] u14-34f fix # # Need to reenable interrupts around the call to scsi_register(), which blocks. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.28 # [PATCH] fix adaptec diagnostics for ppc64 # # The return type of sizeof() is size_t. On many architectrues size_t is # unsigned long, and may not be printed with %d. Use %Zu instead. # -------------------------------------------- # 03/02/12 akpm@digeo.com 1.1003.1.29 # [PATCH] printk size_t qualifier confusion # # My printf manpage says: # # z A following integer conversion corresponds to a # size_t or ssize_t argument. (Linux libc5 has Z with # this meaning. Don't use it.) # # And the opengroup spec says # # z Specifies that a following d , i , o , u , x , or X conversion specifier # applies to a size_t or the corresponding signed integer type argument; or # that a following n conversion specifier applies to a pointer to a signed # integer type corresponding to a size_t argument. # # # yet our vsnprintf implementation has # # /* 'z' support added 23/7/1999 S.H. */ # /* 'z' changed to 'Z' --davidm 1/25/99 */ # # # I guess the path of least surprise is to support both. gcc-3.2.1 doesn't # seem to care. # -------------------------------------------- # 03/02/12 agrover@groveronline.com 1.1003.4.1 # Merge groveronline.com:/root/bk/linux-2.5 # into groveronline.com:/root/bk/linux-acpi # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.3 # acpi: make source files look for headers in (event files) # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.6 # acpi: make source files look for headers in (executor files) # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.7 # acpi: make source files look for headers in (hardware files) # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.8 # acpi: make source files look in for headers (namespace files). # -------------------------------------------- # 03/02/12 acme@conectiva.com.br 1.1003.5.1 # [SUNZILOG]: fix DEVFS device name # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.9 # acpi: make source files look in for headers. (parser files). # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.10 # acpi: make source files look in for headers (resources files). # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.11 # acpi: make source files look in for headers (tables files). # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.12 # acpi: make source files look for headers in . # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.13 # acpi: make headers look in for other headers. # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.14 # acpi: make source files look in for headers. (other top-level files) # -------------------------------------------- # 03/02/12 davej@codemonkey.org.uk 1.1003.6.1 # [WATCHDOG] pcwd.c: if cpu has overheated, we want to shutdown, not panic. # Based on a patch from Tariq Shureih # -------------------------------------------- # 03/02/12 davej@codemonkey.org.uk 1.1003.6.2 # [WATCHDOG] printk levels for pcwd.c # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.15 # acpi: remove some acpi-specific compiler definitions in favor of standard ones. # # - Check if __linux__ is defined in include/acpi/platform/acenv.h, instead # of -D_LINUX (defined by drivers/acpi/Makefile). # - Remove -D_LINUX from custom CFLAGS. # - Remove include path of include/acpi, since all headers are looked for in # include/acpi. # -------------------------------------------- # 03/02/12 davej@codemonkey.org.uk 1.1003.6.3 # [WATCHDOG] More panic -> shutdown replacements in pcwd.c # -------------------------------------------- # 03/02/12 agrover@groveronline.com 1.1003.4.2 # ACPI: Lower errorlevel of a debug message (Matthew Wilcox) # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.16 # acpi: fix recently introduced proc-related bugs. # # Recently, the acpi proc files were changed to use the seq_file interface. # As a result of this, the write methods became top-level write() methods # (i.e. not called by the proc layer). # # Whoever made these changes, did not take into account that the parameters # passed to these changed. The fourth parameter previously was a void*, that # pointed to the private data for the owner of the file, and some of the # methods still expected this, even though the parameter is now an loff_t*, # and points to the offset into the file that is being written. Huge Bug. # # This fixes the broken methods to look in the same place as the other # methods (i.e. in the file's private data). # # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.17 # acpi: split sleep support into generic portion, and procfs-handlers. # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.18 # Consolidate ACPI and APM sysrq implementations. # # Each power management scheme was implmenting a sysrq callback for 'o' which # would call their respective power off routines. # # This moves the installation of the sysrq handler to kernel/pm.c, and calls # pm_power_off(), which will work for any platform that has that method # defined. # -------------------------------------------- # 03/02/12 mochel@osdl.org 1.1003.2.19 # acpi sleep: divorce sleep functionality from power off functionality. # # When ACPI turns the system off on shutdown, it actually enters S5, a sleep # state. This functionality is dependent on CONFIG_ACPI_SLEEP, which is # dependent on CONFIG_SOFTWARE_SUSPEND. # # This patch breaks the power off functionality into a separate file, and # removes the dependency on the above-mentioned crap. Finally, power off works # for me again. # # Thanks to Tobias Ringstrom for the original patch. # -------------------------------------------- # 03/02/12 davem@nuts.ninka.net 1.1003.1.30 # Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5 # into nuts.ninka.net:/home/davem/src/BK/sparc-2.5 # -------------------------------------------- # 03/02/12 davem@nuts.ninka.net 1.1003.1.31 # Merge bk://kernel.bkbits.net/acme/sparc-2.5 # into nuts.ninka.net:/home/davem/src/BK/sparc-2.5 # -------------------------------------------- # 03/02/12 zaitcev@redhat.com 1.1003.1.32 # [SUNZILOG]: Fix off-by-1 in spinlock initialization loop. # -------------------------------------------- # 03/02/12 davem@nuts.ninka.net 1.1003.7.1 # Merge nuts.ninka.net:/home/davem/src/BK/network-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/02/12 ahaas@airmail.net 1.1003.7.2 # [PATCH] C99 initializers for net/sunrpc/sysctl.c # -------------------------------------------- # 03/02/12 ahaas@airmail.net 1.1003.7.3 # [PATCH] C99 initializers for net/unix/sysctl_net_unix.c # -------------------------------------------- # 03/02/12 ahaas@airmail.net 1.1003.7.4 # [PATCH] C99 initializers for net/ipv4/netfilter files # -------------------------------------------- # 03/02/12 ahaas@airmail.net 1.1003.7.5 # [PATCH] C99 initializers for net/sctp/sysctl.c # -------------------------------------------- # 03/02/12 ahaas@airmail.net 1.1003.7.6 # [PATCH] C99 initializers for net/ipv6/netfilter/ip6_queue.c # -------------------------------------------- # 03/02/12 ahaas@airmail.net 1.1003.7.7 # [PATCH] C99 initializers for net/ax25/sysctl_net_ax25.c # -------------------------------------------- # 03/02/12 ahaas@airmail.net 1.1003.7.8 # [PATCH] C99 initializers for net/irda/irsysctl.c # -------------------------------------------- # 03/02/13 jgarzik@redhat.com 1.1003.8.1 # [netdrvr fc/iphase] correct PCI probe loop-end test logic [#323] # # Fixes bugzilla bug #323. # -------------------------------------------- # 03/02/13 jgarzik@redhat.com 1.1003.8.2 # [tokenring smctr] remove stray ';' that prevented a loop from working [#312] # # Fixes broken node address check, and bugzilla bug #312. # -------------------------------------------- # 03/02/13 jgarzik@redhat.com 1.1003.8.3 # [netdrvr amd8111e] remove stray ';', fixing register dump [#311] # # Fixes bugzilla bug #311. # -------------------------------------------- # 03/02/12 latten@austin.ibm.com 1.1003.7.9 # [IPSEC]: Make AF_KEY allow NULL encryption. # -------------------------------------------- # 03/02/12 toml@us.ibm.com 1.1003.7.10 # [IPSEC]: Make sure to clear sin_zero in AF_KEY. # -------------------------------------------- # 03/02/12 davem@nuts.ninka.net 1.1003.7.11 # [IPSEC]: Add missed bit of sin_zero fix. # -------------------------------------------- # 03/02/13 jgarzik@redhat.com 1.1003.8.4 # [netdrvr tg3] DMA MRM bit only exists on 5700, 5701 # # Fixed by David Miller, spotted by Manish Lachwani. # -------------------------------------------- # 03/02/12 toml@us.ibm.com 1.1003.7.12 # [IPSEC] Make sure SADB_X_SPDADD messages have proper spid. # -------------------------------------------- # 03/02/13 jgarzik@redhat.com 1.1003.8.5 # [netdrvr arlan] fix the fixed fix. really. # # struct arlan_private clearly needs to be a pointer. # -------------------------------------------- # 03/02/13 jt@hpl.hp.com 1.1003.9.1 # [irda][CORRECT] Properly initialise IrCOMM status line (DCE settings) # # -------------------------------------------- # 03/02/13 jt@hpl.hp.com 1.1003.9.2 # [irda] better poll bit handling during times of packet loss # # o [CORRECT] fix the secondary function to send RR and frames without # the poll bit when it detect packet losses # -------------------------------------------- # 03/02/13 jt@hpl.hp.com 1.1003.9.3 # [irda] rx/tx wrapper path rewrites and cleanup: # o [FEATURE] Properly inline in wrapper Tx path # o [FEATURE] Rewrite/simplify/optimise wrapper Rx path # Lower CPU overhead *and* kernel image size # o [FEATURE] Add ZeroCopy in wrapper Rx path for drivers that support it # I'll update drivers later on... # -------------------------------------------- # 03/02/13 vojtech@kernel.bkbits.net 1.1018 # Merge kernel.bkbits.net:/home/repos/linux-2.5 # into kernel.bkbits.net:/home/vojtech/input # -------------------------------------------- # 03/02/13 davem@nuts.ninka.net 1.1003.7.13 # [IPSEC]: Fix mis-patch of previous changes. # -------------------------------------------- # 03/02/13 kunihiro@ipinfusion.com 1.1003.7.14 # [IPSEC]: Add ipv6 support infrastructure. # -------------------------------------------- # 03/02/13 davem@nuts.ninka.net 1.1003.7.15 # [IPSEC]: ipv6_syms needs net/xfrm.h # -------------------------------------------- # 03/02/13 davem@nuts.ninka.net 1.1003.7.16 # [IPSEC]: Fix af_key.c build. # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1003.6.4 # [WATCHDOG] missing printk level in acquirewdt # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1003.6.5 # [WATCHDOG] printk levels for alim7101_wdt.c # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1003.6.6 # [WATCHDOG] C99 struct initialisers for sc1200wdt # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1003.6.7 # [WATCHDOG] fix sc1200wdt for CONFIG_PNP=n # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1003.6.8 # [WATCHDOG] C99 struct intiialisers for remaining drivers. # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1003.6.9 # [WATCHDOG] Remove unneeded EXPORT_NO_SYMBOLS from sc1200wdt # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1003.10.1 # [CPUFREQ] Add powernow-k7 driver for AMD mobile Athlon/Duron CPUs. # -------------------------------------------- # 03/02/13 davem@nuts.ninka.net 1.1003.7.17 # [IPSEC]: Mark pfkey_sadb_addr2xfrm_addr static again. # -------------------------------------------- # 03/02/13 davej@tetrachloride.(none) 1.1003.11.1 # Merge tetrachloride.(none):/mnt/stuff/kernel/2.5/bk-linus # into tetrachloride.(none):/mnt/stuff/kernel/2.5/agpgart # -------------------------------------------- # 03/02/13 davej@tetrachloride.(none) 1.1003.12.1 # Merge tetrachloride.(none):/mnt/stuff/kernel/2.5/bk-linus # into tetrachloride.(none):/mnt/stuff/kernel/2.5/watchdog # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1003.12.2 # [WATCHDOG] Merge sma cpu5 watchdog driver. # By Heiko Ronsdorf, has been around linux-kernel a few days, and has # been through some rounds of cleanup. # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1003.12.3 # [WATCHDOG] Remove unneeded includes & EXPORT_NO_SYMBOLS from cpu5wdt # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1003.11.2 # [AGPGART] Export needed symbols for AMD K8 GART # -------------------------------------------- # 03/02/13 mochel@osdl.org 1.1003.13.1 # Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin # into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-power # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1003.10.2 # [CPUFREQ] powernow-k7.c: Zeropad the VID or we get 1.50V instead of 1.050V # -------------------------------------------- # 03/02/13 torvalds@home.transmeta.com 1.1019 # Missed initialization of "curr_target" in execve() dethreading case. # -------------------------------------------- # 03/02/13 torvalds@home.transmeta.com 1.1020 # Make dequeue_signal() take the process as an argument. # # This simplifies it and makes it more generic. # -------------------------------------------- # 03/02/13 akpm@digeo.com 1.1021 # [PATCH] set unplug_timer.function inside blk_queue_make_request # # Patch from Neil Brown # # Initialise the queue's unplug_timer inside blk_queue_make_request. This # makes the new auto-unplugging more accessable by other clients of # blk_queue_make_request - e.g. raid5, umem. # -------------------------------------------- # 03/02/13 akpm@digeo.com 1.1022 # [PATCH] make imm.c build # # Patch from: Ingo Oeser # # Cure imm.c of the recent scsi core damage. # -------------------------------------------- # 03/02/13 akpm@digeo.com 1.1023 # [PATCH] fix hugetlbfs_forget_inode() oddity # # - hugetlbfs_forget_inode() should be using || # -------------------------------------------- # 03/02/13 akpm@digeo.com 1.1024 # [PATCH] sysfs error handling fix # # Patch from: Rusty Lynch # # Attempting to cat a sysfs file that returns an error will result in an # endless dump of garbage to the screen because the result of the specific show # operation was being saved to a size_t (unsigned) and then later checked for a # negative value. # # Here is a trivial patch to fix the error. # -------------------------------------------- # 03/02/13 akpm@digeo.com 1.1025 # [PATCH] ia32 TSC timer cleanup # # Patch from: john stultz # # This cleanup patch makes fast_gettimeoffset_quotient (a timer_tsc specific # variable) static, and replaces its usage with cpu_khz, making it timer_opt # independent. # -------------------------------------------- # 03/02/13 akpm@digeo.com 1.1026 # [PATCH] Cyclone timer fixes # # Patch from: john stultz # # This patch "fixes" the timer_cyclone code by having it # initialize fast_gettimeoffset_quotient and cpu_khz in the same manner as # timer_tsc. This is required for enabling the timer_cyclone code on the # x440. # # Ideally fast_gettimeoffset_quotient would not be used outside timer_tsc # and cpu_khz would be initialized generically outside the timer # subsystem. I have patches to do this, but they touch quite a bit of # generic code, and I'd rather not make the timer_cyclone enablement # (patch to follow) depend on these larger changes. # -------------------------------------------- # 03/02/13 akpm@digeo.com 1.1027 # [PATCH] Enable timer_cyclone code # # Patch from john stultz # # This patch simply enables the existing timer_cyclone code for # Summit/x440 systems. # -------------------------------------------- # 03/02/13 akpm@digeo.com 1.1028 # [PATCH] hugetlbfs i_size fix # # Growing i_size in hugetlbfs_prefault() isn't right - if we run out of pages, # do_mmap_pgoff() will chop the partially-instantiated pages off again. # # So update i_size in hugetlbfs_file_mmap() if the whole mmap attempt was # successful. # -------------------------------------------- # 03/02/13 akpm@digeo.com 1.1029 # [PATCH] xattr: lock_kernel() balancing fix # # Patch from Andreas Gruenbacher # # This patch fixes an unbalanced lock_kernel()/unlock_kernel() path in the ext3 # extended attributes code. Instead of fixing this in fs/ext3/xattr_user.c, # the locking code is moved to fs/ext3/xattr.c, since most other types of # extended attributes will need the exact same functionality. # -------------------------------------------- # 03/02/13 mochel@osdl.org 1.1003.13.2 # acpi: Split i386 support up. # # - Created arch/i386/kernel/acpi/ # - Split file into boot.c and sleep.c. # - Moved acpi_wakeup.S into there. # -------------------------------------------- # 03/02/13 torvalds@home.transmeta.com 1.1030 # Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/13 torvalds@home.transmeta.com 1.1031 # Merge bk://kernel.bkbits.net/jgarzik/irda-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/13 mochel@osdl.org 1.1003.13.3 # acpi: Only build sleep directory if we have rest of bus support. # -------------------------------------------- # 03/02/13 torvalds@home.transmeta.com 1.1032 # Merge bk://kernel.bkbits.net/davem/sparc-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/13 torvalds@home.transmeta.com 1.1033 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/13 torvalds@home.transmeta.com 1.1034 # Fix acl_set_handle() compile that got broken by the xattr # updates. # -------------------------------------------- # 03/02/13 mochel@osdl.org 1.1033.1.1 # Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin # into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-power # -------------------------------------------- # 03/02/13 torvalds@home.transmeta.com 1.1035 # Merge bk://linux-dj.bkbits.net/watchdog # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/13 torvalds@home.transmeta.com 1.1036 # Merge bk://linux-dj.bkbits.net/cpufreq # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1037 # [PATCH] ES1370 OSS fix # # from 2.4 # only register gameport if the port is active # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1038 # [PATCH] ES1371 OSS fix # # from 2.4 # only register gameport if the port is active # -------------------------------------------- # 03/02/13 mochel@osdl.org 1.1033.1.2 # acpi sleep: demote sleep proc file creation. # # - Make acpi_sleep_proc_init() a late_initcall(), and not called from # acpi_sleep_init(). This guarantees that the acpi proc hierarchy is at # least there when we create the dang file. # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1039 # [PATCH] improve K7 SMP tainting. # # If we have a non-SMP approved CPU, but its in a UP system, # we should allow SMP kernels. # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1040 # [PATCH] VIA C3 Nehemiah cachesize errata fix. # # Whoops, VIA goofed, and it reports L2 size as 65KB. # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1041 # [PATCH] fix sigio on tty drivers outgoing # # This went into 2.4.18 # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1042 # [PATCH] nvram driver uses incorrect types in llseek method # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1043 # [PATCH] i2c namespace pollution. # # adap_lock is a little generic for a global.. # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1044 # [PATCH] nwflash driver uses wrong types in llseek methods # # from 2.4 # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1045 # [PATCH] proc_file_read documentation/buffer overflow detection. # # This one has been around for ages, has Rusty's name # all over it, but wasn't from him. # 48 lines of comments, and no swearing? 8-) # # Mostly documentation, but also has some buffer overflow # detection in there. # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1046 # [PATCH] nec vrc5477 oss driver update # # Fixes from 2.4 + compile fixes from me. # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1047 # [PATCH] Missing maintainer. # # Forgot to bring this bit forward when I updated the watchdog drivers. # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1048 # [PATCH] VIA C3 Nehemiah support. # # The new C3s won't boot a C3 kernel as they dropped 3dnow support in # favour of SSE. It now also has cmov though and can be scheduled as a # 686 CPU. # # I've a patch for gcc pending inclusion that adds the -march=c3-2 option. # -------------------------------------------- # 03/02/13 davej@codemonkey.org.uk 1.1049 # [PATCH] OSS rme96xx update. # # Lingering around for a while. 2.4 forward port. # -------------------------------------------- # 03/02/13 David_Jeffery@adaptec.com 1.1050 # [PATCH] ips: missing reboot notifier and Mode Sense P8 # # This adds back the reboot_notifier hook that was accidentally removed in # the last set of patches. # # It also adds support handle a Mode Page 8 command so the scsi layer # won't complain anymore. And the movement to using ->device to get scsi # numbers resulted in 2 typos in debug code. These are also fixed. # -------------------------------------------- # 03/02/13 David_Jeffery@adaptec.com 1.1051 # [PATCH] ips: 2.4 compatability code # # This adds a few bits of code and couple #ifdefs that are needed to # enable this driver to work for 2.4 as well as 2.5. # -------------------------------------------- # 03/02/13 David_Jeffery@adaptec.com 1.1052 # [PATCH] ips: remove LinuxVersionCode # # This removes the old LinuxVersionCode() and replaces it with # KERNEL_VERSION(). Thanks go to Adrian Bunk for sending the initial # version. # -------------------------------------------- # 03/02/13 David_Jeffery@adaptec.com 1.1053 # [PATCH] ips: use scsi_add_host # # This converts the driver to use the new scsi_add_host() interface to add # scsi controllers. # -------------------------------------------- # 03/02/13 mochel@osdl.org 1.1033.1.3 # acpi sleep: demote acpi_sleep_init() to a late_initcall. # # - It depends on the rest of the subsys_initcalls in acpi to be done to get # the sleep info from the firmware. # - It doesn't need to be available any earlier... # -------------------------------------------- # 03/02/13 agrover@groveronline.com 1.1054 # Merge groveronline.com:/root/bk/linux-2.5 # into groveronline.com:/root/bk/linux-acpi # -------------------------------------------- # 03/02/13 torvalds@penguin.transmeta.com 1.1053.1.1 # Merge bk://ldm.bkbits.net/linux-2.5-power # into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux # -------------------------------------------- # 03/02/13 torvalds@penguin.transmeta.com 1.1053.1.2 # Merge bk://linux-dj.bkbits.net/agpgart # into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux # -------------------------------------------- # 03/02/13 agrover@groveronline.com 1.1053.2.1 # Merge http://ldm.bkbits.net/linux-2.5-power # into groveronline.com:/root/bk/linux-mochel # -------------------------------------------- # 03/02/13 agrover@groveronline.com 1.1055 # Merge groveronline.com:/root/bk/linux-mochel # into groveronline.com:/root/bk/linux-acpi # -------------------------------------------- # 03/02/13 agrover@groveronline.com 1.1056 # ACPI: Fix whitespace (Pavel Machek) # -------------------------------------------- # 03/02/13 ionut@badula.org 1.1053.1.3 # [PATCH] starfire driver update for 2.5.60 # # This is a rather large update for the starfire network driver, # implementing VLAN support, 64-bit dma_addr_t support, and NAPI support. It # also fixes a couple of show-stopper bugs in the old driver which were # biting real people out there. # # I've had a few positive test results with this version, including one from # Martin Bligh who tested it on his monster SMP boxes. So I'm pretty # confident that it's mostly all right, and certainly better than what's # currently in the tree. # -------------------------------------------- # 03/02/13 agrover@groveronline.com 1.1057 # Merge groveronline.com:/root/bk/linux-2.5 # into groveronline.com:/root/bk/linux-acpi # -------------------------------------------- # 03/02/13 roland@frob.com 1.1053.1.4 # [PATCH] Ctrl-C-ing strace # # This patch fix es the signals vs strace problem. The signal code # assumes that anybody who is TAK_STOPPED will check signals before # resuming, and the ptrace paths didn't do that. # -------------------------------------------- # 03/02/13 agrover@groveronline.com 1.1058 # ACPI: Fix some compilation issues # -------------------------------------------- # 03/02/13 trond.myklebust@fys.uio.no 1.1053.1.5 # [PATCH] further rpc_pipefs cleanups... # # - Only set up pipefs entries for those RPC services that actually # need them (for the moment NFS only). Portmap, lockd,... shouldn't # need to make upcalls. # # - Add in missing semaphore in rpc_populate(). # # - Make inode/dentry variable names in rpc_depopulate/rpc_populate # more consistent w.r.t other functions in rpc_pipe.c # # - Call shrink_dcache_parent() in order to clean up child entries # before we rmdir(). # -------------------------------------------- # 03/02/13 trond.myklebust@fys.uio.no 1.1053.1.6 # [PATCH] Clean up and fix SMP issue w.r.t. XID allocation # # This problem was identified by Olaf Kirch: # # In xprt_request_init(), the XID allocation needs to be protected by a # global spinlock. # -------------------------------------------- # 03/02/13 torvalds@home.transmeta.com 1.1059 # Merge http://linux-acpi.bkbits.net/linux-acpi # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/13 akpm@digeo.com 1.1060 # [PATCH] ACPI sleep build fix # # If you have !CONFIG_ACPI_SLEEP and CONFIG_PROC_FS, drivers/acpi/sleep/proc.o # is built, but drivers/acpi/sleep/main.o is not. # # But proc.o needs symbols from main.o # -------------------------------------------- # diff -Nru a/Documentation/sound/rme96xx b/Documentation/sound/rme96xx --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/sound/rme96xx Fri Feb 14 00:27:30 2003 @@ -0,0 +1,767 @@ +Beta release of the rme96xx (driver for RME 96XX cards like the +"Hammerfall" and the "Hammerfall light") + +Important: The driver module has to be installed on a freshly rebooted system, +otherwise the driver might not be able to acquire its buffers. + +features: + + - OSS programming interface (i.e. runs with standard OSS soundsoftware) + - OSS/Multichannel interface (OSS multichannel is done by just aquiring + more than 2 channels). The driver does not use more than one device + ( yet .. this feature may be implemented later ) + - more than one RME card supported + +The driver uses a specific multichannel interface, which I will document +when the driver gets stable. (take a look at the defines in rme96xx.h, +which adds blocked multichannel formats i.e instead of +lrlrlrlr --> llllrrrr etc. + +Use the "rmectrl" programm to look at the status of the card .. +or use xrmectrl, a GUI interface for the ctrl program. + +What you can do with the rmectrl program is to set the stereo device for +OSS emulation (e.g. if you use SPDIF out). + +You do: + +./ctrl offset 24 24 + +which makes the stereo device use channels 25 and 26. + +Guenter Geiger + +copy the first part of the attached source code into rmectrl.c +and the second part into xrmectrl (or get the program from +http://gige.xdv.org/pages/soft/pages/rme) + +to compile: gcc -o rmectrl rmectrl.c +------------------------------ snip ------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rme96xx.h" + +/* + remctrl.c + (C) 2000 Guenter Geiger + HP20020201 - Heiko Purnhagen +*/ + +/* # define DEVICE_NAME "/dev/mixer" */ +# define DEVICE_NAME "/dev/mixer1" + + +void usage(void) +{ + fprintf(stderr,"usage: rmectrl [/dev/mixer] [command [options]]\n\n"); + fprintf(stderr,"where command is one of:\n"); + fprintf(stderr," help show this help\n"); + fprintf(stderr," status show status bits\n"); + fprintf(stderr," control show control bits\n"); + fprintf(stderr," mix show mixer/offset status\n"); + fprintf(stderr," master set sync master\n"); + fprintf(stderr," pro set spdif out pro\n"); + fprintf(stderr," emphasis set spdif out emphasis\n"); + fprintf(stderr," dolby set spdif out no audio\n"); + fprintf(stderr," optout set spdif out optical\n"); + fprintf(stderr," wordclock set sync wordclock\n"); + fprintf(stderr," spdifin set spdif in (0=optical,1=coax,2=intern)\n"); + fprintf(stderr," syncref set sync source (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n"); + fprintf(stderr," adat1cd set ADAT1 on internal CD\n"); + fprintf(stderr," offset set dev (0..3) offset (0..25)\n"); + exit(-1); +} + + +int main(int argc, char* argv[]) +{ + int cards; + int ret; + int i; + double ft; + int fd, fdwr; + int param,orig; + rme_status_t stat; + rme_ctrl_t ctrl; + char *device; + int argidx; + + if (argc < 2) + usage(); + + if (*argv[1]=='/') { + device = argv[1]; + argidx = 2; + } + else { + device = DEVICE_NAME; + argidx = 1; + } + + fprintf(stdout,"mixer device %s\n",device); + if ((fd = open(device,O_RDONLY)) < 0) { + fprintf(stdout,"opening device failed\n"); + exit(-1); + } + + if ((fdwr = open(device,O_WRONLY)) < 0) { + fprintf(stdout,"opening device failed\n"); + exit(-1); + } + + if (argc < argidx+1) + usage(); + + if (!strcmp(argv[argidx],"help")) + usage(); + if (!strcmp(argv[argidx],"-h")) + usage(); + if (!strcmp(argv[argidx],"--help")) + usage(); + + if (!strcmp(argv[argidx],"status")) { + ioctl(fd,SOUND_MIXER_PRIVATE2,&stat); + fprintf(stdout,"stat.irq %d\n",stat.irq); + fprintf(stdout,"stat.lockmask %d\n",stat.lockmask); + fprintf(stdout,"stat.sr48 %d\n",stat.sr48); + fprintf(stdout,"stat.wclock %d\n",stat.wclock); + fprintf(stdout,"stat.bufpoint %d\n",stat.bufpoint); + fprintf(stdout,"stat.syncmask %d\n",stat.syncmask); + fprintf(stdout,"stat.doublespeed %d\n",stat.doublespeed); + fprintf(stdout,"stat.tc_busy %d\n",stat.tc_busy); + fprintf(stdout,"stat.tc_out %d\n",stat.tc_out); + fprintf(stdout,"stat.crystalrate %d (0=64k 3=96k 4=88.2k 5=48k 6=44.1k 7=32k)\n",stat.crystalrate); + fprintf(stdout,"stat.spdif_error %d\n",stat.spdif_error); + fprintf(stdout,"stat.bufid %d\n",stat.bufid); + fprintf(stdout,"stat.tc_valid %d\n",stat.tc_valid); + exit (0); + } + + if (!strcmp(argv[argidx],"control")) { + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + fprintf(stdout,"ctrl.start %d\n",ctrl.start); + fprintf(stdout,"ctrl.latency %d (0=64 .. 7=8192)\n",ctrl.latency); + fprintf(stdout,"ctrl.master %d\n",ctrl.master); + fprintf(stdout,"ctrl.ie %d\n",ctrl.ie); + fprintf(stdout,"ctrl.sr48 %d\n",ctrl.sr48); + fprintf(stdout,"ctrl.spare %d\n",ctrl.spare); + fprintf(stdout,"ctrl.doublespeed %d\n",ctrl.doublespeed); + fprintf(stdout,"ctrl.pro %d\n",ctrl.pro); + fprintf(stdout,"ctrl.emphasis %d\n",ctrl.emphasis); + fprintf(stdout,"ctrl.dolby %d\n",ctrl.dolby); + fprintf(stdout,"ctrl.opt_out %d\n",ctrl.opt_out); + fprintf(stdout,"ctrl.wordclock %d\n",ctrl.wordclock); + fprintf(stdout,"ctrl.spdif_in %d (0=optical,1=coax,2=intern)\n",ctrl.spdif_in); + fprintf(stdout,"ctrl.sync_ref %d (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n",ctrl.sync_ref); + fprintf(stdout,"ctrl.spdif_reset %d\n",ctrl.spdif_reset); + fprintf(stdout,"ctrl.spdif_select %d\n",ctrl.spdif_select); + fprintf(stdout,"ctrl.spdif_clock %d\n",ctrl.spdif_clock); + fprintf(stdout,"ctrl.spdif_write %d\n",ctrl.spdif_write); + fprintf(stdout,"ctrl.adat1_cd %d\n",ctrl.adat1_cd); + exit (0); + } + + if (!strcmp(argv[argidx],"mix")) { + rme_mixer mix; + int i; + + for (i=0; i<4; i++) { + mix.devnr = i; + ioctl(fd,SOUND_MIXER_PRIVATE1,&mix); + if (mix.devnr == i) { + fprintf(stdout,"devnr %d\n",mix.devnr); + fprintf(stdout,"mix.i_offset %2d (0-25)\n",mix.i_offset); + fprintf(stdout,"mix.o_offset %2d (0-25)\n",mix.o_offset); + } + } + exit (0); + } + +/* the control flags */ + + if (argc < argidx+2) + usage(); + + if (!strcmp(argv[argidx],"master")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("master = %d\n",val); + ctrl.master = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"pro")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("pro = %d\n",val); + ctrl.pro = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"emphasis")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("emphasis = %d\n",val); + ctrl.emphasis = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"dolby")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("dolby = %d\n",val); + ctrl.dolby = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"optout")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("optout = %d\n",val); + ctrl.opt_out = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"wordclock")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("wordclock = %d\n",val); + ctrl.wordclock = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"spdifin")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("spdifin = %d\n",val); + ctrl.spdif_in = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"syncref")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("syncref = %d\n",val); + ctrl.sync_ref = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"adat1cd")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("adat1cd = %d\n",val); + ctrl.adat1_cd = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + +/* setting offset */ + + if (argc < argidx+4) + usage(); + + if (!strcmp(argv[argidx],"offset")) { + rme_mixer mix; + + mix.devnr = atoi(argv[argidx+1]); + + mix.i_offset = atoi(argv[argidx+2]); + mix.o_offset = atoi(argv[argidx+3]); + ioctl(fdwr,SOUND_MIXER_PRIVATE1,&mix); + fprintf(stdout,"devnr %d\n",mix.devnr); + fprintf(stdout,"mix.i_offset to %d\n",mix.i_offset); + fprintf(stdout,"mix.o_offset to %d\n",mix.o_offset); + exit (0); + } + + usage(); + exit (0); /* to avoid warning */ +} + + +---------------------------- -------------------------------- +#!/usr/bin/wish + +# xrmectrl +# (C) 2000 Guenter Geiger +# HP20020201 - Heiko Purnhagen + +#set defaults "-relief ridged" +set CTRLPROG "./rmectrl" +if {$argc} { + set CTRLPROG "$CTRLPROG $argv" +} +puts "CTRLPROG $CTRLPROG" + +frame .butts +button .butts.exit -text "Exit" -command "exit" -relief ridge +#button .butts.state -text "State" -command "get_all" + +pack .butts.exit -side left +pack .butts -side bottom + + +# +# STATUS +# + +frame .status + +# Sampling Rate + +frame .status.sr +label .status.sr.text -text "Sampling Rate" -justify left +radiobutton .status.sr.441 -selectcolor red -text "44.1 kHz" -width 10 -anchor nw -variable srate -value 44100 -font times +radiobutton .status.sr.480 -selectcolor red -text "48 kHz" -width 10 -anchor nw -variable srate -value 48000 -font times +radiobutton .status.sr.882 -selectcolor red -text "88.2 kHz" -width 10 -anchor nw -variable srate -value 88200 -font times +radiobutton .status.sr.960 -selectcolor red -text "96 kHz" -width 10 -anchor nw -variable srate -value 96000 -font times + +pack .status.sr.text .status.sr.441 .status.sr.480 .status.sr.882 .status.sr.960 -side top -padx 3 + +# Lock + +frame .status.lock +label .status.lock.text -text "Lock" -justify left +checkbutton .status.lock.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatlock1 -font times +checkbutton .status.lock.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatlock2 -font times +checkbutton .status.lock.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatlock3 -font times + +pack .status.lock.text .status.lock.adat1 .status.lock.adat2 .status.lock.adat3 -side top -padx 3 + +# Sync + +frame .status.sync +label .status.sync.text -text "Sync" -justify left +checkbutton .status.sync.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatsync1 -font times +checkbutton .status.sync.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatsync2 -font times +checkbutton .status.sync.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatsync3 -font times + +pack .status.sync.text .status.sync.adat1 .status.sync.adat2 .status.sync.adat3 -side top -padx 3 + +# Timecode + +frame .status.tc +label .status.tc.text -text "Timecode" -justify left +checkbutton .status.tc.busy -selectcolor red -text "busy" -anchor nw -width 10 -variable tcbusy -font times +checkbutton .status.tc.out -selectcolor red -text "out" -anchor nw -width 10 -variable tcout -font times +checkbutton .status.tc.valid -selectcolor red -text "valid" -anchor nw -width 10 -variable tcvalid -font times + +pack .status.tc.text .status.tc.busy .status.tc.out .status.tc.valid -side top -padx 3 + +# SPDIF In + +frame .status.spdif +label .status.spdif.text -text "SPDIF In" -justify left +label .status.spdif.sr -text "--.- kHz" -anchor n -width 10 -font times +checkbutton .status.spdif.error -selectcolor red -text "Input Lock" -anchor nw -width 10 -variable spdiferr -font times + +pack .status.spdif.text .status.spdif.sr .status.spdif.error -side top -padx 3 + +pack .status.sr .status.lock .status.sync .status.tc .status.spdif -side left -fill x -anchor n -expand 1 + + +# +# CONTROL +# + +proc setprof {} { + global CTRLPROG + global spprof + exec $CTRLPROG pro $spprof +} + +proc setemph {} { + global CTRLPROG + global spemph + exec $CTRLPROG emphasis $spemph +} + +proc setnoaud {} { + global CTRLPROG + global spnoaud + exec $CTRLPROG dolby $spnoaud +} + +proc setoptical {} { + global CTRLPROG + global spoptical + exec $CTRLPROG optout $spoptical +} + +proc setspdifin {} { + global CTRLPROG + global spdifin + exec $CTRLPROG spdifin [expr $spdifin - 1] +} + +proc setsyncsource {} { + global CTRLPROG + global syncsource + exec $CTRLPROG syncref [expr $syncsource -1] +} + + +proc setmaster {} { + global CTRLPROG + global master + exec $CTRLPROG master $master +} + +proc setwordclock {} { + global CTRLPROG + global wordclock + exec $CTRLPROG wordclock $wordclock +} + +proc setadat1cd {} { + global CTRLPROG + global adat1cd + exec $CTRLPROG adat1cd $adat1cd +} + + +frame .control + +# SPDIF In & SPDIF Out + + +frame .control.spdif + +frame .control.spdif.in +label .control.spdif.in.text -text "SPDIF In" -justify left +radiobutton .control.spdif.in.input1 -text "Optical" -anchor nw -width 13 -variable spdifin -value 1 -command setspdifin -selectcolor blue -font times +radiobutton .control.spdif.in.input2 -text "Coaxial" -anchor nw -width 13 -variable spdifin -value 2 -command setspdifin -selectcolor blue -font times +radiobutton .control.spdif.in.input3 -text "Intern " -anchor nw -width 13 -variable spdifin -command setspdifin -value 3 -selectcolor blue -font times + +checkbutton .control.spdif.in.adat1cd -text "ADAT1 Intern" -anchor nw -width 13 -variable adat1cd -command setadat1cd -selectcolor blue -font times + +pack .control.spdif.in.text .control.spdif.in.input1 .control.spdif.in.input2 .control.spdif.in.input3 .control.spdif.in.adat1cd + +label .control.spdif.space + +frame .control.spdif.out +label .control.spdif.out.text -text "SPDIF Out" -justify left +checkbutton .control.spdif.out.pro -text "Professional" -anchor nw -width 13 -variable spprof -command setprof -selectcolor blue -font times +checkbutton .control.spdif.out.emphasis -text "Emphasis" -anchor nw -width 13 -variable spemph -command setemph -selectcolor blue -font times +checkbutton .control.spdif.out.dolby -text "NoAudio" -anchor nw -width 13 -variable spnoaud -command setnoaud -selectcolor blue -font times +checkbutton .control.spdif.out.optout -text "Optical Out" -anchor nw -width 13 -variable spoptical -command setoptical -selectcolor blue -font times + +pack .control.spdif.out.optout .control.spdif.out.dolby .control.spdif.out.emphasis .control.spdif.out.pro .control.spdif.out.text -side bottom + +pack .control.spdif.in .control.spdif.space .control.spdif.out -side top -fill y -padx 3 -expand 1 + +# Sync Mode & Sync Source + +frame .control.sync +frame .control.sync.mode +label .control.sync.mode.text -text "Sync Mode" -justify left +checkbutton .control.sync.mode.master -text "Master" -anchor nw -width 13 -variable master -command setmaster -selectcolor blue -font times +checkbutton .control.sync.mode.wc -text "Wordclock" -anchor nw -width 13 -variable wordclock -command setwordclock -selectcolor blue -font times + +pack .control.sync.mode.text .control.sync.mode.master .control.sync.mode.wc + +label .control.sync.space + +frame .control.sync.src +label .control.sync.src.text -text "Sync Source" -justify left +radiobutton .control.sync.src.input1 -text "ADAT1" -anchor nw -width 13 -variable syncsource -value 1 -command setsyncsource -selectcolor blue -font times +radiobutton .control.sync.src.input2 -text "ADAT2" -anchor nw -width 13 -variable syncsource -value 2 -command setsyncsource -selectcolor blue -font times +radiobutton .control.sync.src.input3 -text "ADAT3" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 3 -selectcolor blue -font times +radiobutton .control.sync.src.input4 -text "SPDIF" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 4 -selectcolor blue -font times + +pack .control.sync.src.input4 .control.sync.src.input3 .control.sync.src.input2 .control.sync.src.input1 .control.sync.src.text -side bottom + +pack .control.sync.mode .control.sync.space .control.sync.src -side top -fill y -padx 3 -expand 1 + +label .control.space -text "" -width 10 + +# Buffer Size + +frame .control.buf +label .control.buf.text -text "Buffer Size (Latency)" -justify left +radiobutton .control.buf.b1 -selectcolor red -text "64 (1.5 ms)" -width 13 -anchor nw -variable ssrate -value 1 -font times +radiobutton .control.buf.b2 -selectcolor red -text "128 (3 ms)" -width 13 -anchor nw -variable ssrate -value 2 -font times +radiobutton .control.buf.b3 -selectcolor red -text "256 (6 ms)" -width 13 -anchor nw -variable ssrate -value 3 -font times +radiobutton .control.buf.b4 -selectcolor red -text "512 (12 ms)" -width 13 -anchor nw -variable ssrate -value 4 -font times +radiobutton .control.buf.b5 -selectcolor red -text "1024 (23 ms)" -width 13 -anchor nw -variable ssrate -value 5 -font times +radiobutton .control.buf.b6 -selectcolor red -text "2048 (46 ms)" -width 13 -anchor nw -variable ssrate -value 6 -font times +radiobutton .control.buf.b7 -selectcolor red -text "4096 (93 ms)" -width 13 -anchor nw -variable ssrate -value 7 -font times +radiobutton .control.buf.b8 -selectcolor red -text "8192 (186 ms)" -width 13 -anchor nw -variable ssrate -value 8 -font times + +pack .control.buf.text .control.buf.b1 .control.buf.b2 .control.buf.b3 .control.buf.b4 .control.buf.b5 .control.buf.b6 .control.buf.b7 .control.buf.b8 -side top -padx 3 + +# Offset + +frame .control.offset + +frame .control.offset.in +label .control.offset.in.text -text "Offset In" -justify left +label .control.offset.in.off0 -text "dev\#0: -" -anchor nw -width 10 -font times +label .control.offset.in.off1 -text "dev\#1: -" -anchor nw -width 10 -font times +label .control.offset.in.off2 -text "dev\#2: -" -anchor nw -width 10 -font times +label .control.offset.in.off3 -text "dev\#3: -" -anchor nw -width 10 -font times + +pack .control.offset.in.text .control.offset.in.off0 .control.offset.in.off1 .control.offset.in.off2 .control.offset.in.off3 + +label .control.offset.space + +frame .control.offset.out +label .control.offset.out.text -text "Offset Out" -justify left +label .control.offset.out.off0 -text "dev\#0: -" -anchor nw -width 10 -font times +label .control.offset.out.off1 -text "dev\#1: -" -anchor nw -width 10 -font times +label .control.offset.out.off2 -text "dev\#2: -" -anchor nw -width 10 -font times +label .control.offset.out.off3 -text "dev\#3: -" -anchor nw -width 10 -font times + +pack .control.offset.out.off3 .control.offset.out.off2 .control.offset.out.off1 .control.offset.out.off0 .control.offset.out.text -side bottom + +pack .control.offset.in .control.offset.space .control.offset.out -side top -fill y -padx 3 -expand 1 + + +pack .control.spdif .control.sync .control.space .control.buf .control.offset -side left -fill both -anchor n -expand 1 + + +label .statustext -text Status -justify center -relief ridge +label .controltext -text Control -justify center -relief ridge + +label .statusspace +label .controlspace + +pack .statustext .status .statusspace .controltext .control .controlspace -side top -anchor nw -fill both -expand 1 + + +proc get_bit {output sstr} { + set idx1 [string last [concat $sstr 1] $output] + set idx1 [expr $idx1 != -1] + return $idx1 +} + +proc get_val {output sstr} { + set val [string wordend $output [string last $sstr $output]] + set val [string range $output $val [expr $val+1]] + return $val +} + +proc get_val2 {output sstr} { + set val [string wordend $output [string first $sstr $output]] + set val [string range $output $val [expr $val+2]] + return $val +} + +proc get_control {} { + global spprof + global spemph + global spnoaud + global spoptical + global spdifin + global ssrate + global master + global wordclock + global syncsource + global CTRLPROG + + set f [open "| $CTRLPROG control" r+] + set ooo [read $f 1000] + close $f +# puts $ooo + + set spprof [ get_bit $ooo "pro"] + set spemph [ get_bit $ooo "emphasis"] + set spnoaud [ get_bit $ooo "dolby"] + set spoptical [ get_bit $ooo "opt_out"] + set spdifin [ expr [ get_val $ooo "spdif_in"] + 1] + set ssrate [ expr [ get_val $ooo "latency"] + 1] + set master [ expr [ get_val $ooo "master"]] + set wordclock [ expr [ get_val $ooo "wordclock"]] + set syncsource [ expr [ get_val $ooo "sync_ref"] + 1] +} + +proc get_status {} { + global srate + global ctrlcom + + global adatlock1 + global adatlock2 + global adatlock3 + + global adatsync1 + global adatsync2 + global adatsync3 + + global tcbusy + global tcout + global tcvalid + + global spdiferr + global crystal + global .status.spdif.text + global CTRLPROG + + + set f [open "| $CTRLPROG status" r+] + set ooo [read $f 1000] + close $f +# puts $ooo + +# samplerate + + set idx1 [string last "sr48 1" $ooo] + set idx2 [string last "doublespeed 1" $ooo] + if {$idx1 >= 0} { + set fact1 48000 + } else { + set fact1 44100 + } + + if {$idx2 >= 0} { + set fact2 2 + } else { + set fact2 1 + } + set srate [expr $fact1 * $fact2] +# ADAT lock + + set val [get_val $ooo lockmask] + set adatlock1 0 + set adatlock2 0 + set adatlock3 0 + if {[expr $val & 1]} { + set adatlock3 1 + } + if {[expr $val & 2]} { + set adatlock2 1 + } + if {[expr $val & 4]} { + set adatlock1 1 + } + +# ADAT sync + set val [get_val $ooo syncmask] + set adatsync1 0 + set adatsync2 0 + set adatsync3 0 + + if {[expr $val & 1]} { + set adatsync3 1 + } + if {[expr $val & 2]} { + set adatsync2 1 + } + if {[expr $val & 4]} { + set adatsync1 1 + } + +# TC busy + + set tcbusy [get_bit $ooo "busy"] + set tcout [get_bit $ooo "out"] + set tcvalid [get_bit $ooo "valid"] + set spdiferr [expr [get_bit $ooo "spdif_error"] == 0] + +# 000=64kHz, 100=88.2kHz, 011=96kHz +# 111=32kHz, 110=44.1kHz, 101=48kHz + + set val [get_val $ooo crystalrate] + + set crystal "--.- kHz" + if {$val == 0} { + set crystal "64 kHz" + } + if {$val == 4} { + set crystal "88.2 kHz" + } + if {$val == 3} { + set crystal "96 kHz" + } + if {$val == 7} { + set crystal "32 kHz" + } + if {$val == 6} { + set crystal "44.1 kHz" + } + if {$val == 5} { + set crystal "48 kHz" + } + .status.spdif.sr configure -text $crystal +} + +proc get_offset {} { + global inoffset + global outoffset + global CTRLPROG + + set f [open "| $CTRLPROG mix" r+] + set ooo [read $f 1000] + close $f +# puts $ooo + + if { [string match "*devnr*" $ooo] } { + set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] + set val [get_val2 $ooo i_offset] + .control.offset.in.off0 configure -text "dev\#0: $val" + set val [get_val2 $ooo o_offset] + .control.offset.out.off0 configure -text "dev\#0: $val" + } else { + .control.offset.in.off0 configure -text "dev\#0: -" + .control.offset.out.off0 configure -text "dev\#0: -" + } + if { [string match "*devnr*" $ooo] } { + set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] + set val [get_val2 $ooo i_offset] + .control.offset.in.off1 configure -text "dev\#1: $val" + set val [get_val2 $ooo o_offset] + .control.offset.out.off1 configure -text "dev\#1: $val" + } else { + .control.offset.in.off1 configure -text "dev\#1: -" + .control.offset.out.off1 configure -text "dev\#1: -" + } + if { [string match "*devnr*" $ooo] } { + set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] + set val [get_val2 $ooo i_offset] + .control.offset.in.off2 configure -text "dev\#2: $val" + set val [get_val2 $ooo o_offset] + .control.offset.out.off2 configure -text "dev\#2: $val" + } else { + .control.offset.in.off2 configure -text "dev\#2: -" + .control.offset.out.off2 configure -text "dev\#2: -" + } + if { [string match "*devnr*" $ooo] } { + set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] + set val [get_val2 $ooo i_offset] + .control.offset.in.off3 configure -text "dev\#3: $val" + set val [get_val2 $ooo o_offset] + .control.offset.out.off3 configure -text "dev\#3: $val" + } else { + .control.offset.in.off3 configure -text "dev\#3: -" + .control.offset.out.off3 configure -text "dev\#3: -" + } +} + + +proc get_all {} { +get_status +get_control +get_offset +} + +# main +while {1} { + after 200 + get_all + update +} diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS Fri Feb 14 00:27:28 2003 +++ b/MAINTAINERS Fri Feb 14 00:27:28 2003 @@ -460,6 +460,13 @@ W: http://www.cyclades.com/ S: Supported +DAC960 RAID CONTROLLER DRIVER +P: Dave Olien +M dmo@osdl.org +W: http://www.osdl.org/archive/dmo/DAC960 +L: linux-kernel@vger.kernel.org +S: Maintained + DAMA SLAVE for AX.25 P: Joerg Reuter M: jreuter@yaina.de @@ -1498,6 +1505,11 @@ P: Eberhard Moenkeberg M: emoenke@gwdg.de L: linux-kernel@vger.kernel.org +S: Maintained + +SC1200 WDT DRIVER +P: Zwane Mwaikambo +M: zwane@commfireservices.com S: Maintained SCHEDULER diff -Nru a/Makefile b/Makefile --- a/Makefile Fri Feb 14 00:27:27 2003 +++ b/Makefile Fri Feb 14 00:27:27 2003 @@ -36,7 +36,8 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) ARCH := $(SUBARCH) -KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g") +# Remove hyphens since they have special meaning in RPM filenames +KERNELPATH=kernel-$(subst -,,$(KERNELRELEASE)) UTS_MACHINE := $(ARCH) @@ -355,7 +356,7 @@ # It's a three stage process: # o .tmp_vmlinux1 has all symbols and sections, but __kallsyms is # empty -# Running kallsyms on that gives as .tmp_kallsyms1.o with +# Running kallsyms on that gives us .tmp_kallsyms1.o with # the right size # o .tmp_vmlinux2 now has a __kallsyms section of the right size, # but due to the added section, some addresses have shifted @@ -689,7 +690,7 @@ # make clean Delete all automatically generated files, including # tools and firmware. # make mrproper Delete the current configuration, and related files -# Any core files spread around is deleted as well +# Any core files spread around are deleted as well # make distclean Remove editor backup files, patch leftover files and the like # Files removed with 'make clean' @@ -884,9 +885,9 @@ $(filter-out $(cmd_$(1)),$(cmd_$@))\ $(filter-out $(cmd_$@),$(cmd_$(1)))),\ @set -e; \ - $(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';) \ + $(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';) \ $(cmd_$(1)); \ - scripts/fixdep $(depfile) $@ '$(cmd_$(1))' > $(@D)/.$(@F).tmp; \ + scripts/fixdep $(depfile) $@ '$(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \ rm -f $(depfile); \ mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd) @@ -913,19 +914,19 @@ fi endef -# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= +# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=dir # Usage: # $(Q)$(MAKE) $(build)=dir build := -f scripts/Makefile.build obj -# Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir +# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir # Usage: # $(Q)$(MAKE) $(clean)=dir clean := -f scripts/Makefile.clean obj # $(call descend,,) # Recursively call a sub-make in with target -# Usage is deprecated, because make do not see this as an invocation of make. +# Usage is deprecated, because make does not see this as an invocation of make. descend =$(Q)$(MAKE) -f scripts/Makefile.build obj=$(1) $(2) FORCE: diff -Nru a/arch/alpha/kernel/init_task.c b/arch/alpha/kernel/init_task.c --- a/arch/alpha/kernel/init_task.c Fri Feb 14 00:27:27 2003 +++ b/arch/alpha/kernel/init_task.c Fri Feb 14 00:27:27 2003 @@ -9,6 +9,7 @@ static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); struct task_struct init_task = INIT_TASK(init_task); diff -Nru a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c --- a/arch/alpha/kernel/signal.c Fri Feb 14 00:27:28 2003 +++ b/arch/alpha/kernel/signal.c Fri Feb 14 00:27:28 2003 @@ -619,11 +619,11 @@ if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ - struct k_sigaction *ka = ¤t->sig->action[signr-1]; + struct k_sigaction *ka = ¤t->sighand->action[signr-1]; if (r0) syscall_restart(r0, r19, regs, ka); handle_signal(signr, ka, &info, oldset, regs, sw); diff -Nru a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c --- a/arch/arm/kernel/ecard.c Fri Feb 14 00:27:29 2003 +++ b/arch/arm/kernel/ecard.c Fri Feb 14 00:27:29 2003 @@ -290,14 +290,7 @@ { struct task_struct *tsk = current; - /* - * We don't want /any/ signals, not even SIGKILL - */ - sigfillset(&tsk->blocked); - sigemptyset(&tsk->pending.signal); - recalc_sigpending(); - strcpy(tsk->comm, "kecardd"); - daemonize(); + daemonize("kecardd"); /* * Allocate a mm. We're not a lazy-TLB kernel task since we need diff -Nru a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c --- a/arch/arm/kernel/signal.c Fri Feb 14 00:27:26 2003 +++ b/arch/arm/kernel/signal.c Fri Feb 14 00:27:26 2003 @@ -522,7 +522,7 @@ struct k_sigaction *ka; spin_lock_irq(¤t->sighand->siglock); - signr = dequeue_signal(¤t->blocked, &info); + signr = dequeue_signal(current, ¤t->blocked, &info); spin_unlock_irq(¤t->sighand->siglock); if (!signr) diff -Nru a/arch/cris/drivers/usb-host.c b/arch/cris/drivers/usb-host.c --- a/arch/cris/drivers/usb-host.c Fri Feb 14 00:27:27 2003 +++ b/arch/cris/drivers/usb-host.c Fri Feb 14 00:27:27 2003 @@ -459,7 +459,8 @@ *R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, stop); /* Somehow wait for the DMA to finish current activities */ i = jiffies + 100; - while (jiffies < i); + while (time_before(jiffies, i)) + ; first_ep = &TxIntrEPList[0]; tmp_ep = first_ep; diff -Nru a/arch/cris/kernel/signal.c b/arch/cris/kernel/signal.c --- a/arch/cris/kernel/signal.c Fri Feb 14 00:27:26 2003 +++ b/arch/cris/kernel/signal.c Fri Feb 14 00:27:26 2003 @@ -560,7 +560,7 @@ if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(canrestart, signr, &info, oldset, regs); diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Fri Feb 14 00:27:27 2003 +++ b/arch/i386/Kconfig Fri Feb 14 00:27:27 2003 @@ -136,6 +136,7 @@ - "Winchip-2" for IDT Winchip 2. - "Winchip-2A" for IDT Winchips with 3dNow! capabilities. - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. + - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above). If you don't know what to do, choose "386". @@ -174,7 +175,7 @@ against the f00f bug found in earlier Pentiums. config MPENTIUMII - bool "Pentium-II/Celeron(pre-Coppermine)" + bool "Pentium-II/Celeron(pre-Coppermine)" help Select this for Intel chips based on the Pentium-II and pre-Coppermine Celeron core. This option enables an unaligned @@ -260,6 +261,16 @@ treat this chip as a generic 586. Whilst the CPU is 686 class, it lacks the cmov extension which gcc assumes is present when generating 686 code. + Note, that Nehemiah (Model 9) and above will not boot with this + kernel due to them lacking the 3dnow instructions used in earlier + incarnations of the CPU. + +config MVIAC3_2 + bool "VIA C3-2 (Nehemiah)" + help + Select this for a VIA C3 "Nehemiah". Selecting this enables usage of SSE + and tells gcc to treat the CPU as a 686. + Note, this kernel will not boot on older (pre model 9) C3s. endchoice @@ -278,8 +289,8 @@ config X86_L1_CACHE_SHIFT int - default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 default "4" if MELAN || M486 || M386 + default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 default "6" if MK7 || MK8 default "7" if MPENTIUM4 @@ -325,12 +336,12 @@ config X86_ALIGNMENT_16 bool - depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486 + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 default y config X86_TSC bool - depends on MWINCHIP3D || MWINCHIP2 || MCRUSOE || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 + depends on MWINCHIP3D || MWINCHIP2 || MCRUSOE || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 default y config X86_GOOD_APIC @@ -345,7 +356,7 @@ config X86_USE_PPRO_CHECKSUM bool - depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || MK8 + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 default y config X86_USE_3DNOW @@ -360,7 +371,7 @@ config X86_PREFETCH bool - depends on MPENTIUMIII || MPENTIUM4 + depends on MPENTIUMIII || MPENTIUM4 || MVIAC3_2 default y config X86_SSE2 @@ -1000,6 +1011,16 @@ help This adds the CPUFreq driver for mobile AMD K6-2+ and mobile AMD K6-3+ processors. + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + +config X86_POWERNOW_K7 + tristate "AMD Mobile Athlon/Duron PowerNow!" + depends on CPU_FREQ + help + This adds the CPUFreq driver for mobile AMD K7 mobile processors. For details, take a look at linux/Documentation/cpufreq. diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile --- a/arch/i386/Makefile Fri Feb 14 00:27:27 2003 +++ b/arch/i386/Makefile Fri Feb 14 00:27:27 2003 @@ -46,6 +46,7 @@ cflags-$(CONFIG_MCYRIXIII) += $(call check_gcc,-march=c3,-march=i486) # The alignment flags change with gcc 3.2 cflags-$(CONFIG_MCYRIXIII) += $(call check_gcc,-falign-functions=0 -falign-jumps=0 -falign-loops=0,-malign-functions=0 -malign-jumps=0 -malign-loops=0) +cflags-$(CONFIG_MVIAC3_2) += $(call check_gcc,-march=c3-2,-march=i686) CFLAGS += $(cflags-y) diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile --- a/arch/i386/kernel/Makefile Fri Feb 14 00:27:27 2003 +++ b/arch/i386/kernel/Makefile Fri Feb 14 00:27:27 2003 @@ -10,14 +10,13 @@ obj-y += cpu/ obj-y += timers/ +obj-$(CONFIG_ACPI) += acpi/ obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o obj-$(CONFIG_MCA) += mca.o obj-$(CONFIG_X86_MSR) += msr.o obj-$(CONFIG_X86_CPUID) += cpuid.o obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_APM) += apm.o -obj-$(CONFIG_ACPI) += acpi.o -obj-$(CONFIG_ACPI_SLEEP) += acpi_wakeup.o obj-$(CONFIG_X86_SMP) += smp.o smpboot.o obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o obj-$(CONFIG_X86_MPPARSE) += mpparse.o diff -Nru a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/acpi/Makefile Fri Feb 14 00:27:30 2003 @@ -0,0 +1,3 @@ +obj-$(CONFIG_ACPI_BOOT) := boot.o +obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o + diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/acpi/boot.c Fri Feb 14 00:27:29 2003 @@ -0,0 +1,425 @@ +/* + * boot.c - Architecture-Specific Low-Level ACPI Boot Support + * + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * Copyright (C) 2001 Jun Nakajima + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include + +#include +#include + +#define PREFIX "ACPI: " + +extern int acpi_disabled; + +/* -------------------------------------------------------------------------- + Boot-time Configuration + -------------------------------------------------------------------------- */ + +enum acpi_irq_model_id acpi_irq_model; + +/* + * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, + * to map the target physical address. The problem is that set_fixmap() + * provides a single page, and it is possible that the page is not + * sufficient. + * By using this area, we can map up to MAX_IO_APICS pages temporarily, + * i.e. until the next __va_range() call. + * + * Important Safety Note: The fixed I/O APIC page numbers are *subtracted* + * from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and + * count idx down while incrementing the phys address. + */ +char *__acpi_map_table(unsigned long phys, unsigned long size) +{ + unsigned long base, offset, mapped_size; + int idx; + + if (phys + size < 8*1024*1024) + return __va(phys); + + offset = phys & (PAGE_SIZE - 1); + mapped_size = PAGE_SIZE - offset; + set_fixmap(FIX_ACPI_END, phys); + base = fix_to_virt(FIX_ACPI_END); + + /* + * Most cases can be covered by the below. + */ + idx = FIX_ACPI_END; + while (mapped_size < size) { + if (--idx < FIX_ACPI_BEGIN) + return 0; /* cannot handle this */ + phys += PAGE_SIZE; + set_fixmap(idx, phys); + mapped_size += PAGE_SIZE; + } + + return ((unsigned char *) base + offset); +} + + +#ifdef CONFIG_X86_LOCAL_APIC + +int acpi_lapic; + +static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; + + +static int __init +acpi_parse_madt ( + unsigned long phys_addr, + unsigned long size) +{ + struct acpi_table_madt *madt = NULL; + + if (!phys_addr || !size) + return -EINVAL; + + madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size); + if (!madt) { + printk(KERN_WARNING PREFIX "Unable to map MADT\n"); + return -ENODEV; + } + + if (madt->lapic_address) + acpi_lapic_addr = (u64) madt->lapic_address; + + printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n", + madt->lapic_address); + + acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); + + return 0; +} + + +static int __init +acpi_parse_lapic ( + acpi_table_entry_header *header) +{ + struct acpi_table_lapic *processor = NULL; + + processor = (struct acpi_table_lapic*) header; + if (!processor) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + mp_register_lapic ( + processor->id, /* APIC ID */ + processor->flags.enabled); /* Enabled? */ + + return 0; +} + + +static int __init +acpi_parse_lapic_addr_ovr ( + acpi_table_entry_header *header) +{ + struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; + + lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header; + if (!lapic_addr_ovr) + return -EINVAL; + + acpi_lapic_addr = lapic_addr_ovr->address; + + return 0; +} + +#ifndef CONFIG_ACPI_HT_ONLY + +static int __init +acpi_parse_lapic_nmi ( + acpi_table_entry_header *header) +{ + struct acpi_table_lapic_nmi *lapic_nmi = NULL; + + lapic_nmi = (struct acpi_table_lapic_nmi*) header; + if (!lapic_nmi) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + if (lapic_nmi->lint != 1) + printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); + + return 0; +} + +#endif /*CONFIG_ACPI_HT_ONLY*/ + +#endif /*CONFIG_X86_LOCAL_APIC*/ + +#ifdef CONFIG_X86_IO_APIC + +int acpi_ioapic; + +#ifndef CONFIG_ACPI_HT_ONLY + +static int __init +acpi_parse_ioapic ( + acpi_table_entry_header *header) +{ + struct acpi_table_ioapic *ioapic = NULL; + + ioapic = (struct acpi_table_ioapic*) header; + if (!ioapic) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + mp_register_ioapic ( + ioapic->id, + ioapic->address, + ioapic->global_irq_base); + + return 0; +} + + +static int __init +acpi_parse_int_src_ovr ( + acpi_table_entry_header *header) +{ + struct acpi_table_int_src_ovr *intsrc = NULL; + + intsrc = (struct acpi_table_int_src_ovr*) header; + if (!intsrc) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + mp_override_legacy_irq ( + intsrc->bus_irq, + intsrc->flags.polarity, + intsrc->flags.trigger, + intsrc->global_irq); + + return 0; +} + + +static int __init +acpi_parse_nmi_src ( + acpi_table_entry_header *header) +{ + struct acpi_table_nmi_src *nmi_src = NULL; + + nmi_src = (struct acpi_table_nmi_src*) header; + if (!nmi_src) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + /* TBD: Support nimsrc entries? */ + + return 0; +} + +#endif /*!CONFIG_ACPI_HT_ONLY*/ +#endif /*CONFIG_X86_IO_APIC*/ + + +static unsigned long __init +acpi_scan_rsdp ( + unsigned long start, + unsigned long length) +{ + unsigned long offset = 0; + unsigned long sig_len = sizeof("RSD PTR ") - 1; + + /* + * Scan all 16-byte boundaries of the physical memory region for the + * RSDP signature. + */ + for (offset = 0; offset < length; offset += 16) { + if (strncmp((char *) (start + offset), "RSD PTR ", sig_len)) + continue; + return (start + offset); + } + + return 0; +} + + +unsigned long __init +acpi_find_rsdp (void) +{ + unsigned long rsdp_phys = 0; + + /* + * Scan memory looking for the RSDP signature. First search EBDA (low + * memory) paragraphs and then search upper memory (E0000-FFFFF). + */ + rsdp_phys = acpi_scan_rsdp (0, 0x400); + if (!rsdp_phys) + rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF); + + return rsdp_phys; +} + + +int __init +acpi_boot_init (void) +{ + int result = 0; + + /* + * The default interrupt routing model is PIC (8259). This gets + * overriden if IOAPICs are enumerated (below). + */ + acpi_irq_model = ACPI_IRQ_MODEL_PIC; + + /* + * Initialize the ACPI boot-time table parser. + */ + result = acpi_table_init(); + if (result) + return result; + + result = acpi_blacklisted(); + if (result) { + acpi_disabled = 1; + return result; + } + else + printk(KERN_NOTICE PREFIX "BIOS passes blacklist\n"); + +#ifdef CONFIG_X86_LOCAL_APIC + + /* + * MADT + * ---- + * Parse the Multiple APIC Description Table (MADT), if exists. + * Note that this table provides platform SMP configuration + * information -- the successor to MPS tables. + */ + + result = acpi_table_parse(ACPI_APIC, acpi_parse_madt); + if (!result) { + printk(KERN_WARNING PREFIX "MADT not present\n"); + return 0; + } + else if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing MADT\n"); + return result; + } + else if (result > 1) + printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n"); + + /* + * Local APIC + * ---------- + * Note that the LAPIC address is obtained from the MADT (32-bit value) + * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). + */ + + result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr); + if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); + return result; + } + + mp_register_lapic_address(acpi_lapic_addr); + + result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic); + if (!result) { + printk(KERN_ERR PREFIX "No LAPIC entries present\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return -ENODEV; + } + else if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return result; + } + +#ifndef CONFIG_ACPI_HT_ONLY + result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi); + if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return result; + } +#endif /*!CONFIG_ACPI_HT_ONLY*/ + + acpi_lapic = 1; + +#endif /*CONFIG_X86_LOCAL_APIC*/ + +#ifdef CONFIG_X86_IO_APIC +#ifndef CONFIG_ACPI_HT_ONLY + + /* + * I/O APIC + * -------- + */ + + result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic); + if (!result) { + printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); + return -ENODEV; + } + else if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); + return result; + } + + /* Build a default routing table for legacy (ISA) interrupts. */ + mp_config_acpi_legacy_irqs(); + + result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr); + if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return result; + } + + result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src); + if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return result; + } + + acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; + + acpi_ioapic = 1; + +#endif /*!CONFIG_ACPI_HT_ONLY*/ +#endif /*CONFIG_X86_IO_APIC*/ + +#ifdef CONFIG_X86_LOCAL_APIC + if (acpi_lapic && acpi_ioapic) { + smp_found_config = 1; + clustered_apic_check(); + } +#endif + + return 0; +} diff -Nru a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/acpi/sleep.c Fri Feb 14 00:27:30 2003 @@ -0,0 +1,96 @@ +/* + * sleep.c - x86-specific ACPI sleep support. + * + * Copyright (C) 2001-2003 Patrick Mochel + */ + +#include +#include +#include + + +/* address in low memory of the wakeup routine. */ +unsigned long acpi_wakeup_address = 0; +unsigned long acpi_video_flags; +extern char wakeup_start, wakeup_end; + +extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); + +static void init_low_mapping(pgd_t *pgd, int pgd_limit) +{ + int pgd_ofs = 0; + + while ((pgd_ofs < pgd_limit) && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) { + set_pgd(pgd, *(pgd+USER_PTRS_PER_PGD)); + pgd_ofs++, pgd++; + } +} + +/** + * acpi_save_state_mem - save kernel state + * + * Create an identity mapped page table and copy the wakeup routine to + * low memory. + */ +int acpi_save_state_mem (void) +{ +#if CONFIG_X86_PAE + panic("S3 and PAE do not like each other for now."); + return 1; +#endif + init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD); + memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start); + acpi_copy_wakeup_routine(acpi_wakeup_address); + + return 0; +} + +/** + * acpi_save_state_disk - save kernel state to disk + * + */ +int acpi_save_state_disk (void) +{ + return 1; +} + +/* + * acpi_restore_state + */ +void acpi_restore_state_mem (void) +{ + zap_low_mappings(); +} + +/** + * acpi_reserve_bootmem - do _very_ early ACPI initialisation + * + * We allocate a page in low memory for the wakeup + * routine for when we come back from a sleep state. The + * runtime allocator allows specification of <16M pages, but not + * <1M pages. + */ +void __init acpi_reserve_bootmem(void) +{ + acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); + if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) + printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n"); + printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address); +} + +static int __init acpi_sleep_setup(char *str) +{ + while ((str != NULL) && (*str != '\0')) { + if (strncmp(str, "s3_bios", 7) == 0) + acpi_video_flags = 1; + if (strncmp(str, "s3_mode", 7) == 0) + acpi_video_flags |= 2; + str = strchr(str, ','); + if (str != NULL) + str += strspn(str, ", \t"); + } + return 1; +} + + +__setup("acpi_sleep=", acpi_sleep_setup); diff -Nru a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/acpi/wakeup.S Fri Feb 14 00:27:27 2003 @@ -0,0 +1,325 @@ +.text +#include +#include +#include + +# +# wakeup_code runs in real mode, and at unknown address (determined at run-time). +# Therefore it must only use relative jumps/calls. +# +# Do we need to deal with A20? It is okay: ACPI specs says A20 must be enabled +# +# If physical address of wakeup_code is 0x12345, BIOS should call us with +# cs = 0x1234, eip = 0x05 +# + +ALIGN + .align 4096 +ENTRY(wakeup_start) +wakeup_code: + wakeup_code_start = . + .code16 + + movw $0xb800, %ax + movw %ax,%fs + movw $0x0e00 + 'L', %fs:(0x10) + + cli + cld + + # setup data segment + movw %cs, %ax + movw %ax, %ds # Make ds:0 point to wakeup_start + movw %ax, %ss + mov $(wakeup_stack - wakeup_code), %sp # Private stack is needed for ASUS board + movw $0x0e00 + 'S', %fs:(0x12) + + pushl $0 # Kill any dangerous flags + popfl + + movl real_magic - wakeup_code, %eax + cmpl $0x12345678, %eax + jne bogus_real_magic + + testl $1, video_flags - wakeup_code + jz 1f + lcall $0xc000,$3 +1: + + testl $2, video_flags - wakeup_code + jz 1f + mov video_mode - wakeup_code, %ax + call mode_set +1: + + # set up page table + movl $swapper_pg_dir-__PAGE_OFFSET, %eax + movl %eax, %cr3 + + # make sure %cr4 is set correctly (features, etc) + movl real_save_cr4 - wakeup_code, %eax + movl %eax, %cr4 + movw $0xb800, %ax + movw %ax,%fs + movw $0x0e00 + 'i', %fs:(0x12) + + # need a gdt + lgdt real_save_gdt - wakeup_code + + movl real_save_cr0 - wakeup_code, %eax + movl %eax, %cr0 + jmp 1f +1: + movw $0x0e00 + 'n', %fs:(0x14) + + movl real_magic - wakeup_code, %eax + cmpl $0x12345678, %eax + jne bogus_real_magic + + ljmpl $__KERNEL_CS,$wakeup_pmode_return + +real_save_gdt: .word 0 + .long 0 +real_save_cr0: .long 0 +real_save_cr3: .long 0 +real_save_cr4: .long 0 +real_magic: .long 0 +video_mode: .long 0 +video_flags: .long 0 + +bogus_real_magic: + movw $0x0e00 + 'B', %fs:(0x12) + jmp bogus_real_magic + +/* This code uses an extended set of video mode numbers. These include: + * Aliases for standard modes + * NORMAL_VGA (-1) + * EXTENDED_VGA (-2) + * ASK_VGA (-3) + * Video modes numbered by menu position -- NOT RECOMMENDED because of lack + * of compatibility when extending the table. These are between 0x00 and 0xff. + */ +#define VIDEO_FIRST_MENU 0x0000 + +/* Standard BIOS video modes (BIOS number + 0x0100) */ +#define VIDEO_FIRST_BIOS 0x0100 + +/* VESA BIOS video modes (VESA number + 0x0200) */ +#define VIDEO_FIRST_VESA 0x0200 + +/* Video7 special modes (BIOS number + 0x0900) */ +#define VIDEO_FIRST_V7 0x0900 + +# Setting of user mode (AX=mode ID) => CF=success +mode_set: + movw %ax, %bx +#if 0 + cmpb $0xff, %ah + jz setalias + + testb $VIDEO_RECALC>>8, %ah + jnz _setrec + + cmpb $VIDEO_FIRST_RESOLUTION>>8, %ah + jnc setres + + cmpb $VIDEO_FIRST_SPECIAL>>8, %ah + jz setspc + + cmpb $VIDEO_FIRST_V7>>8, %ah + jz setv7 +#endif + + cmpb $VIDEO_FIRST_VESA>>8, %ah + jnc check_vesa +#if 0 + orb %ah, %ah + jz setmenu +#endif + + decb %ah +# jz setbios Add bios modes later + +setbad: clc + ret + +check_vesa: + subb $VIDEO_FIRST_VESA>>8, %bh + orw $0x4000, %bx # Use linear frame buffer + movw $0x4f02, %ax # VESA BIOS mode set call + int $0x10 + cmpw $0x004f, %ax # AL=4f if implemented + jnz _setbad # AH=0 if OK + + stc + ret + +_setbad: jmp setbad + + .code32 + ALIGN + +.org 0x800 +wakeup_stack_begin: # Stack grows down + +.org 0xff0 # Just below end of page +wakeup_stack: +ENTRY(wakeup_end) + +.org 0x1000 + +wakeup_pmode_return: + movl $__KERNEL_DS, %eax + movl %eax, %ds + movw $0x0e00 + 'u', %ds:(0xb8016) + + # restore other segment registers + xorl %eax, %eax + movw %ax, %fs + movw %ax, %gs + + # reload the gdt, as we need the full 32 bit address + lgdt saved_gdt + lidt saved_idt + lldt saved_ldt + ljmp $(__KERNEL_CS),$1f +1: + movl %cr3, %eax + movl %eax, %cr3 + wbinvd + + # and restore the stack ... but you need gdt for this to work + movl $__KERNEL_DS, %eax + movw %ax, %ss + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movl saved_esp, %esp + + movw $0x0e00 + 'W', %ds:(0xb8018) + movl $(1024*1024*3), %ecx + movl $0, %esi + rep lodsb + movw $0x0e00 + 'O', %ds:(0xb8018) + + movl %cs:saved_magic, %eax + cmpl $0x12345678, %eax + jne bogus_magic + + # restore the other general registers + movl saved_ebx, %ebx + movl saved_edi, %edi + movl saved_esi, %esi + movl saved_ebp, %ebp + + # jump to place where we left off + movl saved_eip,%eax + movw $0x0e00 + 'x', %ds:(0xb8018) + pushl %eax + popl %eax + movw $0x0e00 + '!', %ds:(0xb801a) + jmp *%eax + +bogus_magic: + movw $0x0e00 + 'B', %ds:(0xb8018) + jmp bogus_magic + +bogus_magic2: + movw $0x0e00 + '2', %ds:(0xb8018) + jmp bogus_magic2 + +## +# acpi_copy_wakeup_routine +# +# Copy the above routine to low memory. +# +# Parameters: +# %eax: place to copy wakeup routine to +# +# Returned address is location of code in low memory (past data and stack) +# +ENTRY(acpi_copy_wakeup_routine) + + sgdt saved_gdt + sidt saved_idt + sldt saved_ldt + str saved_tss + + movl %cr3, %edx + movl %edx, real_save_cr3 - wakeup_start (%eax) + movl %cr4, %edx + movl %edx, real_save_cr4 - wakeup_start (%eax) + movl %cr0, %edx + movl %edx, real_save_cr0 - wakeup_start (%eax) + sgdt real_save_gdt - wakeup_start (%eax) + + movl saved_videomode, %edx + movl %edx, video_mode - wakeup_start (%eax) + movl acpi_video_flags, %edx + movl %edx, video_flags - wakeup_start (%eax) + movl $0x12345678, real_magic - wakeup_start (%eax) + movl $0x12345678, saved_magic + ret + +.data +ALIGN +ENTRY(saved_ebp) .long 0 +ENTRY(saved_esi) .long 0 +ENTRY(saved_edi) .long 0 +ENTRY(saved_ebx) .long 0 + +ENTRY(saved_eip) .long 0 +ENTRY(saved_esp) .long 0 + +ENTRY(saved_magic) .long 0 + +ENTRY(do_suspend_lowlevel) + cmpl $0,4(%esp) + jne ret_point + call save_processor_state + + movl %esp, saved_context_esp + movl %eax, saved_context_eax + movl %ebx, saved_context_ebx + movl %ecx, saved_context_ecx + movl %edx, saved_context_edx + movl %ebp, saved_context_ebp + movl %esi, saved_context_esi + movl %edi, saved_context_edi + pushfl ; popl saved_context_eflags + + movl $ret_point,saved_eip + movl %esp,saved_esp + movl %ebp,saved_ebp + movl %ebx,saved_ebx + movl %edi,saved_edi + movl %esi,saved_esi + + pushl $3 + call acpi_enter_sleep_state + addl $4,%esp + ret + .p2align 4,,7 +ret_point: + movl $__KERNEL_DS,%eax + movw %ax, %ds + movl saved_context_esp, %esp + movl saved_context_ebp, %ebp + movl saved_context_eax, %eax + movl saved_context_ebx, %ebx + movl saved_context_ecx, %ecx + movl saved_context_edx, %edx + movl saved_context_esi, %esi + movl saved_context_edi, %edi + call restore_processor_state + pushl saved_context_eflags ; popfl + ret + +ALIGN +# saved registers +saved_gdt: .long 0,0 +saved_idt: .long 0,0 +saved_ldt: .long 0 +saved_tss: .long 0 + diff -Nru a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c --- a/arch/i386/kernel/acpi.c Fri Feb 14 00:27:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,539 +0,0 @@ -/* - * acpi.c - Architecture-Specific Low-Level ACPI Support - * - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * Copyright (C) 2001 Jun Nakajima - * Copyright (C) 2001 Patrick Mochel - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define PREFIX "ACPI: " - -extern int acpi_disabled; - -/* -------------------------------------------------------------------------- - Boot-time Configuration - -------------------------------------------------------------------------- */ - -enum acpi_irq_model_id acpi_irq_model; - -#ifdef CONFIG_ACPI_BOOT -/* - * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, - * to map the target physical address. The problem is that set_fixmap() - * provides a single page, and it is possible that the page is not - * sufficient. - * By using this area, we can map up to MAX_IO_APICS pages temporarily, - * i.e. until the next __va_range() call. - * - * Important Safety Note: The fixed I/O APIC page numbers are *subtracted* - * from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and - * count idx down while incrementing the phys address. - */ -char *__acpi_map_table(unsigned long phys, unsigned long size) -{ - unsigned long base, offset, mapped_size; - int idx; - - if (phys + size < 8*1024*1024) - return __va(phys); - - offset = phys & (PAGE_SIZE - 1); - mapped_size = PAGE_SIZE - offset; - set_fixmap(FIX_ACPI_END, phys); - base = fix_to_virt(FIX_ACPI_END); - - /* - * Most cases can be covered by the below. - */ - idx = FIX_ACPI_END; - while (mapped_size < size) { - if (--idx < FIX_ACPI_BEGIN) - return 0; /* cannot handle this */ - phys += PAGE_SIZE; - set_fixmap(idx, phys); - mapped_size += PAGE_SIZE; - } - - return ((unsigned char *) base + offset); -} - - -#ifdef CONFIG_X86_LOCAL_APIC - -int acpi_lapic; - -static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; - - -static int __init -acpi_parse_madt ( - unsigned long phys_addr, - unsigned long size) -{ - struct acpi_table_madt *madt = NULL; - - if (!phys_addr || !size) - return -EINVAL; - - madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size); - if (!madt) { - printk(KERN_WARNING PREFIX "Unable to map MADT\n"); - return -ENODEV; - } - - if (madt->lapic_address) - acpi_lapic_addr = (u64) madt->lapic_address; - - printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n", - madt->lapic_address); - - acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); - - return 0; -} - - -static int __init -acpi_parse_lapic ( - acpi_table_entry_header *header) -{ - struct acpi_table_lapic *processor = NULL; - - processor = (struct acpi_table_lapic*) header; - if (!processor) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - mp_register_lapic ( - processor->id, /* APIC ID */ - processor->flags.enabled); /* Enabled? */ - - return 0; -} - - -static int __init -acpi_parse_lapic_addr_ovr ( - acpi_table_entry_header *header) -{ - struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; - - lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header; - if (!lapic_addr_ovr) - return -EINVAL; - - acpi_lapic_addr = lapic_addr_ovr->address; - - return 0; -} - -#ifndef CONFIG_ACPI_HT_ONLY - -static int __init -acpi_parse_lapic_nmi ( - acpi_table_entry_header *header) -{ - struct acpi_table_lapic_nmi *lapic_nmi = NULL; - - lapic_nmi = (struct acpi_table_lapic_nmi*) header; - if (!lapic_nmi) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - if (lapic_nmi->lint != 1) - printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); - - return 0; -} - -#endif /*CONFIG_ACPI_HT_ONLY*/ - -#endif /*CONFIG_X86_LOCAL_APIC*/ - -#ifdef CONFIG_X86_IO_APIC - -int acpi_ioapic; - -#ifndef CONFIG_ACPI_HT_ONLY - -static int __init -acpi_parse_ioapic ( - acpi_table_entry_header *header) -{ - struct acpi_table_ioapic *ioapic = NULL; - - ioapic = (struct acpi_table_ioapic*) header; - if (!ioapic) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - mp_register_ioapic ( - ioapic->id, - ioapic->address, - ioapic->global_irq_base); - - return 0; -} - - -static int __init -acpi_parse_int_src_ovr ( - acpi_table_entry_header *header) -{ - struct acpi_table_int_src_ovr *intsrc = NULL; - - intsrc = (struct acpi_table_int_src_ovr*) header; - if (!intsrc) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - mp_override_legacy_irq ( - intsrc->bus_irq, - intsrc->flags.polarity, - intsrc->flags.trigger, - intsrc->global_irq); - - return 0; -} - - -static int __init -acpi_parse_nmi_src ( - acpi_table_entry_header *header) -{ - struct acpi_table_nmi_src *nmi_src = NULL; - - nmi_src = (struct acpi_table_nmi_src*) header; - if (!nmi_src) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - /* TBD: Support nimsrc entries? */ - - return 0; -} - -#endif /*!CONFIG_ACPI_HT_ONLY*/ -#endif /*CONFIG_X86_IO_APIC*/ - - -static unsigned long __init -acpi_scan_rsdp ( - unsigned long start, - unsigned long length) -{ - unsigned long offset = 0; - unsigned long sig_len = sizeof("RSD PTR ") - 1; - - /* - * Scan all 16-byte boundaries of the physical memory region for the - * RSDP signature. - */ - for (offset = 0; offset < length; offset += 16) { - if (strncmp((char *) (start + offset), "RSD PTR ", sig_len)) - continue; - return (start + offset); - } - - return 0; -} - - -unsigned long __init -acpi_find_rsdp (void) -{ - unsigned long rsdp_phys = 0; - - /* - * Scan memory looking for the RSDP signature. First search EBDA (low - * memory) paragraphs and then search upper memory (E0000-FFFFF). - */ - rsdp_phys = acpi_scan_rsdp (0, 0x400); - if (!rsdp_phys) - rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF); - - return rsdp_phys; -} - - -int __init -acpi_boot_init (void) -{ - int result = 0; - - /* - * The default interrupt routing model is PIC (8259). This gets - * overriden if IOAPICs are enumerated (below). - */ - acpi_irq_model = ACPI_IRQ_MODEL_PIC; - - /* - * Initialize the ACPI boot-time table parser. - */ - result = acpi_table_init(); - if (result) - return result; - - result = acpi_blacklisted(); - if (result) { - acpi_disabled = 1; - return result; - } - else - printk(KERN_NOTICE PREFIX "BIOS passes blacklist\n"); - -#ifdef CONFIG_X86_LOCAL_APIC - - /* - * MADT - * ---- - * Parse the Multiple APIC Description Table (MADT), if exists. - * Note that this table provides platform SMP configuration - * information -- the successor to MPS tables. - */ - - result = acpi_table_parse(ACPI_APIC, acpi_parse_madt); - if (!result) { - printk(KERN_WARNING PREFIX "MADT not present\n"); - return 0; - } - else if (result < 0) { - printk(KERN_ERR PREFIX "Error parsing MADT\n"); - return result; - } - else if (result > 1) - printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n"); - - /* - * Local APIC - * ---------- - * Note that the LAPIC address is obtained from the MADT (32-bit value) - * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). - */ - - result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr); - if (result < 0) { - printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); - return result; - } - - mp_register_lapic_address(acpi_lapic_addr); - - result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic); - if (!result) { - printk(KERN_ERR PREFIX "No LAPIC entries present\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return -ENODEV; - } - else if (result < 0) { - printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return result; - } - -#ifndef CONFIG_ACPI_HT_ONLY - result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi); - if (result < 0) { - printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return result; - } -#endif /*!CONFIG_ACPI_HT_ONLY*/ - - acpi_lapic = 1; - -#endif /*CONFIG_X86_LOCAL_APIC*/ - -#ifdef CONFIG_X86_IO_APIC -#ifndef CONFIG_ACPI_HT_ONLY - - /* - * I/O APIC - * -------- - */ - - result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic); - if (!result) { - printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); - return -ENODEV; - } - else if (result < 0) { - printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); - return result; - } - - /* Build a default routing table for legacy (ISA) interrupts. */ - mp_config_acpi_legacy_irqs(); - - result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr); - if (result < 0) { - printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return result; - } - - result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src); - if (result < 0) { - printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return result; - } - - acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; - - acpi_ioapic = 1; - -#endif /*!CONFIG_ACPI_HT_ONLY*/ -#endif /*CONFIG_X86_IO_APIC*/ - -#ifdef CONFIG_X86_LOCAL_APIC - if (acpi_lapic && acpi_ioapic) { - smp_found_config = 1; - clustered_apic_check(); - } -#endif - - return 0; -} - -#endif /*CONFIG_ACPI_BOOT*/ - - -/* -------------------------------------------------------------------------- - Low-Level Sleep Support - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_ACPI_SLEEP - -/* address in low memory of the wakeup routine. */ -unsigned long acpi_wakeup_address = 0; -unsigned long acpi_video_flags; -extern char wakeup_start, wakeup_end; - -extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); - -static void init_low_mapping(pgd_t *pgd, int pgd_limit) -{ - int pgd_ofs = 0; - - while ((pgd_ofs < pgd_limit) && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) { - set_pgd(pgd, *(pgd+USER_PTRS_PER_PGD)); - pgd_ofs++, pgd++; - } -} - -/** - * acpi_save_state_mem - save kernel state - * - * Create an identity mapped page table and copy the wakeup routine to - * low memory. - */ -int acpi_save_state_mem (void) -{ -#if CONFIG_X86_PAE - panic("S3 and PAE do not like each other for now."); - return 1; -#endif - init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD); - memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start); - acpi_copy_wakeup_routine(acpi_wakeup_address); - - return 0; -} - -/** - * acpi_save_state_disk - save kernel state to disk - * - */ -int acpi_save_state_disk (void) -{ - return 1; -} - -/* - * acpi_restore_state - */ -void acpi_restore_state_mem (void) -{ - zap_low_mappings(); -} - -/** - * acpi_reserve_bootmem - do _very_ early ACPI initialisation - * - * We allocate a page in low memory for the wakeup - * routine for when we come back from a sleep state. The - * runtime allocator allows specification of <16M pages, but not - * <1M pages. - */ -void __init acpi_reserve_bootmem(void) -{ - acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); - if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) - printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n"); - printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address); -} - -static int __init acpi_sleep_setup(char *str) -{ - while ((str != NULL) && (*str != '\0')) { - if (strncmp(str, "s3_bios", 7) == 0) - acpi_video_flags = 1; - if (strncmp(str, "s3_mode", 7) == 0) - acpi_video_flags |= 2; - str = strchr(str, ','); - if (str != NULL) - str += strspn(str, ", \t"); - } - return 1; -} - - -__setup("acpi_sleep=", acpi_sleep_setup); -#endif /*CONFIG_ACPI_SLEEP*/ diff -Nru a/arch/i386/kernel/acpi_wakeup.S b/arch/i386/kernel/acpi_wakeup.S --- a/arch/i386/kernel/acpi_wakeup.S Fri Feb 14 00:27:27 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,323 +0,0 @@ -.text -#include -#include -#include - -# -# wakeup_code runs in real mode, and at unknown address (determined at run-time). -# Therefore it must only use relative jumps/calls. -# -# Do we need to deal with A20? It is okay: ACPI specs says A20 must be enabled -# -# If physical address of wakeup_code is 0x12345, BIOS should call us with -# cs = 0x1234, eip = 0x05 -# - -ALIGN - .align 4096 -ENTRY(wakeup_start) -wakeup_code: - wakeup_code_start = . - .code16 - - movw $0xb800, %ax - movw %ax,%fs - movw $0x0e00 + 'L', %fs:(0x10) - - cli - cld - - # setup data segment - movw %cs, %ax - movw %ax, %ds # Make ds:0 point to wakeup_start - movw %ax, %ss - mov wakeup_stack - wakeup_code, %sp # Private stack is needed for ASUS board - movw $0x0e00 + 'S', %fs:(0x12) - - pushl $0 # Kill any dangerous flags - popfl - - movl real_magic - wakeup_code, %eax - cmpl $0x12345678, %eax - jne bogus_real_magic - - testl $1, video_flags - wakeup_code - jz 1f - lcall $0xc000,$3 -1: - - testl $2, video_flags - wakeup_code - jz 1f - mov video_mode - wakeup_code, %ax - call mode_set -1: - - # set up page table - movl $swapper_pg_dir-__PAGE_OFFSET, %eax - movl %eax, %cr3 - - # make sure %cr4 is set correctly (features, etc) - movl real_save_cr4 - wakeup_code, %eax - movl %eax, %cr4 - movw $0xb800, %ax - movw %ax,%fs - movw $0x0e00 + 'i', %fs:(0x12) - - # need a gdt - lgdt real_save_gdt - wakeup_code - - movl real_save_cr0 - wakeup_code, %eax - movl %eax, %cr0 - jmp 1f -1: - movw $0x0e00 + 'n', %fs:(0x14) - - movl real_magic - wakeup_code, %eax - cmpl $0x12345678, %eax - jne bogus_real_magic - - ljmpl $__KERNEL_CS,$wakeup_pmode_return - -real_save_gdt: .word 0 - .long 0 -real_save_cr0: .long 0 -real_save_cr3: .long 0 -real_save_cr4: .long 0 -real_magic: .long 0 -video_mode: .long 0 -video_flags: .long 0 - -bogus_real_magic: - movw $0x0e00 + 'B', %fs:(0x12) - jmp bogus_real_magic - -/* This code uses an extended set of video mode numbers. These include: - * Aliases for standard modes - * NORMAL_VGA (-1) - * EXTENDED_VGA (-2) - * ASK_VGA (-3) - * Video modes numbered by menu position -- NOT RECOMMENDED because of lack - * of compatibility when extending the table. These are between 0x00 and 0xff. - */ -#define VIDEO_FIRST_MENU 0x0000 - -/* Standard BIOS video modes (BIOS number + 0x0100) */ -#define VIDEO_FIRST_BIOS 0x0100 - -/* VESA BIOS video modes (VESA number + 0x0200) */ -#define VIDEO_FIRST_VESA 0x0200 - -/* Video7 special modes (BIOS number + 0x0900) */ -#define VIDEO_FIRST_V7 0x0900 - -# Setting of user mode (AX=mode ID) => CF=success -mode_set: - movw %ax, %bx -#if 0 - cmpb $0xff, %ah - jz setalias - - testb $VIDEO_RECALC>>8, %ah - jnz _setrec - - cmpb $VIDEO_FIRST_RESOLUTION>>8, %ah - jnc setres - - cmpb $VIDEO_FIRST_SPECIAL>>8, %ah - jz setspc - - cmpb $VIDEO_FIRST_V7>>8, %ah - jz setv7 -#endif - - cmpb $VIDEO_FIRST_VESA>>8, %ah - jnc check_vesa -#if 0 - orb %ah, %ah - jz setmenu -#endif - - decb %ah -# jz setbios Add bios modes later - -setbad: clc - ret - -check_vesa: - subb $VIDEO_FIRST_VESA>>8, %bh - orw $0x4000, %bx # Use linear frame buffer - movw $0x4f02, %ax # VESA BIOS mode set call - int $0x10 - cmpw $0x004f, %ax # AL=4f if implemented - jnz _setbad # AH=0 if OK - - stc - ret - -_setbad: jmp setbad - - .code32 - ALIGN - - -.org 0x2000 -wakeup_stack: -.org 0x3000 -ENTRY(wakeup_end) -.org 0x4000 - -wakeup_pmode_return: - movl $__KERNEL_DS, %eax - movl %eax, %ds - movw $0x0e00 + 'u', %ds:(0xb8016) - - # restore other segment registers - xorl %eax, %eax - movw %ax, %fs - movw %ax, %gs - - # reload the gdt, as we need the full 32 bit address - lgdt saved_gdt - lidt saved_idt - lldt saved_ldt - ljmp $(__KERNEL_CS),$1f -1: - movl %cr3, %eax - movl %eax, %cr3 - wbinvd - - # and restore the stack ... but you need gdt for this to work - movl $__KERNEL_DS, %eax - movw %ax, %ss - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movl saved_esp, %esp - - movw $0x0e00 + 'W', %ds:(0xb8018) - movl $(1024*1024*3), %ecx - movl $0, %esi - rep lodsb - movw $0x0e00 + 'O', %ds:(0xb8018) - - movl %cs:saved_magic, %eax - cmpl $0x12345678, %eax - jne bogus_magic - - # restore the other general registers - movl saved_ebx, %ebx - movl saved_edi, %edi - movl saved_esi, %esi - movl saved_ebp, %ebp - - # jump to place where we left off - movl saved_eip,%eax - movw $0x0e00 + 'x', %ds:(0xb8018) - pushl %eax - popl %eax - movw $0x0e00 + '!', %ds:(0xb801a) - jmp *%eax - -bogus_magic: - movw $0x0e00 + 'B', %ds:(0xb8018) - jmp bogus_magic - -bogus_magic2: - movw $0x0e00 + '2', %ds:(0xb8018) - jmp bogus_magic2 - -## -# acpi_copy_wakeup_routine -# -# Copy the above routine to low memory. -# -# Parameters: -# %eax: place to copy wakeup routine to -# -# Returned address is location of code in low memory (past data and stack) -# -ENTRY(acpi_copy_wakeup_routine) - - sgdt saved_gdt - sidt saved_idt - sldt saved_ldt - str saved_tss - - movl %cr3, %edx - movl %edx, real_save_cr3 - wakeup_start (%eax) - movl %cr4, %edx - movl %edx, real_save_cr4 - wakeup_start (%eax) - movl %cr0, %edx - movl %edx, real_save_cr0 - wakeup_start (%eax) - sgdt real_save_gdt - wakeup_start (%eax) - - movl saved_videomode, %edx - movl %edx, video_mode - wakeup_start (%eax) - movl acpi_video_flags, %edx - movl %edx, video_flags - wakeup_start (%eax) - movl $0x12345678, real_magic - wakeup_start (%eax) - movl $0x12345678, saved_magic - ret - -.data -ALIGN -ENTRY(saved_ebp) .long 0 -ENTRY(saved_esi) .long 0 -ENTRY(saved_edi) .long 0 -ENTRY(saved_ebx) .long 0 - -ENTRY(saved_eip) .long 0 -ENTRY(saved_esp) .long 0 - -ENTRY(saved_magic) .long 0 - -ENTRY(do_suspend_lowlevel) - cmpl $0,4(%esp) - jne .L1432 - call save_processor_state - - movl %esp, saved_context_esp - movl %eax, saved_context_eax - movl %ebx, saved_context_ebx - movl %ecx, saved_context_ecx - movl %edx, saved_context_edx - movl %ebp, saved_context_ebp - movl %esi, saved_context_esi - movl %edi, saved_context_edi - pushfl ; popl saved_context_eflags - - movl $.L1432,saved_eip - movl %esp,saved_esp - movl %ebp,saved_ebp - movl %ebx,saved_ebx - movl %edi,saved_edi - movl %esi,saved_esi - - pushl $3 - call acpi_enter_sleep_state - addl $4,%esp - ret - .p2align 4,,7 -.L1432: - movl $__KERNEL_DS,%eax - movw %ax, %ds - movl saved_context_esp, %esp - movl saved_context_ebp, %ebp - movl saved_context_eax, %eax - movl saved_context_ebx, %ebx - movl saved_context_ecx, %ecx - movl saved_context_edx, %edx - movl saved_context_esi, %esi - movl saved_context_edi, %edi - call restore_processor_state - pushl saved_context_eflags ; popfl - ret - -ALIGN -# saved registers -saved_gdt: .long 0,0 -saved_idt: .long 0,0 -saved_ldt: .long 0 -saved_tss: .long 0 - diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c --- a/arch/i386/kernel/apic.c Fri Feb 14 00:27:30 2003 +++ b/arch/i386/kernel/apic.c Fri Feb 14 00:27:30 2003 @@ -52,7 +52,7 @@ int prof_multiplier[NR_CPUS] = { 1, }; int prof_old_multiplier[NR_CPUS] = { 1, }; -int prof_counter[NR_CPUS] = { 1, }; +DEFINE_PER_CPU(int, prof_counter) = 1; int get_maxlvt(void) { @@ -997,7 +997,7 @@ x86_do_profile(regs); - if (--prof_counter[cpu] <= 0) { + if (--per_cpu(prof_counter, cpu) <= 0) { /* * The multiplier may have changed since the last time we got * to this point as a result of the user writing to @@ -1006,10 +1006,12 @@ * * Interrupts are already masked off at this point. */ - prof_counter[cpu] = prof_multiplier[cpu]; - if (prof_counter[cpu] != prof_old_multiplier[cpu]) { - __setup_APIC_LVTT(calibration_result/prof_counter[cpu]); - prof_old_multiplier[cpu] = prof_counter[cpu]; + per_cpu(prof_counter, cpu) = prof_multiplier[cpu]; + if (per_cpu(prof_counter, cpu) != prof_old_multiplier[cpu]) { + __setup_APIC_LVTT( + calibration_result/ + per_cpu(prof_counter, cpu)); + prof_old_multiplier[cpu] = per_cpu(prof_counter, cpu); } #ifdef CONFIG_SMP diff -Nru a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c --- a/arch/i386/kernel/apm.c Fri Feb 14 00:27:26 2003 +++ b/arch/i386/kernel/apm.c Fri Feb 14 00:27:26 2003 @@ -226,8 +226,6 @@ #include #include -#include - extern spinlock_t i8253_lock; extern unsigned long get_cmos_time(void); extern void machine_real_restart(unsigned char *, int); @@ -972,30 +970,6 @@ (void) set_system_power_state(APM_STATE_OFF); } -/** - * handle_poweroff - sysrq callback for power down - * @key: key pressed (unused) - * @pt_regs: register state (unused) - * @kbd: keyboard state (unused) - * @tty: tty involved (unused) - * - * When the user hits Sys-Rq o to power down the machine this is the - * callback we use. - */ - -static void handle_poweroff (int key, struct pt_regs *pt_regs, - struct tty_struct *tty) -{ - apm_power_off(); -} - -static struct sysrq_key_op sysrq_poweroff_op = { - .handler = handle_poweroff, - .help_msg = "Off", - .action_msg = "Power Off\n" -}; - - #ifdef CONFIG_APM_DO_ENABLE /** @@ -1742,11 +1716,9 @@ kapmd_running = 1; - daemonize(); + daemonize("kapmd"); - strcpy(current->comm, "kapmd"); current->flags |= PF_IOTHREAD; - sigfillset(¤t->blocked); #ifdef CONFIG_SMP /* 2002/08/01 - WT @@ -1850,7 +1822,6 @@ /* Install our power off handler.. */ if (power_off) pm_power_off = apm_power_off; - register_sysrq_key('o', &sysrq_poweroff_op); if (num_online_cpus() == 1 || smp) { #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) @@ -2098,7 +2069,6 @@ } misc_deregister(&apm_device); remove_proc_entry("apm", NULL); - unregister_sysrq_key('o',&sysrq_poweroff_op); if (power_off) pm_power_off = NULL; exit_kapmd = 1; diff -Nru a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c --- a/arch/i386/kernel/cpu/centaur.c Fri Feb 14 00:27:29 2003 +++ b/arch/i386/kernel/cpu/centaur.c Fri Feb 14 00:27:29 2003 @@ -395,6 +395,8 @@ set_bit(X86_FEATURE_CX8, c->x86_capability); set_bit(X86_FEATURE_3DNOW, c->x86_capability); + case 9: /* Nehemiah */ + default: get_model_name(c); display_cacheinfo(c); break; @@ -408,6 +410,12 @@ /* VIA C3 CPUs (670-68F) need further shifting. */ if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8))) size >>= 8; + + /* VIA also screwed up Nehemiah stepping 1, and made + it return '65KB' instead of '64KB' */ + if ((c->x86==6) && (c->x86_model==9) && (c->x86_mask==1)) + size -=1; + return size; } diff -Nru a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile --- a/arch/i386/kernel/cpu/cpufreq/Makefile Fri Feb 14 00:27:28 2003 +++ b/arch/i386/kernel/cpu/cpufreq/Makefile Fri Feb 14 00:27:28 2003 @@ -1,4 +1,5 @@ obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o +obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o obj-$(CONFIG_X86_LONGHAUL) += longhaul.o obj-$(CONFIG_X86_SPEEDSTEP) += speedstep.o obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o diff -Nru a/arch/i386/kernel/cpu/cpufreq/elanfreq.c b/arch/i386/kernel/cpu/cpufreq/elanfreq.c --- a/arch/i386/kernel/cpu/cpufreq/elanfreq.c Fri Feb 14 00:27:28 2003 +++ b/arch/i386/kernel/cpu/cpufreq/elanfreq.c Fri Feb 14 00:27:28 2003 @@ -242,6 +242,8 @@ NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); if (!driver) return -ENOMEM; + memset(driver, 0, sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy)); driver->policy = (struct cpufreq_policy *) (driver + 1); @@ -260,8 +262,6 @@ driver->verify = &elanfreq_verify; driver->setpolicy = &elanfreq_setpolicy; - driver->init = NULL; - driver->exit = NULL; strncpy(driver->name, "elanfreq", CPUFREQ_NAME_LEN); driver->policy[0].cpu = 0; diff -Nru a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c --- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c Fri Feb 14 00:27:28 2003 +++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c Fri Feb 14 00:27:28 2003 @@ -431,11 +431,15 @@ driver = kmalloc(sizeof(struct cpufreq_driver) + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); if (driver == NULL) return -ENOMEM; + memset(driver, 0, sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy)); + params = kmalloc(sizeof(struct gxfreq_params), GFP_KERNEL); if (params == NULL) { kfree(driver); return -ENOMEM; } + memset(params, 0, sizeof(struct gxfreq_params)); driver->policy = (struct cpufreq_policy *)(driver + 1); params->cs55x0 = gx_pci; diff -Nru a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c Fri Feb 14 00:27:26 2003 +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c Fri Feb 14 00:27:26 2003 @@ -762,6 +762,8 @@ NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); if (!driver) return -ENOMEM; + memset(driver, 0, sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy)); driver->policy = (struct cpufreq_policy *) (driver + 1); @@ -771,8 +773,7 @@ driver->verify = &longhaul_verify; driver->setpolicy = &longhaul_setpolicy; - driver->init = NULL; - driver->exit = NULL; + strncpy(driver->name, "longhaul", CPUFREQ_NAME_LEN); driver->policy[0].cpu = 0; diff -Nru a/arch/i386/kernel/cpu/cpufreq/longrun.c b/arch/i386/kernel/cpu/cpufreq/longrun.c --- a/arch/i386/kernel/cpu/cpufreq/longrun.c Fri Feb 14 00:27:29 2003 +++ b/arch/i386/kernel/cpu/cpufreq/longrun.c Fri Feb 14 00:27:29 2003 @@ -54,7 +54,7 @@ policy->min = longrun_low_freq + msr_lo * ((longrun_high_freq - longrun_low_freq) / 100); - policy->min = longrun_low_freq + msr_hi * + policy->max = longrun_low_freq + msr_hi * ((longrun_high_freq - longrun_low_freq) / 100); policy->cpu = 0; } @@ -241,6 +241,8 @@ NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); if (!driver) return -ENOMEM; + memset(driver, 0, sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy)); driver->policy = (struct cpufreq_policy *) (driver + 1); @@ -251,8 +253,7 @@ driver->policy[0].cpuinfo.min_freq = longrun_low_freq; driver->policy[0].cpuinfo.max_freq = longrun_high_freq; driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL; - driver->init = NULL; - driver->exit = NULL; + strncpy(driver->name, "longrun", CPUFREQ_NAME_LEN); longrun_get_policy(&driver->policy[0]); diff -Nru a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c Fri Feb 14 00:27:30 2003 +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c Fri Feb 14 00:27:30 2003 @@ -220,6 +220,8 @@ NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); if (!driver) return -ENOMEM; + memset(driver, 0, sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy)); driver->policy = (struct cpufreq_policy *) (driver + 1); @@ -240,8 +242,6 @@ driver->verify = &cpufreq_p4_verify; driver->setpolicy = &cpufreq_p4_setpolicy; - driver->init = NULL; - driver->exit = NULL; strncpy(driver->name, "p4-clockmod", CPUFREQ_NAME_LEN); for (i=0;ipolicy = (struct cpufreq_policy *) (driver + 1); /* table init */ @@ -184,8 +186,6 @@ driver->verify = &powernow_k6_verify; driver->setpolicy = &powernow_k6_setpolicy; - driver->init = NULL; - driver->exit = NULL; strncpy(driver->name, "powernow-k6", CPUFREQ_NAME_LEN); /* cpuinfo and default policy values */ diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c Fri Feb 14 00:27:30 2003 @@ -0,0 +1,408 @@ +/* + * $Id: powernow-k7.c,v 1.31 2003/02/12 21:16:35 davej Exp $ + * + * (C) 2003 Dave Jones + * + * Licensed under the terms of the GNU GPL License version 2. + * Based upon datasheets & sample CPUs kindly provided by AMD. + * + * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* + * + * Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt. + * - We cli/sti on stepping A0 CPUs around the FID/VID transition. + * Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect. + * - We disable half multipliers if ACPI is used on A0 stepping CPUs. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "powernow-k7.h" + +#define DEBUG + +#ifdef DEBUG +#define dprintk(msg...) printk(msg) +#else +#define dprintk(msg...) do { } while(0); +#endif + +#define PFX "powernow: " + + +struct psb_s { + u8 signature[10]; + u8 tableversion; + u8 flags; + u16 settlingtime; + u8 reserved1; + u8 numpst; +}; + +struct pst_s { + u32 cpuid; + u8 fsbspeed; + u8 maxfid; + u8 startvid; + u8 numpstates; +}; + + +/* divide by 1000 to get VID. */ +static int mobile_vid_table[32] = { + 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, + 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0, + 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, + 1075, 1050, 1024, 1000, 975, 950, 925, 0, +}; + +/* divide by 10 to get FID. */ +static int fid_codes[32] = { + 110, 115, 120, 125, 50, 55, 60, 65, + 70, 75, 80, 85, 90, 95, 10, 105, + 30, 190, 40, 200, 130, 135, 140, 210, + 150, 225, 160, 165, 170, 180, -1, -1, +}; + +static struct cpufreq_driver powernow_driver; + +static struct cpufreq_frequency_table *powernow_table; + +static unsigned int can_scale_bus; +static unsigned int can_scale_vid; +static unsigned int minimum_speed=-1; +static unsigned int maximum_speed; +static unsigned int number_scales; +static unsigned int fsb; +static unsigned int latency; +static char have_a0; + + +#ifndef rdmsrl +#define rdmsrl(msr,val) do {unsigned long l__,h__; \ + rdmsr (msr, l__, h__); \ + val = l__; \ + val |= ((u64)h__<<32); \ +} while(0); +#endif + +#ifndef wrmsrl +static void wrmsrl (u32 msr, u64 val) +{ + u32 lo, hi; + + lo = (u32) val; + hi = val >> 32; + wrmsr (msr, lo, hi); +} +#endif + + + +static int check_powernow(void) +{ + struct cpuinfo_x86 *c = cpu_data; + unsigned int maxei, eax, ebx, ecx, edx; + + if (c->x86_vendor != X86_VENDOR_AMD) { + printk (KERN_INFO PFX "AMD processor not detected.\n"); + return 0; + } + + if (c->x86 !=6) { + printk (KERN_INFO PFX "This module only works with AMD K7 CPUs\n"); + return 0; + } + + printk (KERN_INFO PFX "AMD K7 CPU detected.\n"); + + if ((c->x86_model == 6) && (c->x86_mask == 0)) { + printk (KERN_INFO PFX "K7 660[A0] core detected, enabling errata workarounds\n"); + have_a0 = 1; + } + + /* Get maximum capabilities */ + maxei = cpuid_eax (0x80000000); + if (maxei < 0x80000007) { /* Any powernow info ? */ + printk (KERN_INFO PFX "No powernow capabilities detected\n"); + return 0; + } + + cpuid(0x80000007, &eax, &ebx, &ecx, &edx); + printk (KERN_INFO PFX "PowerNOW! Technology present. Can scale: "); + + if (edx & 1 << 1) { + printk ("frequency"); + can_scale_bus=1; + } + + if ((edx & (1 << 1 | 1 << 2)) == 0x6) + printk (" and "); + + if (edx & 1 << 2) { + printk ("voltage"); + can_scale_vid=1; + } + + if (!(edx & (1 << 1 | 1 << 2))) { + printk (" nothing.\n"); + return 0; + } + + printk (".\n"); + return 1; +} + + +static int get_ranges (unsigned char *pst) +{ + int j; + u8 fid, vid; + unsigned int speed; + + powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL); + if (!powernow_table) + return -ENOMEM; + memset(powernow_table, 0, (sizeof(struct cpufreq_frequency_table) * (number_scales + 1))); + + for (j=0 ; j < number_scales; j++) { + fid = *pst++; + + powernow_table[j].frequency = fsb * fid_codes[fid] * 100; + powernow_table[j].index = fid; /* lower 8 bits */ + + speed = fsb * (fid_codes[fid]/10); + if ((fid_codes[fid] % 10)==5) { + speed += fsb/2; +#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE) + if (have_a0 == 1) + powernow_table[j].frequency = CPUFREQ_ENTRY_INVALID; +#endif + } + + dprintk (KERN_INFO PFX " FID: 0x%x (%d.%dx [%dMHz])\t", fid, + fid_codes[fid] / 10, fid_codes[fid] % 10, speed); + + if (speed < minimum_speed) + minimum_speed = speed; + if (speed > maximum_speed) + maximum_speed = speed; + + vid = *pst++; + powernow_table[j].index |= (vid << 8); /* upper 8 bits */ + dprintk ("VID: 0x%x (%d.%03dV)\n", vid, mobile_vid_table[vid]/1000, + mobile_vid_table[vid]%1000); + } + dprintk ("\n"); + + powernow_table[number_scales].frequency = CPUFREQ_TABLE_END; + powernow_table[number_scales].index = 0; + + return 0; +} + + +static void change_speed (unsigned int index) +{ + u8 fid, vid; + struct cpufreq_freqs freqs; + union msr_fidvidstatus fidvidstatus; + union msr_fidvidctl fidvidctl; + + + /* fid are the lower 8 bits of the index we stored into + * the cpufreq frequency table in powernow_decode_bios, + * vid are the upper 8 bits. + */ + + fid = powernow_table[index].index & 0xFF; + vid = (powernow_table[index].index & 0xFF00) >> 8; + + freqs.cpu = 0; + + rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); + freqs.old = fsb * fid_codes[fidvidstatus.bits.CFID] * 100; + + freqs.new = powernow_table[index].frequency; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + /* Now do the magic poking into the MSRs. */ + + if (have_a0 == 1) /* A0 errata 5 */ + __asm__("\tcli\n"); + rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val); + fidvidctl.bits.SGTC = latency; /* Stop grant timeout counter */ + fidvidctl.bits.FID = fid; + fidvidctl.bits.VID = vid; + /* Note, we could set these lazily. Ie, only do voltage transition + if its changed since last time (Some speeds have the same voltage) */ + fidvidctl.bits.FIDC = 1; + fidvidctl.bits.VIDC = 1; + wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val); + if (have_a0 == 1) + __asm__("\tsti\n"); + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); +} + + +int powernow_decode_bios (int maxfid, int startvid) +{ + struct psb_s *psb; + struct pst_s *pst; + struct cpuinfo_x86 *c = cpu_data; + unsigned int i, j; + unsigned char *p; + unsigned int etuple; + unsigned int ret; + + etuple = cpuid_eax(0x80000001); + etuple &= 0xf00; + etuple |= (c->x86_model<<4)|(c->x86_mask); + + for (i=0xC0000; i < 0xffff0 ; i+=16) { + + p = phys_to_virt(i); + + if (memcmp(p, "AMDK7PNOW!", 10) == 0){ + dprintk (KERN_INFO PFX "Found PSB header at %p\n", p); + psb = (struct psb_s *) p; + dprintk (KERN_INFO PFX "Table version: 0x%x\n", psb->tableversion); + if (psb->tableversion != 0x12) { + printk (KERN_INFO PFX "Sorry, only v1.2 tables supported right now\n"); + return -ENODEV; + } + + dprintk (KERN_INFO PFX "Flags: 0x%x (", psb->flags); + if ((psb->flags & 1)==0) { + dprintk ("Mobile"); + } else { + dprintk ("Desktop"); + } + dprintk (" voltage regulator)\n"); + + latency = psb->settlingtime; + dprintk (KERN_INFO PFX "Settling Time: %d microseconds.\n", psb->settlingtime); + dprintk (KERN_INFO PFX "Has %d PST tables. (Only dumping ones relevant to this CPU).\n", psb->numpst); + + p += sizeof (struct psb_s); + + pst = (struct pst_s *) p; + + for (i = 0 ; i numpst; i++) { + pst = (struct pst_s *) p; + number_scales = pst->numpstates; + + if ((etuple == pst->cpuid) && (maxfid==pst->maxfid) && (startvid==pst->startvid)) + { + dprintk (KERN_INFO PFX "PST:%d (@%p)\n", i, pst); + dprintk (KERN_INFO PFX " cpuid: 0x%x\t", pst->cpuid); + dprintk ("fsb: %d\t", pst->fsbspeed); + dprintk ("maxFID: 0x%x\t", pst->maxfid); + dprintk ("startvid: 0x%x\n", pst->startvid); + + fsb = pst->fsbspeed; + ret = get_ranges ((char *) pst + sizeof (struct pst_s)); + return ret; + + } else { + p = (char *) pst + sizeof (struct pst_s); + for (j=0 ; j < number_scales; j++) + p+=2; + } + } + return -EINVAL; + } + p++; + } + + return -ENODEV; +} + + +static int powernow_target (struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int newstate; + + if (cpufreq_frequency_table_target(policy, powernow_table, target_freq, relation, &newstate)) + return -EINVAL; + + change_speed(newstate); + + return 0; +} + + +static int powernow_verify (struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, powernow_table); +} + + +static int __init powernow_cpu_init (struct cpufreq_policy *policy) +{ + union msr_fidvidstatus fidvidstatus; + int result; + + if (policy->cpu != 0) + return -ENODEV; + + rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); + + result = powernow_decode_bios(fidvidstatus.bits.MFID, fidvidstatus.bits.SVID); + if (result) + return result; + + printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n", + minimum_speed, maximum_speed); + + policy->policy = CPUFREQ_POLICY_PERFORMANCE; + policy->cpuinfo.transition_latency = latency; +#ifdef CONFIG_CPU_FREQ_24_API + powernow_driver.cpu_cur_freq[policy->cpu] = maximum_speed; +#endif + + return cpufreq_frequency_table_cpuinfo(policy, powernow_table); +} + +static int __init powernow_init (void) +{ + if (check_powernow()==0) + return -ENODEV; + return cpufreq_register_driver(&powernow_driver); +} + + +static void __exit powernow_exit (void) +{ + cpufreq_unregister_driver(&powernow_driver); + if (powernow_table) + kfree(powernow_table); +} + +static struct cpufreq_driver powernow_driver = { + .verify = powernow_verify, + .target = powernow_target, + .init = powernow_cpu_init, + .name = "powernow-k7", +}; + + +MODULE_AUTHOR ("Dave Jones "); +MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors."); +MODULE_LICENSE ("GPL"); + +module_init(powernow_init); +module_exit(powernow_exit); + diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k7.h b/arch/i386/kernel/cpu/cpufreq/powernow-k7.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.h Fri Feb 14 00:27:30 2003 @@ -0,0 +1,52 @@ +/* + * $Id: powernow-k7.h,v 1.2 2003/02/10 18:26:01 davej Exp $ + * (C) 2003 Dave Jones. + * + * Licensed under the terms of the GNU GPL License version 2. + * + * AMD-specific information + * + */ + +#ifndef MSR_K7_FID_VID_CTL +#define MSR_K7_FID_VID_CTL 0xc0010041 +#endif +#ifndef MSR_K7_FID_VID_STATUS +#define MSR_K7_FID_VID_STATUS 0xc0010042 +#endif + + +union msr_fidvidctl { + struct { + unsigned FID:5, // 4:0 + reserved1:3, // 7:5 + VID:5, // 12:8 + reserved2:3, // 15:13 + FIDC:1, // 16 + VIDC:1, // 17 + reserved3:2, // 19:18 + FIDCHGRATIO:1, // 20 + reserved4:11, // 31-21 + SGTC:20, // 32:51 + reserved5:12; // 63:52 + } bits; + unsigned long long val; +}; + +union msr_fidvidstatus { + struct { + unsigned CFID:5, // 4:0 + reserved1:3, // 7:5 + SFID:5, // 12:8 + reserved2:3, // 15:13 + MFID:5, // 20:16 + reserved3:11, // 31:21 + CVID:5, // 36:32 + reserved4:3, // 39:37 + SVID:5, // 44:40 + reserved5:3, // 47:45 + MVID:5, // 52:48 + reserved6:11; // 63:53 + } bits; + unsigned long long val; +}; diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep.c b/arch/i386/kernel/cpu/cpufreq/speedstep.c --- a/arch/i386/kernel/cpu/cpufreq/speedstep.c Fri Feb 14 00:27:26 2003 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep.c Fri Feb 14 00:27:26 2003 @@ -674,6 +674,8 @@ NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); if (!driver) return -ENOMEM; + memset(driver, 0, sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy)); driver->policy = (struct cpufreq_policy *) (driver + 1); @@ -690,8 +692,6 @@ driver->verify = &speedstep_verify; driver->setpolicy = &speedstep_setpolicy; - driver->init = NULL; - driver->exit = NULL; strncpy(driver->name, "speedstep", CPUFREQ_NAME_LEN); driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL; diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c --- a/arch/i386/kernel/io_apic.c Fri Feb 14 00:27:27 2003 +++ b/arch/i386/kernel/io_apic.c Fri Feb 14 00:27:27 2003 @@ -510,9 +510,8 @@ int i; unsigned long prev_balance_time = jiffies; long time_remaining = balanced_irq_interval; - daemonize(); - sigfillset(¤t->blocked); - sprintf(current->comm, "kirqd"); + + daemonize("kirqd"); /* push everything to CPU 0 to give us a starting point. */ for (i = 0 ; i < NR_IRQS ; i++) @@ -1440,7 +1439,8 @@ * by Matt Domsch Tue Dec 21 12:25:05 CST 1999 */ -static void __init setup_ioapic_ids_from_mpc (void) +#ifndef CONFIG_X86_NUMAQ +static void __init setup_ioapic_ids_from_mpc(void) { struct IO_APIC_reg_00 reg_00; unsigned long phys_id_present_map; @@ -1533,6 +1533,9 @@ printk(" ok.\n"); } } +#else +static void __init setup_ioapic_ids_from_mpc(void) { } +#endif /* * There is a nasty bug in some older SMP boards, their mptable lies diff -Nru a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c --- a/arch/i386/kernel/nmi.c Fri Feb 14 00:27:28 2003 +++ b/arch/i386/kernel/nmi.c Fri Feb 14 00:27:28 2003 @@ -63,8 +63,6 @@ CRU_ESCR0 (with any non-null event selector) through a complemented max threshold. [IA32-Vol3, Section 14.9.9] */ #define MSR_P4_IQ_COUNTER0 0x30C -#define MSR_P4_IQ_CCCR0 0x36C -#define MSR_P4_CRU_ESCR0 0x3B8 #define P4_NMI_CRU_ESCR0 (P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR) #define P4_NMI_IQ_CCCR0 \ (P4_CCCR_OVF_PMI|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ diff -Nru a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c --- a/arch/i386/kernel/ptrace.c Fri Feb 14 00:27:27 2003 +++ b/arch/i386/kernel/ptrace.c Fri Feb 14 00:27:27 2003 @@ -530,11 +530,9 @@ return; /* the 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ - current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0); - current->state = TASK_STOPPED; - notify_parent(current, SIGCHLD); - schedule(); + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + ? 0x80 : 0)); + /* * this isn't the same as continuing with a signal, but it will do * for normal use. strace only continues with a signal if the diff -Nru a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c --- a/arch/i386/kernel/signal.c Fri Feb 14 00:27:28 2003 +++ b/arch/i386/kernel/signal.c Fri Feb 14 00:27:28 2003 @@ -582,7 +582,7 @@ if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { /* Reenable any watchpoints before delivering the * signal to user space. The processor register will diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c --- a/arch/i386/kernel/smpboot.c Fri Feb 14 00:27:28 2003 +++ b/arch/i386/kernel/smpboot.c Fri Feb 14 00:27:28 2003 @@ -160,7 +160,6 @@ goto valid_k7; /* If we get here, it's not a certified SMP capable AMD system. */ - printk (KERN_INFO "WARNING: This combination of AMD processors is not suitable for SMP.\n"); tainted |= TAINT_UNSAFE_SMP; } @@ -182,8 +181,6 @@ #define NR_LOOPS 5 -extern unsigned long fast_gettimeoffset_quotient; - /* * accurate 64-bit/32-bit division, expanded to 32-bit divisions and 64-bit * multiplication. Not terribly optimized but we need it at boot time only @@ -223,7 +220,8 @@ printk("checking TSC synchronization across %u CPUs: ", num_booting_cpus()); - one_usec = ((1<<30)/fast_gettimeoffset_quotient)*(1<<2); + /* convert from kcyc/sec to cyc/usec */ + one_usec = cpu_khz / 1000; atomic_set(&tsc_start_flag, 1); wmb(); @@ -935,10 +933,6 @@ * Cycle through the processors sending APIC IPIs to boot each. */ -extern int prof_multiplier[NR_CPUS]; -extern int prof_old_multiplier[NR_CPUS]; -extern int prof_counter[NR_CPUS]; - static int boot_cpu_logical_apicid; /* Where the IO area was mapped on multiquad, always 0 otherwise */ void *xquad_portio; @@ -950,17 +944,6 @@ int apicid, cpu, bit; /* - * Initialize the logical to physical CPU number mapping - * and the per-CPU profiling counter/multiplier - */ - - for (cpu = 0; cpu < NR_CPUS; cpu++) { - prof_counter[cpu] = 1; - prof_old_multiplier[cpu] = 1; - prof_multiplier[cpu] = 1; - } - - /* * Setup boot CPU information */ smp_store_cpu_info(0); /* Final full version of the data */ @@ -1084,6 +1067,15 @@ if (smp_b_stepping) printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n"); + + /* Don't taint if we are running SMP kernel on a single non-MP approved Athlon */ + if (tainted & TAINT_UNSAFE_SMP) { + if (cpucount) + printk (KERN_INFO "WARNING: This combination of AMD processors is not suitable for SMP.\n"); + else + tainted &= ~TAINT_UNSAFE_SMP; + } + Dprintk("Boot done.\n"); /* diff -Nru a/arch/i386/kernel/timers/Makefile b/arch/i386/kernel/timers/Makefile --- a/arch/i386/kernel/timers/Makefile Fri Feb 14 00:27:26 2003 +++ b/arch/i386/kernel/timers/Makefile Fri Feb 14 00:27:26 2003 @@ -4,4 +4,4 @@ obj-y := timer.o timer_none.o timer_tsc.o timer_pit.o -obj-$(CONFIG_X86_CYCLONE) += timer_cyclone.o +obj-$(CONFIG_X86_SUMMIT) += timer_cyclone.o diff -Nru a/arch/i386/kernel/timers/timer.c b/arch/i386/kernel/timers/timer.c --- a/arch/i386/kernel/timers/timer.c Fri Feb 14 00:27:30 2003 +++ b/arch/i386/kernel/timers/timer.c Fri Feb 14 00:27:30 2003 @@ -4,9 +4,14 @@ /* list of externed timers */ extern struct timer_opts timer_pit; extern struct timer_opts timer_tsc; - +#ifdef CONFIG_X86_SUMMIT +extern struct timer_opts timer_cyclone; +#endif /* list of timers, ordered by preference, NULL terminated */ static struct timer_opts* timers[] = { +#ifdef CONFIG_X86_SUMMIT + &timer_cyclone, +#endif &timer_tsc, &timer_pit, NULL, diff -Nru a/arch/i386/kernel/timers/timer_cyclone.c b/arch/i386/kernel/timers/timer_cyclone.c --- a/arch/i386/kernel/timers/timer_cyclone.c Fri Feb 14 00:27:29 2003 +++ b/arch/i386/kernel/timers/timer_cyclone.c Fri Feb 14 00:27:29 2003 @@ -17,6 +17,7 @@ #include extern spinlock_t i8253_lock; +extern unsigned long calibrate_tsc(void); /* Number of usecs that the last interrupt was delayed */ static int delay_at_last_interrupt; @@ -142,6 +143,27 @@ printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n"); cyclone_timer = 0; return -ENODEV; + } + } + + /* init cpu_khz. + * XXX - This should really be done elsewhere, + * and in a more generic fashion. -johnstul@us.ibm.com + */ + if (cpu_has_tsc) { + unsigned long tsc_quotient = calibrate_tsc(); + if (tsc_quotient) { + /* report CPU clock rate in Hz. + * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = + * clock/second. Our precision is about 100 ppm. + */ + { unsigned long eax=0, edx=1000; + __asm__("divl %2" + :"=a" (cpu_khz), "=d" (edx) + :"r" (tsc_quotient), + "0" (eax), "1" (edx)); + printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); + } } } diff -Nru a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c --- a/arch/i386/kernel/timers/timer_tsc.c Fri Feb 14 00:27:29 2003 +++ b/arch/i386/kernel/timers/timer_tsc.c Fri Feb 14 00:27:29 2003 @@ -29,7 +29,7 @@ * Equal to 2^32 * (1 / (clocks per usec) ). * Initialized in time_init. */ -unsigned long fast_gettimeoffset_quotient; +static unsigned long fast_gettimeoffset_quotient; static unsigned long get_offset_tsc(void) { @@ -130,7 +130,7 @@ #define CALIBRATE_LATCH (5 * LATCH) #define CALIBRATE_TIME (5 * 1000020/HZ) -static unsigned long __init calibrate_tsc(void) +unsigned long __init calibrate_tsc(void) { /* Set the Gate high, disable speaker */ outb((inb(0x61) & ~0x02) | 0x01, 0x61); diff -Nru a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c --- a/arch/i386/mach-voyager/voyager_smp.c Fri Feb 14 00:27:28 2003 +++ b/arch/i386/mach-voyager/voyager_smp.c Fri Feb 14 00:27:28 2003 @@ -236,7 +236,7 @@ /* The per cpu profile stuff - used in smp_local_timer_interrupt */ static unsigned int prof_multiplier[NR_CPUS] __cacheline_aligned = { 1, }; static unsigned int prof_old_multiplier[NR_CPUS] __cacheline_aligned = { 1, }; -static unsigned int prof_counter[NR_CPUS] __cacheline_aligned = { 1, }; +static DEFINE_PER_CPU(unsigned int, prof_counter) = 1; /* the map used to check if a CPU has booted */ static __u32 cpu_booted_map; @@ -393,9 +393,6 @@ /* initialize the CPU structures (moved from smp_boot_cpus) */ for(i=0; icomm, THREAD_NAME); sigfillset(¤t->blocked); current->tty = NULL; /* get rid of controlling tty */ diff -Nru a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c --- a/arch/i386/mm/hugetlbpage.c Fri Feb 14 00:27:30 2003 +++ b/arch/i386/mm/hugetlbpage.c Fri Feb 14 00:27:30 2003 @@ -88,6 +88,18 @@ set_pte(page_table, entry); } +/* + * This function checks for proper alignment of input addr and len parameters. + */ +int is_aligned_hugepage_range(unsigned long addr, unsigned long len) +{ + if (len & ~HPAGE_MASK) + return -EINVAL; + if (addr & ~HPAGE_MASK) + return -EINVAL; + return 0; +} + int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma) { @@ -284,7 +296,6 @@ int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) { struct mm_struct *mm = current->mm; - struct inode *inode = mapping->host; unsigned long addr; int ret = 0; @@ -308,7 +319,6 @@ + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); page = find_get_page(mapping, idx); if (!page) { - loff_t i_size; page = alloc_hugetlb_page(); if (!page) { ret = -ENOMEM; @@ -320,9 +330,6 @@ free_huge_page(page); goto out; } - i_size = (loff_t)(idx + 1) * HPAGE_SIZE; - if (i_size > inode->i_size) - inode->i_size = i_size; } set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE); } diff -Nru a/arch/i386/oprofile/Makefile b/arch/i386/oprofile/Makefile --- a/arch/i386/oprofile/Makefile Fri Feb 14 00:27:30 2003 +++ b/arch/i386/oprofile/Makefile Fri Feb 14 00:27:30 2003 @@ -7,4 +7,4 @@ oprofile-y := $(DRIVER_OBJS) init.o timer_int.o oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o \ - op_model_ppro.o + op_model_ppro.o op_model_p4.o diff -Nru a/arch/i386/oprofile/init.c b/arch/i386/oprofile/init.c --- a/arch/i386/oprofile/init.c Fri Feb 14 00:27:28 2003 +++ b/arch/i386/oprofile/init.c Fri Feb 14 00:27:28 2003 @@ -16,14 +16,14 @@ * code unlike the NMI-based code. */ -extern int nmi_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu); -extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu); +extern int nmi_init(struct oprofile_operations ** ops); +extern void timer_init(struct oprofile_operations ** ops); -int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +int __init oprofile_arch_init(struct oprofile_operations ** ops) { #ifdef CONFIG_X86_LOCAL_APIC - if (!nmi_init(ops, cpu)) + if (!nmi_init(ops)) #endif - timer_init(ops, cpu); + timer_init(ops); return 0; } diff -Nru a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c --- a/arch/i386/oprofile/nmi_int.c Fri Feb 14 00:27:30 2003 +++ b/arch/i386/oprofile/nmi_int.c Fri Feb 14 00:27:30 2003 @@ -214,12 +214,62 @@ .stop = nmi_stop }; + +#if !defined(CONFIG_X86_64) + +static int __init p4_init(void) +{ + __u8 cpu_model = current_cpu_data.x86_model; + + if (cpu_model > 3) + return 0; + +#ifndef CONFIG_SMP + nmi_ops.cpu_type = "i386/p4"; + model = &op_p4_spec; + return 1; +#else + switch (smp_num_siblings) { + case 1: + nmi_ops.cpu_type = "i386/p4"; + model = &op_p4_spec; + return 1; + + case 2: + nmi_ops.cpu_type = "i386/p4-ht"; + model = &op_p4_ht2_spec; + return 1; + } +#endif + + printk(KERN_INFO "oprofile: P4 HyperThreading detected with > 2 threads\n"); + printk(KERN_INFO "oprofile: Reverting to timer mode.\n"); + return 0; +} + + +static int __init ppro_init(void) +{ + __u8 cpu_model = current_cpu_data.x86_model; + + if (cpu_model > 5) { + nmi_ops.cpu_type = "i386/piii"; + } else if (cpu_model > 2) { + nmi_ops.cpu_type = "i386/pii"; + } else { + nmi_ops.cpu_type = "i386/ppro"; + } + + model = &op_ppro_spec; + return 1; +} + +#endif /* !CONFIG_X86_64 */ -int __init nmi_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +int __init nmi_init(struct oprofile_operations ** ops) { __u8 vendor = current_cpu_data.x86_vendor; __u8 family = current_cpu_data.x86; - __u8 cpu_model = current_cpu_data.x86_model; if (!cpu_has_apic) return 0; @@ -230,26 +280,29 @@ if (family < 6) return 0; model = &op_athlon_spec; - *cpu = OPROFILE_CPU_ATHLON; + nmi_ops.cpu_type = "i386/athlon"; break; -#ifndef CONFIG_X86_64 +#if !defined(CONFIG_X86_64) case X86_VENDOR_INTEL: - /* Less than a P6-class processor */ - if (family != 6) - return 0; - - if (cpu_model > 5) { - *cpu = OPROFILE_CPU_PIII; - } else if (cpu_model > 2) { - *cpu = OPROFILE_CPU_PII; - } else { - *cpu = OPROFILE_CPU_PPRO; + switch (family) { + /* Pentium IV */ + case 0xf: + if (!p4_init()) + return 0; + break; + + /* A P6-class processor */ + case 6: + if (!ppro_init()) + return 0; + break; + + default: + return 0; } - - model = &op_ppro_spec; break; -#endif +#endif /* !CONFIG_X86_64 */ default: return 0; diff -Nru a/arch/i386/oprofile/op_counter.h b/arch/i386/oprofile/op_counter.h --- a/arch/i386/oprofile/op_counter.h Fri Feb 14 00:27:28 2003 +++ b/arch/i386/oprofile/op_counter.h Fri Feb 14 00:27:28 2003 @@ -10,7 +10,7 @@ #ifndef OP_COUNTER_H #define OP_COUNTER_H -#define OP_MAX_COUNTER 4 +#define OP_MAX_COUNTER 8 /* Per-perfctr configuration as set via * oprofilefs. diff -Nru a/arch/i386/oprofile/op_model_athlon.c b/arch/i386/oprofile/op_model_athlon.c --- a/arch/i386/oprofile/op_model_athlon.c Fri Feb 14 00:27:29 2003 +++ b/arch/i386/oprofile/op_model_athlon.c Fri Feb 14 00:27:29 2003 @@ -96,10 +96,13 @@ { unsigned int low, high; int i; + unsigned long eip = instruction_pointer(regs); + int is_kernel = !user_mode(regs); + for (i = 0 ; i < NUM_COUNTERS; ++i) { CTR_READ(low, high, msrs, i); if (CTR_OVERFLOWED(low)) { - oprofile_add_sample(instruction_pointer(regs), i, cpu); + oprofile_add_sample(eip, is_kernel, i, cpu); CTR_WRITE(reset_value[i], msrs, i); return 1; } diff -Nru a/arch/i386/oprofile/op_model_p4.c b/arch/i386/oprofile/op_model_p4.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/oprofile/op_model_p4.c Fri Feb 14 00:27:30 2003 @@ -0,0 +1,673 @@ +/** + * @file op_model_p4.c + * P4 model-specific MSR operations + * + * @remark Copyright 2002 OProfile authors + * @remark Read the file COPYING + * + * @author Graydon Hoare + */ + +#include +#include +#include +#include +#include +#include + +#include "op_x86_model.h" +#include "op_counter.h" + +#define NUM_EVENTS 39 + +#define NUM_COUNTERS_NON_HT 8 +#define NUM_ESCRS_NON_HT 45 +#define NUM_CCCRS_NON_HT 18 +#define NUM_CONTROLS_NON_HT (NUM_ESCRS_NON_HT + NUM_CCCRS_NON_HT) + +#define NUM_COUNTERS_HT2 4 +#define NUM_ESCRS_HT2 23 +#define NUM_CCCRS_HT2 9 +#define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2) + +static unsigned int num_counters = NUM_COUNTERS_NON_HT; +static unsigned int num_cccrs = NUM_CCCRS_NON_HT; + + +/* this has to be checked dynamically since the + hyper-threadedness of a chip is discovered at + kernel boot-time. */ +static inline void setup_num_counters(void) +{ +#ifdef CONFIG_SMP + if (smp_num_siblings == 2) { + num_counters = NUM_COUNTERS_HT2; + num_cccrs = NUM_CCCRS_HT2; + } +#endif +} + + +/* tables to simulate simplified hardware view of p4 registers */ +struct p4_counter_binding { + int virt_counter; + int counter_address; + int cccr_address; +}; + +struct p4_event_binding { + int escr_select; /* value to put in CCCR */ + int event_select; /* value to put in ESCR */ + struct { + int virt_counter; /* for this counter... */ + int escr_address; /* use this ESCR */ + } bindings[2]; +}; + +/* nb: these CTR_* defines are a duplicate of defines in + libop/op_events.c. */ + + +#define CTR_BPU_0 (1 << 0) +#define CTR_MS_0 (1 << 1) +#define CTR_FLAME_0 (1 << 2) +#define CTR_IQ_4 (1 << 3) +#define CTR_BPU_2 (1 << 4) +#define CTR_MS_2 (1 << 5) +#define CTR_FLAME_2 (1 << 6) +#define CTR_IQ_5 (1 << 7) + +static struct p4_counter_binding p4_counters [NUM_COUNTERS_NON_HT] = { + { CTR_BPU_0, MSR_P4_BPU_PERFCTR0, MSR_P4_BPU_CCCR0 }, + { CTR_MS_0, MSR_P4_MS_PERFCTR0, MSR_P4_MS_CCCR0 }, + { CTR_FLAME_0, MSR_P4_FLAME_PERFCTR0, MSR_P4_FLAME_CCCR0 }, + { CTR_IQ_4, MSR_P4_IQ_PERFCTR4, MSR_P4_IQ_CCCR4 }, + { CTR_BPU_2, MSR_P4_BPU_PERFCTR2, MSR_P4_BPU_CCCR2 }, + { CTR_MS_2, MSR_P4_MS_PERFCTR2, MSR_P4_MS_CCCR2 }, + { CTR_FLAME_2, MSR_P4_FLAME_PERFCTR2, MSR_P4_FLAME_CCCR2 }, + { CTR_IQ_5, MSR_P4_IQ_PERFCTR5, MSR_P4_IQ_CCCR5 } +}; + +/* p4 event codes in libop/op_event.h are indices into this table. */ + +static struct p4_event_binding p4_events[NUM_EVENTS] = { + + { /* BRANCH_RETIRED */ + 0x05, 0x06, + { {CTR_IQ_4, MSR_P4_CRU_ESCR2}, + {CTR_IQ_5, MSR_P4_CRU_ESCR3} } + }, + + { /* MISPRED_BRANCH_RETIRED */ + 0x04, 0x03, + { { CTR_IQ_4, MSR_P4_CRU_ESCR0}, + { CTR_IQ_5, MSR_P4_CRU_ESCR1} } + }, + + { /* TC_DELIVER_MODE */ + 0x01, 0x01, + { { CTR_MS_0, MSR_P4_TC_ESCR0}, + { CTR_MS_2, MSR_P4_TC_ESCR1} } + }, + + { /* BPU_FETCH_REQUEST */ + 0x00, 0x03, + { { CTR_BPU_0, MSR_P4_BPU_ESCR0}, + { CTR_BPU_2, MSR_P4_BPU_ESCR1} } + }, + + { /* ITLB_REFERENCE */ + 0x03, 0x18, + { { CTR_BPU_0, MSR_P4_ITLB_ESCR0}, + { CTR_BPU_2, MSR_P4_ITLB_ESCR1} } + }, + + { /* MEMORY_CANCEL */ + 0x05, 0x02, + { { CTR_FLAME_0, MSR_P4_DAC_ESCR0}, + { CTR_FLAME_2, MSR_P4_DAC_ESCR1} } + }, + + { /* MEMORY_COMPLETE */ + 0x02, 0x08, + { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0}, + { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} } + }, + + { /* LOAD_PORT_REPLAY */ + 0x02, 0x04, + { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0}, + { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} } + }, + + { /* STORE_PORT_REPLAY */ + 0x02, 0x05, + { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0}, + { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} } + }, + + { /* MOB_LOAD_REPLAY */ + 0x02, 0x03, + { { CTR_BPU_0, MSR_P4_MOB_ESCR0}, + { CTR_BPU_2, MSR_P4_MOB_ESCR1} } + }, + + { /* PAGE_WALK_TYPE */ + 0x04, 0x01, + { { CTR_BPU_0, MSR_P4_PMH_ESCR0}, + { CTR_BPU_2, MSR_P4_PMH_ESCR1} } + }, + + { /* BSQ_CACHE_REFERENCE */ + 0x07, 0x0c, + { { CTR_BPU_0, MSR_P4_BSU_ESCR0}, + { CTR_BPU_2, MSR_P4_BSU_ESCR1} } + }, + + { /* IOQ_ALLOCATION */ + 0x06, 0x03, + { { CTR_BPU_0, MSR_P4_FSB_ESCR0}, + {-1,-1} } + }, + + { /* IOQ_ACTIVE_ENTRIES */ + 0x06, 0x1a, + { { CTR_BPU_2, MSR_P4_FSB_ESCR1}, + {-1,-1} } + }, + + { /* FSB_DATA_ACTIVITY */ + 0x06, 0x17, + { { CTR_BPU_0, MSR_P4_FSB_ESCR0}, + { CTR_BPU_2, MSR_P4_FSB_ESCR1} } + }, + + { /* BSQ_ALLOCATION */ + 0x07, 0x05, + { { CTR_BPU_0, MSR_P4_BSU_ESCR0}, + {-1,-1} } + }, + + { /* BSQ_ACTIVE_ENTRIES */ + 0x07, 0x06, + { { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */}, + {-1,-1} } + }, + + { /* X87_ASSIST */ + 0x05, 0x03, + { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, + { CTR_IQ_5, MSR_P4_CRU_ESCR3} } + }, + + { /* SSE_INPUT_ASSIST */ + 0x01, 0x34, + { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, + { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } + }, + + { /* PACKED_SP_UOP */ + 0x01, 0x08, + { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, + { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } + }, + + { /* PACKED_DP_UOP */ + 0x01, 0x0c, + { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, + { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } + }, + + { /* SCALAR_SP_UOP */ + 0x01, 0x0a, + { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, + { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } + }, + + { /* SCALAR_DP_UOP */ + 0x01, 0x0e, + { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, + { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } + }, + + { /* 64BIT_MMX_UOP */ + 0x01, 0x02, + { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, + { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } + }, + + { /* 128BIT_MMX_UOP */ + 0x01, 0x1a, + { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, + { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } + }, + + { /* X87_FP_UOP */ + 0x01, 0x04, + { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, + { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } + }, + + { /* X87_SIMD_MOVES_UOP */ + 0x01, 0x2e, + { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, + { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } + }, + + { /* MACHINE_CLEAR */ + 0x05, 0x02, + { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, + { CTR_IQ_5, MSR_P4_CRU_ESCR3} } + }, + + { /* GLOBAL_POWER_EVENTS */ + 0x06, 0x13 /* manual says 0x05 */, + { { CTR_BPU_0, MSR_P4_FSB_ESCR0}, + { CTR_BPU_2, MSR_P4_FSB_ESCR1} } + }, + + { /* TC_MS_XFER */ + 0x00, 0x05, + { { CTR_MS_0, MSR_P4_MS_ESCR0}, + { CTR_MS_2, MSR_P4_MS_ESCR1} } + }, + + { /* UOP_QUEUE_WRITES */ + 0x00, 0x09, + { { CTR_MS_0, MSR_P4_MS_ESCR0}, + { CTR_MS_2, MSR_P4_MS_ESCR1} } + }, + + { /* FRONT_END_EVENT */ + 0x05, 0x08, + { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, + { CTR_IQ_5, MSR_P4_CRU_ESCR3} } + }, + + { /* EXECUTION_EVENT */ + 0x05, 0x0c, + { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, + { CTR_IQ_5, MSR_P4_CRU_ESCR3} } + }, + + { /* REPLAY_EVENT */ + 0x05, 0x09, + { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, + { CTR_IQ_5, MSR_P4_CRU_ESCR3} } + }, + + { /* INSTR_RETIRED */ + 0x04, 0x02, + { { CTR_IQ_4, MSR_P4_CRU_ESCR0}, + { CTR_IQ_5, MSR_P4_CRU_ESCR1} } + }, + + { /* UOPS_RETIRED */ + 0x04, 0x01, + { { CTR_IQ_4, MSR_P4_CRU_ESCR0}, + { CTR_IQ_5, MSR_P4_CRU_ESCR1} } + }, + + { /* UOP_TYPE */ + 0x02, 0x02, + { { CTR_IQ_4, MSR_P4_RAT_ESCR0}, + { CTR_IQ_5, MSR_P4_RAT_ESCR1} } + }, + + { /* RETIRED_MISPRED_BRANCH_TYPE */ + 0x02, 0x05, + { { CTR_MS_0, MSR_P4_TBPU_ESCR0}, + { CTR_MS_2, MSR_P4_TBPU_ESCR1} } + }, + + { /* RETIRED_BRANCH_TYPE */ + 0x02, 0x04, + { { CTR_MS_0, MSR_P4_TBPU_ESCR0}, + { CTR_MS_2, MSR_P4_TBPU_ESCR1} } + } +}; + + +#define MISC_PMC_ENABLED_P(x) ((x) & 1 << 7) + +#define ESCR_RESERVED_BITS 0x80000003 +#define ESCR_CLEAR(escr) ((escr) &= ESCR_RESERVED_BITS) +#define ESCR_SET_USR_0(escr, usr) ((escr) |= (((usr) & 1) << 2)) +#define ESCR_SET_OS_0(escr, os) ((escr) |= (((os) & 1) << 3)) +#define ESCR_SET_USR_1(escr, usr) ((escr) |= (((usr) & 1))) +#define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1)) +#define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x1f) << 25)) +#define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9)) +#define ESCR_READ(escr,high,ev,i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0); +#define ESCR_WRITE(escr,high,ev,i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0); + +#define CCCR_RESERVED_BITS 0x38030FFF +#define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS) +#define CCCR_SET_REQUIRED_BITS(cccr) ((cccr) |= 0x00030000) +#define CCCR_SET_ESCR_SELECT(cccr, sel) ((cccr) |= (((sel) & 0x07) << 13)) +#define CCCR_SET_PMI_OVF_0(cccr) ((cccr) |= (1<<26)) +#define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27)) +#define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12)) +#define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12)) +#define CCCR_READ(low, high, i) do {rdmsr (p4_counters[(i)].cccr_address, (low), (high));} while (0); +#define CCCR_WRITE(low, high, i) do {wrmsr (p4_counters[(i)].cccr_address, (low), (high));} while (0); +#define CCCR_OVF_P(cccr) ((cccr) & (1U<<31)) +#define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31))) + +#define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0); +#define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0); +#define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000)) + +/* these access the underlying cccrs 1-18, not the subset of 8 bound to "virtual counters" */ +#define RAW_CCCR_READ(low, high, i) do {rdmsr (MSR_P4_BPU_CCCR0 + (i), (low), (high));} while (0); +#define RAW_CCCR_WRITE(low, high, i) do {wrmsr (MSR_P4_BPU_CCCR0 + (i), (low), (high));} while (0); + + +/* this assigns a "stagger" to the current CPU, which is used throughout + the code in this module as an extra array offset, to select the "even" + or "odd" part of all the divided resources. */ +static inline unsigned int get_stagger(void) +{ +#ifdef CONFIG_SMP + int cpu; + if (smp_num_siblings > 1) { + cpu = smp_processor_id(); + return (cpu_sibling_map[cpu] > cpu) ? 0 : 1; + } +#endif + return 0; +} + + +/* finally, mediate access to a real hardware counter + by passing a "virtual" counter numer to this macro, + along with your stagger setting. */ +#define VIRT_CTR(stagger, i) ((i) + ((num_counters) * (stagger))) + +static unsigned long reset_value[NUM_COUNTERS_NON_HT]; + + +static void p4_fill_in_addresses(struct op_msrs * const msrs) +{ + int i; + unsigned int addr, stag; + + setup_num_counters(); + stag = get_stagger(); + + /* the 8 counter registers we pay attention to */ + for (i = 0; i < num_counters; ++i) + msrs->counters.addrs[i] = + p4_counters[VIRT_CTR(stag, i)].counter_address; + + /* 18 CCCR registers */ + for (i=stag, addr = MSR_P4_BPU_CCCR0; + addr <= MSR_P4_IQ_CCCR5; ++i, addr += (1 + stag)) + msrs->controls.addrs[i] = addr; + + /* 43 ESCR registers */ + for (addr = MSR_P4_BSU_ESCR0; + addr <= MSR_P4_SSU_ESCR0; ++i, addr += (1 + stag)){ + msrs->controls.addrs[i] = addr; + } + + for (addr = MSR_P4_MS_ESCR0; + addr <= MSR_P4_TC_ESCR1; ++i, addr += (1 + stag)){ + msrs->controls.addrs[i] = addr; + } + + for (addr = MSR_P4_IX_ESCR0; + addr <= MSR_P4_CRU_ESCR3; ++i, addr += (1 + stag)){ + msrs->controls.addrs[i] = addr; + } + + /* there are 2 remaining non-contiguously located ESCRs */ + + if (num_counters == NUM_COUNTERS_NON_HT) { + /* standard non-HT CPUs handle both remaining ESCRs*/ + msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR5; + msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR4; + + } else if (stag == 0) { + /* HT CPUs give the first remainder to the even thread, as + the 32nd control register */ + msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR4; + + } else { + /* and two copies of the second to the odd thread, + for the 31st and 32nd control registers */ + msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR5; + msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR5; + } +} + + +static void pmc_setup_one_p4_counter(unsigned int ctr) +{ + int i; + int const maxbind = 2; + unsigned int cccr = 0; + unsigned int escr = 0; + unsigned int high = 0; + unsigned int counter_bit; + struct p4_event_binding * ev = 0; + unsigned int stag; + + stag = get_stagger(); + + /* convert from counter *number* to counter *bit* */ + counter_bit = 1 << ctr; + + /* find our event binding structure. */ + if (counter_config[ctr].event <= 0 || counter_config[ctr].event > NUM_EVENTS) { + printk(KERN_ERR + "oprofile: P4 event code 0x%lx out of range\n", + counter_config[ctr].event); + return; + } + + ev = &(p4_events[counter_config[ctr].event - 1]); + + for (i = 0; i < maxbind; i++) { + if (ev->bindings[i].virt_counter & counter_bit) { + + /* modify ESCR */ + ESCR_READ(escr, high, ev, i); + ESCR_CLEAR(escr); + if (stag == 0) { + ESCR_SET_USR_0(escr, counter_config[ctr].user); + ESCR_SET_OS_0(escr, counter_config[ctr].kernel); + } else { + ESCR_SET_USR_1(escr, counter_config[ctr].user); + ESCR_SET_OS_1(escr, counter_config[ctr].kernel); + } + ESCR_SET_EVENT_SELECT(escr, ev->event_select); + ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask); + ESCR_WRITE(escr, high, ev, i); + + /* modify CCCR */ + CCCR_READ(cccr, high, VIRT_CTR(stag, ctr)); + CCCR_CLEAR(cccr); + CCCR_SET_REQUIRED_BITS(cccr); + CCCR_SET_ESCR_SELECT(cccr, ev->escr_select); + if (stag == 0) { + CCCR_SET_PMI_OVF_0(cccr); + } else { + CCCR_SET_PMI_OVF_1(cccr); + } + CCCR_WRITE(cccr, high, VIRT_CTR(stag, ctr)); + return; + } + } +} + + +static void p4_setup_ctrs(struct op_msrs const * const msrs) +{ + unsigned int i; + unsigned int low, high; + unsigned int addr; + unsigned int stag; + + stag = get_stagger(); + + rdmsr(MSR_IA32_MISC_ENABLE, low, high); + if (! MISC_PMC_ENABLED_P(low)) { + printk(KERN_ERR "oprofile: P4 PMC not available\n"); + return; + } + + /* clear all cccrs (including those outside our concern) */ + for (i = stag ; i < num_cccrs ; i += (1 + stag)) { + RAW_CCCR_READ(low, high, i); + CCCR_CLEAR(low); + CCCR_SET_REQUIRED_BITS(low); + RAW_CCCR_WRITE(low, high, i); + } + + /* clear all escrs (including those outside out concern) */ + for (addr = MSR_P4_BSU_ESCR0 + stag; + addr <= MSR_P4_SSU_ESCR0; addr += (1 + stag)){ + wrmsr(addr, 0, 0); + } + + for (addr = MSR_P4_MS_ESCR0 + stag; + addr <= MSR_P4_TC_ESCR1; addr += (1 + stag)){ + wrmsr(addr, 0, 0); + } + + for (addr = MSR_P4_IX_ESCR0 + stag; + addr <= MSR_P4_CRU_ESCR3; addr += (1 + stag)){ + wrmsr(addr, 0, 0); + } + + if (num_counters == NUM_COUNTERS_NON_HT) { + wrmsr(MSR_P4_CRU_ESCR4, 0, 0); + wrmsr(MSR_P4_CRU_ESCR5, 0, 0); + } else if (stag == 0) { + wrmsr(MSR_P4_CRU_ESCR4, 0, 0); + } else { + wrmsr(MSR_P4_CRU_ESCR5, 0, 0); + } + + /* setup all counters */ + for (i = 0 ; i < num_counters ; ++i) { + if (counter_config[i].event) { + reset_value[i] = counter_config[i].count; + pmc_setup_one_p4_counter(i); + CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i)); + } else { + reset_value[i] = 0; + } + } +} + + +static int p4_check_ctrs(unsigned int const cpu, + struct op_msrs const * const msrs, + struct pt_regs * const regs) +{ + unsigned long ctr, low, high, stag, real; + int i; + unsigned long eip = instruction_pointer(regs); + int is_kernel = !user_mode(regs); + + stag = get_stagger(); + + for (i = 0; i < num_counters; ++i) { + + if (!counter_config[i].event) + continue; + + /* + * there is some eccentricity in the hardware which + * requires that we perform 2 extra corrections: + * + * - check both the CCCR:OVF flag for overflow and the + * counter high bit for un-flagged overflows. + * + * - write the counter back twice to ensure it gets + * updated properly. + * + * the former seems to be related to extra NMIs happening + * during the current NMI; the latter is reported as errata + * N15 in intel doc 249199-029, pentium 4 specification + * update, though their suggested work-around does not + * appear to solve the problem. + */ + + real = VIRT_CTR(stag, i); + + CCCR_READ(low, high, real); + CTR_READ(ctr, high, real); + if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) { + oprofile_add_sample(eip, is_kernel, i, cpu); + CTR_WRITE(reset_value[i], real); + CCCR_CLEAR_OVF(low); + CCCR_WRITE(low, high, real); + CTR_WRITE(reset_value[i], real); + /* P4 quirk: you have to re-unmask the apic vector */ + apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); + return 1; + } + } + + /* P4 quirk: you have to re-unmask the apic vector */ + apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); + return 0; +} + + +static void p4_start(struct op_msrs const * const msrs) +{ + unsigned int low, high, stag; + int i; + + stag = get_stagger(); + + for (i = 0; i < num_counters; ++i) { + if (!reset_value[i]) + continue; + CCCR_READ(low, high, VIRT_CTR(stag, i)); + CCCR_SET_ENABLE(low); + CCCR_WRITE(low, high, VIRT_CTR(stag, i)); + } +} + + +static void p4_stop(struct op_msrs const * const msrs) +{ + unsigned int low, high, stag; + int i; + + stag = get_stagger(); + + for (i = 0; i < num_counters; ++i) { + CCCR_READ(low, high, VIRT_CTR(stag, i)); + CCCR_SET_DISABLE(low); + CCCR_WRITE(low, high, VIRT_CTR(stag, i)); + } +} + + +#ifdef CONFIG_SMP +struct op_x86_model_spec const op_p4_ht2_spec = { + .num_counters = NUM_COUNTERS_HT2, + .num_controls = NUM_CONTROLS_HT2, + .fill_in_addresses = &p4_fill_in_addresses, + .setup_ctrs = &p4_setup_ctrs, + .check_ctrs = &p4_check_ctrs, + .start = &p4_start, + .stop = &p4_stop +}; +#endif + +struct op_x86_model_spec const op_p4_spec = { + .num_counters = NUM_COUNTERS_NON_HT, + .num_controls = NUM_CONTROLS_NON_HT, + .fill_in_addresses = &p4_fill_in_addresses, + .setup_ctrs = &p4_setup_ctrs, + .check_ctrs = &p4_check_ctrs, + .start = &p4_start, + .stop = &p4_stop +}; diff -Nru a/arch/i386/oprofile/op_model_ppro.c b/arch/i386/oprofile/op_model_ppro.c --- a/arch/i386/oprofile/op_model_ppro.c Fri Feb 14 00:27:29 2003 +++ b/arch/i386/oprofile/op_model_ppro.c Fri Feb 14 00:27:29 2003 @@ -90,11 +90,13 @@ { unsigned int low, high; int i; + unsigned long eip = instruction_pointer(regs); + int is_kernel = !user_mode(regs); for (i = 0 ; i < NUM_COUNTERS; ++i) { CTR_READ(low, high, msrs, i); if (CTR_OVERFLOWED(low)) { - oprofile_add_sample(instruction_pointer(regs), i, cpu); + oprofile_add_sample(eip, is_kernel, i, cpu); CTR_WRITE(reset_value[i], msrs, i); return 1; } diff -Nru a/arch/i386/oprofile/op_x86_model.h b/arch/i386/oprofile/op_x86_model.h --- a/arch/i386/oprofile/op_x86_model.h Fri Feb 14 00:27:27 2003 +++ b/arch/i386/oprofile/op_x86_model.h Fri Feb 14 00:27:27 2003 @@ -11,8 +11,8 @@ #ifndef OP_X86_MODEL_H #define OP_X86_MODEL_H -/* will need re-working for Pentium IV */ -#define MAX_MSR 4 +/* Pentium IV needs all these */ +#define MAX_MSR 63 struct op_saved_msr { unsigned int high; @@ -47,6 +47,8 @@ }; extern struct op_x86_model_spec const op_ppro_spec; +extern struct op_x86_model_spec const op_p4_spec; +extern struct op_x86_model_spec const op_p4_ht2_spec; extern struct op_x86_model_spec const op_athlon_spec; #endif /* OP_X86_MODEL_H */ diff -Nru a/arch/i386/oprofile/timer_int.c b/arch/i386/oprofile/timer_int.c --- a/arch/i386/oprofile/timer_int.c Fri Feb 14 00:27:27 2003 +++ b/arch/i386/oprofile/timer_int.c Fri Feb 14 00:27:27 2003 @@ -20,8 +20,9 @@ { struct pt_regs * regs = (struct pt_regs *)data; int cpu = smp_processor_id(); + unsigned long eip = instruction_pointer(regs); - oprofile_add_sample(instruction_pointer(regs), 0, cpu); + oprofile_add_sample(eip, !user_mode(regs), 0, cpu); return 0; } @@ -45,13 +46,13 @@ static struct oprofile_operations timer_ops = { .start = timer_start, - .stop = timer_stop + .stop = timer_stop, + .cpu_type = "timer" }; -void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +void __init timer_init(struct oprofile_operations ** ops) { *ops = &timer_ops; - *cpu = OPROFILE_CPU_TIMER; printk(KERN_INFO "oprofile: using timer interrupt.\n"); } diff -Nru a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c --- a/arch/ia64/kernel/signal.c Fri Feb 14 00:27:28 2003 +++ b/arch/ia64/kernel/signal.c Fri Feb 14 00:27:28 2003 @@ -517,7 +517,7 @@ restart = 0; while (1) { - int signr = get_signal_to_deliver(&info, &scr->pt); + int signr = get_signal_to_deliver(&info, &scr->pt, NULL); if (signr <= 0) break; diff -Nru a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c --- a/arch/ia64/mm/hugetlbpage.c Fri Feb 14 00:27:28 2003 +++ b/arch/ia64/mm/hugetlbpage.c Fri Feb 14 00:27:28 2003 @@ -96,6 +96,18 @@ return; } +/* + * This function checks for proper alignment of input addr and len parameters. + */ +int is_aligned_hugepage_range(unsigned long addr, unsigned long len) +{ + if (len & ~HPAGE_MASK) + return -EINVAL; + if (addr & ~HPAGE_MASK) + return -EINVAL; + return 0; +} + int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma) { diff -Nru a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c --- a/arch/m68k/kernel/signal.c Fri Feb 14 00:27:29 2003 +++ b/arch/m68k/kernel/signal.c Fri Feb 14 00:27:29 2003 @@ -1004,7 +1004,7 @@ for (;;) { int signr; - signr = dequeue_signal(¤t->blocked, &info); + signr = dequeue_signal(current, ¤t->blocked, &info); if (!signr) break; diff -Nru a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c --- a/arch/m68knommu/kernel/signal.c Fri Feb 14 00:27:29 2003 +++ b/arch/m68knommu/kernel/signal.c Fri Feb 14 00:27:29 2003 @@ -768,7 +768,7 @@ for (;;) { int signr; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (!signr) break; diff -Nru a/arch/mips/baget/vacserial.c b/arch/mips/baget/vacserial.c --- a/arch/mips/baget/vacserial.c Fri Feb 14 00:27:29 2003 +++ b/arch/mips/baget/vacserial.c Fri Feb 14 00:27:29 2003 @@ -1785,7 +1785,7 @@ schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } current->state = TASK_RUNNING; diff -Nru a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c --- a/arch/mips/kernel/irixsig.c Fri Feb 14 00:27:29 2003 +++ b/arch/mips/kernel/irixsig.c Fri Feb 14 00:27:29 2003 @@ -183,7 +183,7 @@ unsigned long signr; spin_lock_irq(¤t->sigmask_lock); - signr = dequeue_signal(¤t->blocked, &info); + signr = dequeue_signal(current, ¤t->blocked, &info); spin_unlock_irq(¤t->sigmask_lock); if (!signr) diff -Nru a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c --- a/arch/mips/kernel/signal.c Fri Feb 14 00:27:29 2003 +++ b/arch/mips/kernel/signal.c Fri Feb 14 00:27:29 2003 @@ -544,7 +544,7 @@ if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { if (regs->regs[0]) syscall_restart(regs, ka); diff -Nru a/arch/mips64/kernel/signal.c b/arch/mips64/kernel/signal.c --- a/arch/mips64/kernel/signal.c Fri Feb 14 00:27:27 2003 +++ b/arch/mips64/kernel/signal.c Fri Feb 14 00:27:27 2003 @@ -602,7 +602,7 @@ if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { if (regs->regs[0]) syscall_restart(regs, ka); diff -Nru a/arch/mips64/kernel/signal32.c b/arch/mips64/kernel/signal32.c --- a/arch/mips64/kernel/signal32.c Fri Feb 14 00:27:28 2003 +++ b/arch/mips64/kernel/signal32.c Fri Feb 14 00:27:28 2003 @@ -676,7 +676,7 @@ if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { if (regs->regs[0]) syscall_restart(regs, ka); diff -Nru a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c --- a/arch/parisc/kernel/binfmt_elf32.c Fri Feb 14 00:27:28 2003 +++ b/arch/parisc/kernel/binfmt_elf32.c Fri Feb 14 00:27:28 2003 @@ -19,7 +19,7 @@ #include #include #include -#include +#include /* struct compat_timeval */ #define elf_prstatus elf_prstatus32 struct elf_prstatus32 diff -Nru a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c --- a/arch/parisc/kernel/signal.c Fri Feb 14 00:27:30 2003 +++ b/arch/parisc/kernel/signal.c Fri Feb 14 00:27:30 2003 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -97,13 +98,13 @@ sigset_t saveset, newset; #ifdef __LP64__ /* XXX FIXME -- assumes 32-bit user app! */ - sigset_t32 newset32; + compat_sigset_t newset32; /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset_t32)) + if (sigsetsize != sizeof(compat_sigset_t)) return -EINVAL; - if (copy_from_user(&newset32, (sigset_t32 *)unewset, sizeof(newset32))) + if (copy_from_user(&newset32, (compat_sigset_t *)unewset, sizeof(newset32))) return -EFAULT; newset.sig[0] = newset32.sig[0] | ((unsigned long)newset32.sig[1] << 32); diff -Nru a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c --- a/arch/parisc/kernel/signal32.c Fri Feb 14 00:27:27 2003 +++ b/arch/parisc/kernel/signal32.c Fri Feb 14 00:27:27 2003 @@ -18,22 +18,22 @@ }; static inline void -sigset_32to64(sigset_t *s64, sigset_t32 *s32) +sigset_32to64(sigset_t *s64, compat_sigset_t *s32) { s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32); } static inline void -sigset_64to32(sigset_t32 *s32, sigset_t *s64) +sigset_64to32(compat_sigset_t *s32, sigset_t *s64) { s32->sig[0] = s64->sig[0] & 0xffffffffUL; s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL; } static int -put_sigset32(sigset_t32 *up, sigset_t *set, size_t sz) +put_sigset32(compat_sigset_t *up, sigset_t *set, size_t sz) { - sigset_t32 s; + compat_sigset_t s; if (sz != sizeof *set) panic("put_sigset32()"); sigset_64to32(&s, set); @@ -42,9 +42,9 @@ } static int -get_sigset32(sigset_t32 *up, sigset_t *set, size_t sz) +get_sigset32(compat_sigset_t *up, sigset_t *set, size_t sz) { - sigset_t32 s; + compat_sigset_t s; int r; if (sz != sizeof *set) panic("put_sigset32()"); @@ -56,7 +56,7 @@ return r; } -int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, +int sys32_rt_sigprocmask(int how, compat_sigset_t *set, compat_sigset_t *oset, unsigned int sigsetsize) { extern long sys_rt_sigprocmask(int how, @@ -78,7 +78,7 @@ } -int sys32_rt_sigpending(sigset_t32 *uset, unsigned int sigsetsize) +int sys32_rt_sigpending(compat_sigset_t *uset, unsigned int sigsetsize) { int ret; sigset_t set; diff -Nru a/arch/parisc/kernel/sys32.h b/arch/parisc/kernel/sys32.h --- a/arch/parisc/kernel/sys32.h Fri Feb 14 00:27:28 2003 +++ b/arch/parisc/kernel/sys32.h Fri Feb 14 00:27:28 2003 @@ -14,15 +14,10 @@ typedef __u32 __sighandler_t32; -#include -typedef struct { - unsigned int sig[_NSIG_WORDS * 2]; -} sigset_t32; - struct sigaction32 { __sighandler_t32 sa_handler; unsigned int sa_flags; - sigset_t32 sa_mask; /* mask last for extensibility */ + compat_sigset_t sa_mask; /* mask last for extensibility */ }; #endif diff -Nru a/arch/parisc/oprofile/init.c b/arch/parisc/oprofile/init.c --- a/arch/parisc/oprofile/init.c Fri Feb 14 00:27:28 2003 +++ b/arch/parisc/oprofile/init.c Fri Feb 14 00:27:28 2003 @@ -11,10 +11,10 @@ #include #include -extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu); +extern void timer_init(struct oprofile_operations ** ops); -int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +int __init oprofile_arch_init(struct oprofile_operations ** ops) { - timer_init(ops, cpu); + timer_init(ops); return 0; } diff -Nru a/arch/parisc/oprofile/timer_int.c b/arch/parisc/oprofile/timer_int.c --- a/arch/parisc/oprofile/timer_int.c Fri Feb 14 00:27:26 2003 +++ b/arch/parisc/oprofile/timer_int.c Fri Feb 14 00:27:26 2003 @@ -19,8 +19,10 @@ { struct pt_regs * regs = (struct pt_regs *)data; int cpu = smp_processor_id(); + unsigned long pc = regs->iaoq[0]; + int is_kernel = !user_mode(regs); - oprofile_add_sample(regs->iaoq[0], 0, cpu); + oprofile_add_sample(pc, is_kernel, 0, cpu); return 0; } @@ -44,13 +46,13 @@ static struct oprofile_operations timer_ops = { .start = timer_start, - .stop = timer_stop + .stop = timer_stop, + .cpu_type = "timer" }; -void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +void __init timer_init(struct oprofile_operations ** ops) { *ops = &timer_ops; - *cpu = OPROFILE_CPU_TIMER; printk(KERN_INFO "oprofile: using timer interrupt.\n"); } diff -Nru a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c --- a/arch/ppc/kernel/signal.c Fri Feb 14 00:27:30 2003 +++ b/arch/ppc/kernel/signal.c Fri Feb 14 00:27:30 2003 @@ -484,7 +484,7 @@ newsp = frame = 0; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { ka = ¤t->sig->action[signr-1]; if ( (ka->sa.sa_flags & SA_ONSTACK) diff -Nru a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c --- a/arch/ppc64/kernel/rtasd.c Fri Feb 14 00:27:27 2003 +++ b/arch/ppc64/kernel/rtasd.c Fri Feb 14 00:27:27 2003 @@ -211,9 +211,7 @@ DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2); - daemonize(); - sigfillset(¤t->blocked); - sprintf(current->comm, "rtasd"); + daemonize("rtasd"); #if 0 /* Rusty unreal time task */ diff -Nru a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c --- a/arch/ppc64/kernel/signal.c Fri Feb 14 00:27:26 2003 +++ b/arch/ppc64/kernel/signal.c Fri Feb 14 00:27:26 2003 @@ -551,7 +551,7 @@ newsp = frame = 0; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { ka = ¤t->sighand->action[signr-1]; if ((ka->sa.sa_flags & SA_ONSTACK) diff -Nru a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c --- a/arch/ppc64/kernel/signal32.c Fri Feb 14 00:27:30 2003 +++ b/arch/ppc64/kernel/signal32.c Fri Feb 14 00:27:30 2003 @@ -1063,7 +1063,7 @@ newsp = frame = 0; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { ka = ¤t->sighand->action[signr-1]; if ((ka->sa.sa_flags & SA_ONSTACK) diff -Nru a/arch/ppc64/oprofile/init.c b/arch/ppc64/oprofile/init.c --- a/arch/ppc64/oprofile/init.c Fri Feb 14 00:27:28 2003 +++ b/arch/ppc64/oprofile/init.c Fri Feb 14 00:27:28 2003 @@ -11,10 +11,10 @@ #include #include -extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu); +extern void timer_init(struct oprofile_operations ** ops); -int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +int __init oprofile_arch_init(struct oprofile_operations ** ops) { - timer_init(ops, cpu); + timer_init(ops); return 0; } diff -Nru a/arch/ppc64/oprofile/timer_int.c b/arch/ppc64/oprofile/timer_int.c --- a/arch/ppc64/oprofile/timer_int.c Fri Feb 14 00:27:30 2003 +++ b/arch/ppc64/oprofile/timer_int.c Fri Feb 14 00:27:30 2003 @@ -19,8 +19,10 @@ { struct pt_regs * regs = (struct pt_regs *)data; int cpu = smp_processor_id(); + unsigned long pc = instruction_pointer(regs); + int is_kernel = !user_mode(regs); - oprofile_add_sample(instruction_pointer(regs), 0, cpu); + oprofile_add_sample(pc, is_kernel, 0, cpu); return 0; } @@ -44,13 +46,13 @@ static struct oprofile_operations timer_ops = { .start = timer_start, - .stop = timer_stop + .stop = timer_stop, + .cpu_type = "timer" }; -void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +void __init timer_init(struct oprofile_operations ** ops) { *ops = &timer_ops; - *cpu = OPROFILE_CPU_TIMER; printk(KERN_INFO "oprofile: using timer interrupt.\n"); } diff -Nru a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c --- a/arch/s390/kernel/signal.c Fri Feb 14 00:27:29 2003 +++ b/arch/s390/kernel/signal.c Fri Feb 14 00:27:29 2003 @@ -461,7 +461,7 @@ if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, oldset, regs); diff -Nru a/arch/s390x/kernel/linux32.c b/arch/s390x/kernel/linux32.c --- a/arch/s390x/kernel/linux32.c Fri Feb 14 00:27:29 2003 +++ b/arch/s390x/kernel/linux32.c Fri Feb 14 00:27:29 2003 @@ -1726,7 +1726,7 @@ } spin_lock_irq(¤t->sighand->siglock); - sig = dequeue_signal(&these, &info); + sig = dequeue_signal(current, &these, &info); if (!sig) { /* None ready -- temporarily unblock those we're interested in so that we'll be awakened when they arrive. */ @@ -1744,7 +1744,7 @@ timeout = schedule_timeout(timeout); spin_lock_irq(¤t->sighand->siglock); - sig = dequeue_signal(&these, &info); + sig = dequeue_signal(current, &these, &info); current->blocked = current->real_blocked; siginitset(¤t->real_blocked, 0); recalc_sigpending(); diff -Nru a/arch/s390x/kernel/signal.c b/arch/s390x/kernel/signal.c --- a/arch/s390x/kernel/signal.c Fri Feb 14 00:27:29 2003 +++ b/arch/s390x/kernel/signal.c Fri Feb 14 00:27:29 2003 @@ -461,7 +461,7 @@ } #endif - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, oldset, regs); diff -Nru a/arch/s390x/kernel/signal32.c b/arch/s390x/kernel/signal32.c --- a/arch/s390x/kernel/signal32.c Fri Feb 14 00:27:28 2003 +++ b/arch/s390x/kernel/signal32.c Fri Feb 14 00:27:28 2003 @@ -622,7 +622,7 @@ if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal32(signr, &info, oldset, regs); diff -Nru a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c --- a/arch/sh/kernel/signal.c Fri Feb 14 00:27:30 2003 +++ b/arch/sh/kernel/signal.c Fri Feb 14 00:27:30 2003 @@ -556,7 +556,7 @@ if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, oldset, regs); diff -Nru a/arch/sparc/Makefile b/arch/sparc/Makefile --- a/arch/sparc/Makefile Fri Feb 14 00:27:27 2003 +++ b/arch/sparc/Makefile Fri Feb 14 00:27:27 2003 @@ -38,7 +38,7 @@ LDFLAGS_vmlinux = -r head-y := arch/sparc/kernel/head.o arch/sparc/kernel/init_task.o -HEAD := $(head-y) +HEAD_Y := $(head-y) core-y += arch/sparc/kernel/ arch/sparc/mm/ arch/sparc/math-emu/ libs-y += arch/sparc/prom/ arch/sparc/lib/ @@ -52,7 +52,7 @@ DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y)) NET_Y := $(patsubst %/, %/built-in.o, $(net-y)) LIBS_Y := $(patsubst %/, %/lib.a, $(libs-y)) -export INIT_Y CORE_Y DRIVERS_Y NET_Y LIBS_Y HEAD +export INIT_Y CORE_Y DRIVERS_Y NET_Y LIBS_Y HEAD_Y makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/$(ARCH)/boot $(1) diff -Nru a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile --- a/arch/sparc/boot/Makefile Fri Feb 14 00:27:30 2003 +++ b/arch/sparc/boot/Makefile Fri Feb 14 00:27:30 2003 @@ -17,7 +17,7 @@ quiet_cmd_btfix = BTFIX $@ cmd_btfix = $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@ -BTOBJS := $(HEAD) $(INIT_Y) +BTOBJS := $(HEAD_Y) $(INIT_Y) BTLIBS := $(CORE_Y) $(LIBS_Y) $(DRIVERS_Y) $(NET_Y) LDFLAGS_image := -T arch/sparc/vmlinux.lds.s $(BTOBJS) --start-group $(BTLIBS) --end-group diff -Nru a/arch/sparc/kernel/init_task.c b/arch/sparc/kernel/init_task.c --- a/arch/sparc/kernel/init_task.c Fri Feb 14 00:27:28 2003 +++ b/arch/sparc/kernel/init_task.c Fri Feb 14 00:27:28 2003 @@ -8,6 +8,7 @@ static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); struct task_struct init_task = INIT_TASK(init_task); diff -Nru a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c --- a/arch/sparc/kernel/signal.c Fri Feb 14 00:27:29 2003 +++ b/arch/sparc/kernel/signal.c Fri Feb 14 00:27:29 2003 @@ -1045,8 +1045,9 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, unsigned long orig_i0, int restart_syscall) { - struct k_sigaction *ka; siginfo_t info; + struct sparc_deliver_cookie cookie; + int signr; /* * XXX Disable svr4 signal handling until solaris emulation works. @@ -1059,142 +1060,32 @@ int svr4_signal = current->personality == PER_SVR4; #endif + cookie.restart_syscall = restart_syscall; + cookie.orig_i0 = orig_i0; + if (!oldset) oldset = ¤t->blocked; - for (;;) { - sigset_t *mask = ¤t->blocked; - unsigned long signr = 0; - - spin_lock_irq(¤t->sighand->siglock); - signr = dequeue_signal(mask, &info); - spin_unlock_irq(¤t->sighand->siglock); - - if (!signr) - break; - - if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { - /* Do the syscall restart before we let the debugger - * look at the child registers. - */ - if (restart_syscall && - (regs->u_regs[UREG_I0] == ERESTARTNOHAND || - regs->u_regs[UREG_I0] == ERESTARTSYS || - regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { - /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = orig_i0; - regs->pc -= 4; - regs->npc -= 4; - restart_syscall = 0; - } - if (restart_syscall && - regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { - regs->u_regs[UREG_G1] = __NR_restart_syscall; - regs->pc -= 4; - regs->npc -= 4; - restart_syscall = 0; - } - current->exit_code = signr; - set_current_state(TASK_STOPPED); - - /* This happens to be SMP safe so no need to - * grab master kernel lock even in this case. - */ - notify_parent(current, SIGCHLD); - schedule(); - if (!(signr = current->exit_code)) - continue; - current->exit_code = 0; - if (signr == SIGSTOP) - continue; - - /* Update the siginfo structure. Is this good? */ - if (signr != info.si_signo) { - info.si_signo = signr; - info.si_errno = 0; - info.si_code = SI_USER; - info.si_pid = current->parent->pid; - info.si_uid = current->parent->uid; - } - - /* If the (new) signal is now blocked, requeue it. */ - if (sigismember(¤t->blocked, signr)) { - send_sig_info(signr, &info, current); - continue; - } - } - - ka = ¤t->sig->action[signr-1]; - - if (ka->sa.sa_handler == SIG_IGN) { - if (signr != SIGCHLD) - continue; - - /* sys_wait4() grabs the master kernel lock, so - * we need not do so, that sucker should be - * threaded and would not be that difficult to - * do anyways. - */ - while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0) - ; - continue; - } - if (ka->sa.sa_handler == SIG_DFL) { - unsigned long exit_code = signr; - - if (current->pid == 1) - continue; - switch (signr) { - case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG: - continue; - - case SIGTSTP: case SIGTTIN: case SIGTTOU: - /* The operations performed by - * is_orphaned_pgrp() are protected by - * the tasklist_lock. - */ - if (is_orphaned_pgrp(current->pgrp)) - continue; - - case SIGSTOP: { - struct signal_struct *sig; - set_current_state(TASK_STOPPED); - current->exit_code = signr; - sig = current->parent->sig; - if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & - SA_NOCLDSTOP)) - notify_parent(current, SIGCHLD); - schedule(); - continue; - } - - case SIGQUIT: case SIGILL: case SIGTRAP: - case SIGABRT: case SIGFPE: case SIGSEGV: - case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: - if (do_coredump(signr, exit_code, regs)) - exit_code |= 0x80; - /* FALLTHRU */ - - default: - sig_exit(signr, exit_code, &info); - /* NOT REACHED */ - } - } - if (restart_syscall) - syscall_restart(orig_i0, regs, &ka->sa); + signr = get_signal_to_deliver(&info, regs, &cookie); + if (signr > 0) { + struct k_sigaction *ka; + + ka = ¤t->sighand->action[signr-1]; + if (cookie.restart_syscall) + syscall_restart(cookie.orig_i0, regs, &ka->sa); handle_signal(signr, ka, &info, oldset, regs, svr4_signal); return 1; } - if (restart_syscall && + if (cookie.restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = orig_i0; + regs->u_regs[UREG_I0] = cookie.orig_i0; regs->pc -= 4; regs->npc -= 4; } - if (restart_syscall && + if (cookie.restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->pc -= 4; diff -Nru a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c --- a/arch/sparc/mm/init.c Fri Feb 14 00:27:28 2003 +++ b/arch/sparc/mm/init.c Fri Feb 14 00:27:28 2003 @@ -525,7 +525,7 @@ } #endif -void flush_page_to_ram(struct page *page) +void sparc_flush_page_to_ram(struct page *page) { unsigned long vaddr = (unsigned long)page_address(page); diff -Nru a/arch/sparc64/kernel/init_task.c b/arch/sparc64/kernel/init_task.c --- a/arch/sparc64/kernel/init_task.c Fri Feb 14 00:27:30 2003 +++ b/arch/sparc64/kernel/init_task.c Fri Feb 14 00:27:30 2003 @@ -9,6 +9,7 @@ static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); /* .text section in head.S is aligned at 2 page boundry and this gets linked diff -Nru a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c --- a/arch/sparc64/kernel/ioctl32.c Fri Feb 14 00:27:30 2003 +++ b/arch/sparc64/kernel/ioctl32.c Fri Feb 14 00:27:30 2003 @@ -4285,6 +4285,7 @@ COMPATIBLE_IOCTL(TCSETAW) COMPATIBLE_IOCTL(TCSETAF) COMPATIBLE_IOCTL(TCSBRK) +COMPATIBLE_IOCTL(TCSBRKP) COMPATIBLE_IOCTL(TCXONC) COMPATIBLE_IOCTL(TCFLSH) COMPATIBLE_IOCTL(TCGETS) diff -Nru a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c --- a/arch/sparc64/kernel/irq.c Fri Feb 14 00:27:30 2003 +++ b/arch/sparc64/kernel/irq.c Fri Feb 14 00:27:30 2003 @@ -740,9 +740,6 @@ irq_enter(); kstat_cpu(cpu).irqs[irq]++; - if (irq == 9) - kbd_pt_regs = regs; - /* Sliiiick... */ #ifndef CONFIG_SMP bp = ((irq != 0) ? diff -Nru a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c --- a/arch/sparc64/kernel/power.c Fri Feb 14 00:27:30 2003 +++ b/arch/sparc64/kernel/power.c Fri Feb 14 00:27:30 2003 @@ -65,14 +65,11 @@ static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; char *argv[] = { "/sbin/shutdown", "-h", "now", NULL }; - daemonize(); - sprintf(current->comm, "powerd"); + daemonize("powerd"); again: while (button_pressed == 0) { - spin_lock_irq(¤t->sighand->siglock); flush_signals(current); - spin_unlock_irq(¤t->sighand->siglock); interruptible_sleep_on(&powerd_wait); } diff -Nru a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c --- a/arch/sparc64/kernel/signal.c Fri Feb 14 00:27:28 2003 +++ b/arch/sparc64/kernel/signal.c Fri Feb 14 00:27:28 2003 @@ -603,8 +603,12 @@ unsigned long orig_i0, int restart_syscall) { siginfo_t info; - struct k_sigaction *ka; + struct signal_deliver_cookie cookie; + int signr; + cookie.restart_syscall = restart_syscall; + cookie.orig_i0 = orig_i0; + if (!oldset) oldset = ¤t->blocked; @@ -612,135 +616,31 @@ if (test_thread_flag(TIF_32BIT)) { extern int do_signal32(sigset_t *, struct pt_regs *, unsigned long, int); - return do_signal32(oldset, regs, orig_i0, restart_syscall); + return do_signal32(oldset, regs, orig_i0, + cookie.restart_syscall); } #endif - for (;;) { - sigset_t *mask = ¤t->blocked; - unsigned long signr = 0; - - spin_lock_irq(¤t->sighand->siglock); - signr = dequeue_signal(mask, &info); - spin_unlock_irq(¤t->sighand->siglock); - - if (!signr) - break; - - if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { - /* Do the syscall restart before we let the debugger - * look at the child registers. - */ - if (restart_syscall && - (regs->u_regs[UREG_I0] == ERESTARTNOHAND || - regs->u_regs[UREG_I0] == ERESTARTSYS || - regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { - /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = orig_i0; - regs->tpc -= 4; - regs->tnpc -= 4; - restart_syscall = 0; - } - if (restart_syscall && - regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { - regs->u_regs[UREG_G1] = __NR_restart_syscall; - regs->tpc -= 4; - regs->tnpc -= 4; - restart_syscall = 0; - } - - current->exit_code = signr; - set_current_state(TASK_STOPPED); - notify_parent(current, SIGCHLD); - schedule(); - if (!(signr = current->exit_code)) - continue; - current->exit_code = 0; - if (signr == SIGSTOP) - continue; - - /* Update the siginfo structure. Is this good? */ - if (signr != info.si_signo) { - info.si_signo = signr; - info.si_errno = 0; - info.si_code = SI_USER; - info.si_pid = current->parent->pid; - info.si_uid = current->parent->uid; - } - - /* If the (new) signal is now blocked, requeue it. */ - if (sigismember(¤t->blocked, signr)) { - send_sig_info(signr, &info, current); - continue; - } - } - - ka = ¤t->sig->action[signr-1]; - - if (ka->sa.sa_handler == SIG_IGN) { - if (signr != SIGCHLD) - continue; - - /* sys_wait4() grabs the master kernel lock, so - * we need not do so, that sucker should be - * threaded and would not be that difficult to - * do anyways. - */ - while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) - ; - continue; - } - if (ka->sa.sa_handler == SIG_DFL) { - unsigned long exit_code = signr; - - if (current->pid == 1) - continue; - switch (signr) { - case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG: - continue; - - case SIGTSTP: case SIGTTIN: case SIGTTOU: - if (is_orphaned_pgrp(current->pgrp)) - continue; - - case SIGSTOP: { - struct signal_struct *sig; - set_current_state(TASK_STOPPED); - current->exit_code = signr; - sig = current->parent->sig; - if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & - SA_NOCLDSTOP)) - notify_parent(current, SIGCHLD); - schedule(); - continue; - } - case SIGQUIT: case SIGILL: case SIGTRAP: - case SIGABRT: case SIGFPE: case SIGSEGV: - case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: - if (do_coredump(signr, exit_code, regs)) - exit_code |= 0x80; - /* FALLTHRU */ + signr = get_signal_to_deliver(&info, regs, &cookie); + if (signr > 0) { + struct k_sigaction *ka; - default: - sig_exit(signr, exit_code, &info); - /* NOT REACHED */ - } - } - if (restart_syscall) + ka = ¤t->sighand->action[signr-1]; + if (cookie.restart_syscall) syscall_restart(orig_i0, regs, &ka->sa); handle_signal(signr, ka, &info, oldset, regs); return 1; } - if (restart_syscall && + if (cookie.restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = orig_i0; + regs->u_regs[UREG_I0] = cookie.orig_i0; regs->tpc -= 4; regs->tnpc -= 4; } - if (restart_syscall && + if (cookie.restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; diff -Nru a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c --- a/arch/sparc64/kernel/signal32.c Fri Feb 14 00:27:26 2003 +++ b/arch/sparc64/kernel/signal32.c Fri Feb 14 00:27:26 2003 @@ -1279,136 +1279,34 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, unsigned long orig_i0, int restart_syscall) { - struct k_sigaction *ka; siginfo_t info; - + struct signal_deliver_cookie cookie; + int signr; int svr4_signal = current->personality == PER_SVR4; - for (;;) { - sigset_t *mask = ¤t->blocked; - unsigned long signr = 0; - - spin_lock_irq(¤t->sighand->siglock); - signr = dequeue_signal(mask, &info); - spin_unlock_irq(¤t->sighand->siglock); - - if (!signr) - break; - - if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { - /* Do the syscall restart before we let the debugger - * look at the child registers. - */ - if (restart_syscall && - (regs->u_regs[UREG_I0] == ERESTARTNOHAND || - regs->u_regs[UREG_I0] == ERESTARTSYS || - regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { - /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = orig_i0; - regs->tpc -= 4; - regs->tnpc -= 4; - restart_syscall = 0; - } - if (restart_syscall && - regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { - regs->u_regs[UREG_G1] = __NR_restart_syscall; - regs->tpc -= 4; - regs->tnpc -= 4; - restart_syscall = 0; - } - - current->exit_code = signr; - set_current_state(TASK_STOPPED); - notify_parent(current, SIGCHLD); - schedule(); - if (!(signr = current->exit_code)) - continue; - current->exit_code = 0; - if (signr == SIGSTOP) - continue; - - /* Update the siginfo structure. Is this good? */ - if (signr != info.si_signo) { - info.si_signo = signr; - info.si_errno = 0; - info.si_code = SI_USER; - info.si_pid = current->parent->pid; - info.si_uid = current->parent->uid; - } - - /* If the (new) signal is now blocked, requeue it. */ - if (sigismember(¤t->blocked, signr)) { - send_sig_info(signr, &info, current); - continue; - } - } - - ka = ¤t->sig->action[signr-1]; - - if (ka->sa.sa_handler == SIG_IGN) { - if (signr != SIGCHLD) - continue; - - /* sys_wait4() grabs the master kernel lock, so - * we need not do so, that sucker should be - * threaded and would not be that difficult to - * do anyways. - */ - while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) - ; - continue; - } - if (ka->sa.sa_handler == SIG_DFL) { - unsigned long exit_code = signr; - - if (current->pid == 1) - continue; - switch (signr) { - case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG: - continue; - - case SIGTSTP: case SIGTTIN: case SIGTTOU: - if (is_orphaned_pgrp(current->pgrp)) - continue; + cookie.restart_syscall = restart_syscall; + cookie.orig_i0 = orig_i0; - case SIGSTOP: { - struct signal_struct *sig; - set_current_state(TASK_STOPPED); - current->exit_code = signr; - sig = current->parent->sig; - if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & - SA_NOCLDSTOP)) - notify_parent(current, SIGCHLD); - schedule(); - continue; - } - case SIGQUIT: case SIGILL: case SIGTRAP: - case SIGABRT: case SIGFPE: case SIGSEGV: - case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: - if (do_coredump(signr, exit_code, regs)) - exit_code |= 0x80; - /* FALLTHRU */ + signr = get_signal_to_deliver(&info, regs, &cookie); + if (signr > 0) { + struct k_sigaction *ka; - default: - sig_exit(signr, exit_code, &info); - /* NOT REACHED */ - } - } - if (restart_syscall) + ka = ¤t->sighand->action[signr-1]; + if (cookie.restart_syscall) syscall_restart32(orig_i0, regs, &ka->sa); handle_signal32(signr, ka, &info, oldset, regs, svr4_signal); return 1; } - if (restart_syscall && + if (cookie.restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = orig_i0; + regs->u_regs[UREG_I0] = cookie.orig_i0; regs->tpc -= 4; regs->tnpc -= 4; } - if (restart_syscall && + if (cookie.restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c --- a/arch/sparc64/kernel/sys_sparc32.c Fri Feb 14 00:27:29 2003 +++ b/arch/sparc64/kernel/sys_sparc32.c Fri Feb 14 00:27:29 2003 @@ -1679,23 +1679,6 @@ return ret; } -extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset); - -asmlinkage int sys32_sigprocmask(int how, compat_old_sigset_t *set, compat_old_sigset_t *oset) -{ - old_sigset_t s; - int ret; - mm_segment_t old_fs = get_fs(); - - if (set && get_user (s, set)) return -EFAULT; - set_fs (KERNEL_DS); - ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL); - set_fs (old_fs); - if (ret) return ret; - if (oset && put_user (s, oset)) return -EFAULT; - return 0; -} - extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize); asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set, compat_sigset_t *oset, compat_size_t sigsetsize) @@ -1732,21 +1715,6 @@ return 0; } -extern asmlinkage int sys_sigpending(old_sigset_t *set); - -asmlinkage int sys32_sigpending(compat_old_sigset_t *set) -{ - old_sigset_t s; - int ret; - mm_segment_t old_fs = get_fs(); - - set_fs (KERNEL_DS); - ret = sys_sigpending(&s); - set_fs (old_fs); - if (put_user (s, set)) return -EFAULT; - return ret; -} - extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize); asmlinkage int sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize) @@ -1813,7 +1781,7 @@ } spin_lock_irq(¤t->sighand->siglock); - sig = dequeue_signal(&these, &info); + sig = dequeue_signal(current, &these, &info); if (!sig) { timeout = MAX_SCHEDULE_TIMEOUT; if (uts) @@ -1833,7 +1801,7 @@ timeout = schedule_timeout(timeout); spin_lock_irq(¤t->sighand->siglock); - sig = dequeue_signal(&these, &info); + sig = dequeue_signal(current, &these, &info); current->blocked = current->real_blocked; siginitset(¤t->real_blocked, 0); recalc_sigpending(); diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S --- a/arch/sparc64/kernel/systbls.S Fri Feb 14 00:27:28 2003 +++ b/arch/sparc64/kernel/systbls.S Fri Feb 14 00:27:28 2003 @@ -55,7 +55,7 @@ .word sys_quotactl, sys_set_tid_address, sys32_mount, sys_ustat, sys_setxattr /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr -/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys_ni_syscall +/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname /*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl .word sys_epoll_wait, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask @@ -63,7 +63,7 @@ .word sys32_readahead, sys32_socketcall, sys_syslog, sys32_lookup_dcookie, sys_nis_syscall /*210*/ .word sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys32_sysinfo .word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex -/*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid +/*220*/ .word compat_sys_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 /*230*/ .word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_ni_syscall .word sys_ni_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall @@ -203,7 +203,7 @@ .word sunos_nosys, sunos_getdents, sys_setsid .word sys_fchdir, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sys32_sigpending, sunos_nosys + .word sunos_nosys, compat_sys_sigpending, sunos_nosys .word sys_setpgid, sunos_pathconf, sunos_fpathconf .word sunos_sysconf, sunos_uname, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys diff -Nru a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c --- a/arch/sparc64/mm/hugetlbpage.c Fri Feb 14 00:27:29 2003 +++ b/arch/sparc64/mm/hugetlbpage.c Fri Feb 14 00:27:29 2003 @@ -232,6 +232,18 @@ return -1; } +/* + * This function checks for proper alignment of input addr and len parameters. + */ +int is_aligned_hugepage_range(unsigned long addr, unsigned long len) +{ + if (len & ~HPAGE_MASK) + return -EINVAL; + if (addr & ~HPAGE_MASK) + return -EINVAL; + return 0; +} + int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma) { diff -Nru a/arch/sparc64/oprofile/init.c b/arch/sparc64/oprofile/init.c --- a/arch/sparc64/oprofile/init.c Fri Feb 14 00:27:28 2003 +++ b/arch/sparc64/oprofile/init.c Fri Feb 14 00:27:28 2003 @@ -11,10 +11,10 @@ #include #include -extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu); +extern void timer_init(struct oprofile_operations ** ops); -int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +int __init oprofile_arch_init(struct oprofile_operations ** ops) { - timer_init(ops, cpu); + timer_init(ops); return 0; } diff -Nru a/arch/sparc64/oprofile/timer_int.c b/arch/sparc64/oprofile/timer_int.c --- a/arch/sparc64/oprofile/timer_int.c Fri Feb 14 00:27:29 2003 +++ b/arch/sparc64/oprofile/timer_int.c Fri Feb 14 00:27:29 2003 @@ -19,8 +19,10 @@ { struct pt_regs * regs = (struct pt_regs *)data; int cpu = smp_processor_id(); + unsigned long pc = instruction_pointer(regs); + int is_kernel = !user_mode(regs); - oprofile_add_sample(instruction_pointer(regs), 0, cpu); + oprofile_add_sample(pc, is_kernel, 0, cpu); return 0; } @@ -44,13 +46,13 @@ static struct oprofile_operations timer_ops = { .start = timer_start, - .stop = timer_stop + .stop = timer_stop, + .cpu_type = "timer" }; -void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +void __init timer_init(struct oprofile_operations ** ops) { *ops = &timer_ops; - *cpu = OPROFILE_CPU_TIMER; printk(KERN_INFO "oprofile: using timer interrupt.\n"); } diff -Nru a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c --- a/arch/um/kernel/signal_kern.c Fri Feb 14 00:27:28 2003 +++ b/arch/um/kernel/signal_kern.c Fri Feb 14 00:27:28 2003 @@ -136,7 +136,7 @@ if (!oldset) oldset = ¤t->blocked; - sig = get_signal_to_deliver(&info, regs); + sig = get_signal_to_deliver(&info, regs, NULL); if(sig == 0) return(0); diff -Nru a/arch/v850/kernel/signal.c b/arch/v850/kernel/signal.c --- a/arch/v850/kernel/signal.c Fri Feb 14 00:27:30 2003 +++ b/arch/v850/kernel/signal.c Fri Feb 14 00:27:30 2003 @@ -506,7 +506,7 @@ if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, oldset, regs); diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig --- a/arch/x86_64/Kconfig Fri Feb 14 00:27:29 2003 +++ b/arch/x86_64/Kconfig Fri Feb 14 00:27:29 2003 @@ -19,11 +19,6 @@ config X86 bool default y - help - This is Linux's home port. Linux was originally native to the Intel - 386, and runs on all the later x86 processors including the Intel - 486, 586, Pentiums, and various instruction-set-compatible chips by - AMD, Cyrix, and others. config MMU bool @@ -35,20 +30,10 @@ config ISA bool - help - Find out whether you have ISA slots on your motherboard. ISA is the - name of a bus system, i.e. the way the CPU talks to the other stuff - inside your box. Other bus systems are PCI, EISA, MicroChannel - (MCA) or VESA. ISA is an older system, now being displaced by PCI; - newer boards don't support it. If you have ISA, say Y, otherwise N. config SBUS bool -config UID16 - bool - default y - config RWSEM_GENERIC_SPINLOCK bool default y @@ -86,14 +71,14 @@ default MK8 config MK8 - bool "AMD-Hammer" + bool "AMD-Opteron/Athlon64" help - Support for AMD Clawhammer/Sledgehammer CPUs. Only choice for x86-64 - currently so you should choose this if you want a x86-64 kernel. In fact - you will have no other choice than to choose this. + Optimize for AMD Opteron/Athlon64/Hammer/K8 CPUs. config GENERIC_CPU bool "Generic-x86-64" + help + Generic x86-64 CPU. endchoice @@ -196,25 +181,12 @@ singleprocessor machines. On a singleprocessor machine, the kernel will run faster if you say N here. - Note that if you say Y here and choose architecture "586" or - "Pentium" under "Processor family", the kernel will not work on 486 - architectures. Similarly, multiprocessor kernels for the "PPro" - architecture may not work on all Pentium based boards. - - People using multiprocessor machines who say Y here should also say - Y to "Enhanced Real Time Clock Support", below. The "Advanced Power - Management" code will be disabled if you say Y here. - - See also the , - , , - and the SMP-HOWTO available at - . - If you don't know what to do here, say N. +# broken currently config PREEMPT + depends on NOT_WORKING bool "Preemptible Kernel" - depends on !SMP ---help--- This option reduces the latency of the kernel when reacting to real-time or interactive events by allowing a low priority process to @@ -229,6 +201,28 @@ Say Y here if you are feeling brave and building a kernel for a desktop, embedded or real-time system. Say N if you are unsure. +# someone write a better help text please. +config K8_NUMA + bool "K8 NUMA support" + depends on SMP + help + Enable NUMA (Non Unified Memory Architecture) support for + AMD Opteron Multiprocessor systems. The kernel will try to allocate + memory used by a CPU on the local memory controller of the CPU + and in the future do more optimizations. This may improve performance + or it may not. Code is still experimental. + Say N if unsure. + +config DISCONTIGMEM + bool + depends on K8_NUMA + default y + +config NUMA + bool + depends on K8_NUMA + default y + config HAVE_DEC_LOCK bool depends on SMP @@ -245,15 +239,17 @@ kernel will support. The maximum supported value is 32 and the minimum value which makes sense is 2. - This is purely to save memory - each supported CPU adds - approximately eight kilobytes to the kernel image. + This is purely to save memory - each supported CPU requires + memory in the static kernel configuration. config GART_IOMMU bool "IOMMU support" help Support the K8 IOMMU. Needed to run systems with more than 4GB of memory - properly with 32-bit devices. You should probably turn this on. - The iommu can be turned off at runtime with the iommu=off parameter. + properly with 32-bit PCI devices that do not support DAC (Double Address + Cycle). The IOMMU can be turned off at runtime with the iommu=off parameter. + Normally the kernel will take the right choice by itself. + If unsure say Y config DUMMY_IOMMU bool @@ -291,7 +287,8 @@ Note that, even if you say N here, Linux on the x86 architecture will issue the hlt instruction if nothing is to be done, thereby - sending the processor to sleep and saving power. + sending the processor to limited sleep and saving power. However + using ACPI will likely save more power. config SOFTWARE_SUSPEND bool "Software Suspend (EXPERIMENTAL)" @@ -331,16 +328,6 @@ config PCI bool "PCI support" - help - Find out whether you have a PCI motherboard. PCI is the name of a - bus system, i.e. the way the CPU talks to the other stuff inside - your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or - VESA. If you have PCI, say Y, otherwise N. - - The PCI-HOWTO, available from - , contains valuable - information about which PCI hardware does work under Linux and which - doesn't. # x86-64 doesn't support PCI BIOS access from long mode so always go direct. config PCI_DIRECT @@ -381,54 +368,10 @@ bool depends on PROC_FS default y - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linkable Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. -#tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT config BINFMT_ELF - tristate "Kernel support for ELF binaries" - ---help--- - ELF (Executable and Linkable Format) is a format for libraries and - executables used across different architectures and operating - systems. Saying Y here will enable your kernel to run ELF binaries - and enlarge it by about 13 KB. ELF support under Linux has now all - but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC) - because it is portable (this does *not* mean that you will be able - to run executables from different architectures or operating systems - however) and makes building run-time libraries very easy. Many new - executables are distributed solely in ELF format. You definitely - want to say Y here. - - Information about ELF is contained in the ELF HOWTO available from - . - - If you find that after upgrading from Linux kernel 1.2 and saying Y - here, you still can't run any ELF binaries (they just crash), then - you'll have to install the newest ELF runtime libraries, including - ld.so (check the file for location and - latest version). - - If you want to compile this as a module ( = code which can be - inserted in and removed from the running kernel whenever you want), - say M here and read . The module - will be called binfmt_elf. Saying M or N here is dangerous because - some crucial programs on your system might be in ELF format. + bool + default y config BINFMT_MISC tristate "Kernel support for MISC binaries" @@ -436,12 +379,9 @@ If you say Y here, it will be possible to plug wrapper-driven binary formats into the kernel. You will like this especially when you use programs that need an interpreter to run like Java, Python or - Emacs-Lisp. It's also useful if you often run DOS executables under - the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from - ). Once you have - registered such a binary class with the kernel, you can start one of - those programs simply by typing in its name at a shell prompt; Linux - will automatically feed it to the correct interpreter. + Emacs-Lisp. Once you have registered such a binary class with the kernel, + you can start one of those programs simply by typing in its name at a shell + prompt; Linux will automatically feed it to the correct interpreter. You can do other nice things, too. Read the file to learn how to use this @@ -467,6 +407,12 @@ depends on IA32_EMULATION default y + +config UID16 + bool + depends on IA32_EMULATION + default y + endmenu source "drivers/mtd/Kconfig" @@ -672,9 +618,11 @@ best used in conjunction with the NMI watchdog so that spinlock deadlocks are also debuggable. +# !SMP for now because the context switch early causes GPF in segment reloading +# and the GS base checking does the wrong thing then, causing a hang. config CHECKING bool "Additional run-time checks" - depends on DEBUG_KERNEL + depends on DEBUG_KERNEL && !SMP help Enables some internal consistency checks for kernel debugging. You should normally say N. @@ -683,7 +631,8 @@ bool "Debug __init statements" depends on DEBUG_KERNEL help - Fill __init and __initdata at the end of boot. This is only for debugging. + Fill __init and __initdata at the end of boot. This helps debugging + illegal uses of __init and __initdata after initialization. config KALLSYMS bool "Load all symbols for debugging/kksymoops" @@ -696,11 +645,11 @@ bool "Compile the kernel with frame pointers" depends on DEBUG_KERNEL help - If you say Y here the resulting kernel image will be slightly larger - and slower, but it will give very useful debugging information. - If you don't debug the kernel, you can say N, but we may not be able - to solve problems without frame pointers. - Note this is normally not needed on x86-64. + Compile the kernel with frame pointers. This may help for some + debugging with external debuggers. Note the standard oops backtracer + doesn't make use of it and the x86-64 kernel doesn't ensure an consistent + frame pointer through inline assembly (semaphores etc.) + Normally you should say N. endmenu diff -Nru a/arch/x86_64/Makefile b/arch/x86_64/Makefile --- a/arch/x86_64/Makefile Fri Feb 14 00:27:30 2003 +++ b/arch/x86_64/Makefile Fri Feb 14 00:27:30 2003 @@ -58,7 +58,8 @@ boot := arch/x86_64/boot -.PHONY: bzImage bzlilo bzdisk install archmrproper +.PHONY: bzImage bzlilo install archmrproper \ + fdimage fdimage144 fdimage288 archclean #Default target when executing "make" all: bzImage @@ -74,7 +75,7 @@ bzdisk: vmlinux $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zdisk -install: vmlinux +install fdimage fdimage144 fdimage288: vmlinux $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ archclean: @@ -102,4 +103,7 @@ echo ' (distribution) /sbin/installkernel or' echo ' install to $$(INSTALL_PATH) and run lilo' endef + +CLEAN_FILES += arch/$(ARCH)/boot/fdimage arch/$(ARCH)/boot/mtools.conf + diff -Nru a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile --- a/arch/x86_64/boot/Makefile Fri Feb 14 00:27:28 2003 +++ b/arch/x86_64/boot/Makefile Fri Feb 14 00:27:28 2003 @@ -59,8 +59,36 @@ $(obj)/compressed/vmlinux: FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@ -zdisk: $(BOOTIMAGE) - dd bs=8192 if=$(BOOTIMAGE) of=/dev/fd0 +# Set this if you want to pass append arguments to the zdisk/fdimage kernel +FDARGS = + +$(obj)/mtools.conf: $(obj)/mtools.conf.in + sed -e 's|@OBJ@|$(obj)|g' < $< > $@ + +# This requires write access to /dev/fd0 +zdisk: $(BOOTIMAGE) $(obj)/mtools.conf + MTOOLSRC=$(src)/mtools.conf mformat a: ; sync + syslinux /dev/fd0 ; sync + echo 'default linux $(FDARGS)' | \ + MTOOLSRC=$(src)/mtools.conf mcopy - a:syslinux.cfg + MTOOLSRC=$(src)/mtools.conf mcopy $(BOOTIMAGE) a:linux ; sync + +# These require being root or having syslinux run setuid +fdimage fdimage144: $(BOOTIMAGE) $(src)/mtools.conf + dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440 + MTOOLSRC=$(src)/mtools.conf mformat v: ; sync + syslinux $(obj)/fdimage ; sync + echo 'default linux $(FDARGS)' | \ + MTOOLSRC=$(src)/mtools.conf mcopy - v:syslinux.cfg + MTOOLSRC=$(src)/mtools.conf mcopy $(BOOTIMAGE) v:linux ; sync + +fdimage288: $(BOOTIMAGE) $(src)/mtools.conf + dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880 + MTOOLSRC=$(src)/mtools.conf mformat w: ; sync + syslinux $(obj)/fdimage ; sync + echo 'default linux $(FDARGS)' | \ + MTOOLSRC=$(src)/mtools.conf mcopy - w:syslinux.cfg + MTOOLSRC=$(src)/mtools.conf mcopy $(BOOTIMAGE) w:linux ; sync zlilo: $(BOOTIMAGE) if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi diff -Nru a/arch/x86_64/boot/bootsect.S b/arch/x86_64/boot/bootsect.S --- a/arch/x86_64/boot/bootsect.S Fri Feb 14 00:27:29 2003 +++ b/arch/x86_64/boot/bootsect.S Fri Feb 14 00:27:29 2003 @@ -4,29 +4,13 @@ * modified by Drew Eckhardt * modified by Bruce Evans (bde) * modified by Chris Noe (May 1999) (as86 -> gas) - * - * 360k/720k disk support: Andrzej Krzysztofowicz + * gutted by H. Peter Anvin (Jan 2003) * * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment * addresses must be multiplied by 16 to obtain their respective linear * addresses. To avoid confusion, linear addresses are written using leading * hex while segment addresses are written as segment:offset. * - * bde - should not jump blindly, there may be systems with only 512K low - * memory. Use int 0x12 to get the top of memory, etc. - * - * It then loads 'setup' directly after itself (0x90200), and the system - * at 0x10000, using BIOS interrupts. - * - * NOTE! currently system is at most (8*65536-4096) bytes long. This should - * be no problem, even in the future. I want to keep it simple. This 508 kB - * kernel size should be enough, especially as this doesn't contain the - * buffer cache as in minix (and especially now that the kernel is - * compressed :-) - * - * The loader has been made as simple as possible, and continuous - * read errors will result in a unbreakable loop. Reboot by hand. It - * loads pretty fast by getting whole tracks at a time whenever possible. */ #include @@ -59,353 +43,51 @@ .global _start _start: -# First things first. Move ourself from 0x7C00 -> 0x90000 and jump there. + # Normalize the start address + jmpl $BOOTSEG, $start2 - movw $BOOTSEG, %ax - movw %ax, %ds # %ds = BOOTSEG - movw $INITSEG, %ax - movw %ax, %es # %ax = %es = INITSEG - movw $256, %cx - subw %si, %si - subw %di, %di - cld - rep - movsw - ljmp $INITSEG, $go - -# bde - changed 0xff00 to 0x4000 to use debugger at 0x6400 up (bde). We -# wouldn't have to worry about this if we checked the top of memory. Also -# my BIOS can be configured to put the wini drive tables in high memory -# instead of in the vector table. The old stack might have clobbered the -# drive table. - -go: movw $0x4000-12, %di # 0x4000 is an arbitrary value >= - # length of bootsect + length of - # setup + room for stack; - # 12 is disk parm size. - movw %ax, %ds # %ax and %es already contain INITSEG +start2: + movw %cs, %ax + movw %ax, %ds + movw %ax, %es movw %ax, %ss - movw %di, %sp # put stack at INITSEG:0x4000-12. + movw $0x7c00, %sp + sti + cld -# Many BIOS's default disk parameter tables will not recognize -# multi-sector reads beyond the maximum sector number specified -# in the default diskette parameter tables - this may mean 7 -# sectors in some cases. -# -# Since single sector reads are slow and out of the question, -# we must take care of this by creating new parameter tables -# (for the first disk) in RAM. We will set the maximum sector -# count to 36 - the most we will encounter on an ED 2.88. -# -# High doesn't hurt. Low does. -# -# Segments are as follows: %cs = %ds = %es = %ss = INITSEG, %fs = 0, -# and %gs is unused. - - movw %cx, %fs # %fs = 0 - movw $0x78, %bx # %fs:%bx is parameter table address - pushw %ds - ldsw %fs:(%bx), %si # %ds:%si is source - movb $6, %cl # copy 12 bytes - pushw %di # %di = 0x4000-12. - rep # don't worry about cld - movsw # already done above - popw %di - popw %ds - movb $36, 0x4(%di) # patch sector count - movw %di, %fs:(%bx) - movw %es, %fs:2(%bx) - -# Get disk drive parameters, specifically number of sectors/track. - -# It seems that there is no BIOS call to get the number of sectors. -# Guess 36 sectors if sector 36 can be read, 18 sectors if sector 18 -# can be read, 15 if sector 15 can be read. Otherwise guess 9. -# Note that %cx = 0 from rep movsw above. + movw $bugger_off_msg, %si - movw $disksizes, %si # table of sizes to try -probe_loop: +msg_loop: lodsb - cbtw # extend to word - movw %ax, sectors - cmpw $disksizes+4, %si - jae got_sectors # If all else fails, try 9 - - xchgw %cx, %ax # %cx = track and sector - xorw %dx, %dx # drive 0, head 0 - movw $0x0200, %bx # address = 512, in INITSEG (%es = %cs) - movw $0x0201, %ax # service 2, 1 sector - int $0x13 - jc probe_loop # try next value - -got_sectors: - movb $0x03, %ah # read cursor pos - xorb %bh, %bh - int $0x10 - movw $9, %cx - movb $0x07, %bl # page 0, attribute 7 (normal) - # %bh is set above; int10 doesn't - # modify it - movw $msg1, %bp - movw $0x1301, %ax # write string, move cursor - int $0x10 # tell the user we're loading.. - -# Load the setup-sectors directly after the moved bootblock (at 0x90200). -# We should know the drive geometry to do it, as setup may exceed first -# cylinder (for 9-sector 360K and 720K floppies). - - movw $0x0001, %ax # set sread (sector-to-read) to 1 as - movw $sread, %si # the boot sector has already been read - movw %ax, (%si) - - call kill_motor # reset FDC - movw $0x0200, %bx # address = 512, in INITSEG -next_step: - movb setup_sects, %al - movw sectors, %cx - subw (%si), %cx # (%si) = sread - cmpb %cl, %al - jbe no_cyl_crossing - movw sectors, %ax - subw (%si), %ax # (%si) = sread -no_cyl_crossing: - call read_track - pushw %ax # save it - call set_next # set %bx properly; it uses %ax,%cx,%dx - popw %ax # restore - subb %al, setup_sects # rest - for next step - jnz next_step - - pushw $SYSSEG - popw %es # %es = SYSSEG - call read_it - call kill_motor - call print_nl - -# After that we check which root-device to use. If the device is -# defined (!= 0), nothing is done and the given device is used. -# Otherwise, one of /dev/fd0H2880 (2,32) or /dev/PS0 (2,28) or /dev/at0 (2,8) -# depending on the number of sectors we pretend to know we have. - -# Segments are as follows: %cs = %ds = %ss = INITSEG, -# %es = SYSSEG, %fs = 0, %gs is unused. - - movw root_dev, %ax - orw %ax, %ax - jne root_defined - - movw sectors, %bx - movw $0x0208, %ax # /dev/ps0 - 1.2Mb - cmpw $15, %bx - je root_defined - - movb $0x1c, %al # /dev/PS0 - 1.44Mb - cmpw $18, %bx - je root_defined - - movb $0x20, %al # /dev/fd0H2880 - 2.88Mb - cmpw $36, %bx - je root_defined - - movb $0, %al # /dev/fd0 - autodetect -root_defined: - movw %ax, root_dev - -# After that (everything loaded), we jump to the setup-routine -# loaded directly after the bootblock: - - ljmp $SETUPSEG, $0 - -# These variables are addressed via %si register as it gives shorter code. - -sread: .word 0 # sectors read of current track -head: .word 0 # current head -track: .word 0 # current track - -# This routine loads the system at address SYSSEG, making sure -# no 64kB boundaries are crossed. We try to load it as fast as -# possible, loading whole tracks whenever we can. - -read_it: - movw %es, %ax # %es = SYSSEG when called - testw $0x0fff, %ax -die: jne die # %es must be at 64kB boundary - xorw %bx, %bx # %bx is starting address within segment -rp_read: -#ifdef __BIG_KERNEL__ # look in setup.S for bootsect_kludge - bootsect_kludge = 0x220 # 0x200 + 0x20 which is the size of the - lcall *bootsect_kludge # bootsector + bootsect_kludge offset -#else - movw %es, %ax - subw $SYSSEG, %ax - movw %bx, %cx - shr $4, %cx - add %cx, %ax # check offset -#endif - cmpw syssize, %ax # have we loaded everything yet? - jbe ok1_read - - ret - -ok1_read: - movw sectors, %ax - subw (%si), %ax # (%si) = sread - movw %ax, %cx - shlw $9, %cx - addw %bx, %cx - jnc ok2_read - - je ok2_read - - xorw %ax, %ax - subw %bx, %ax - shrw $9, %ax -ok2_read: - call read_track - call set_next - jmp rp_read - -read_track: - pusha - pusha - movw $0xe2e, %ax # loading... message 2e = . + andb %al, %al + jz die + movb $0xe, %ah movw $7, %bx int $0x10 - popa - -# Accessing head, track, sread via %si gives shorter code. + jmp msg_loop - movw 4(%si), %dx # 4(%si) = track - movw (%si), %cx # (%si) = sread - incw %cx - movb %dl, %ch - movw 2(%si), %dx # 2(%si) = head - movb %dl, %dh - andw $0x0100, %dx - movb $2, %ah - pushw %dx # save for error dump - pushw %cx - pushw %bx - pushw %ax - int $0x13 - jc bad_rt - - addw $8, %sp - popa - ret - -set_next: - movw %ax, %cx - addw (%si), %ax # (%si) = sread - cmp sectors, %ax - jne ok3_set - movw $0x0001, %ax - xorw %ax, 2(%si) # change head - jne ok4_set - incw 4(%si) # next track -ok4_set: +die: + # Allow the user to press a key, then reboot xorw %ax, %ax -ok3_set: - movw %ax, (%si) # set sread - shlw $9, %cx - addw %cx, %bx - jnc set_next_fin - movw %es, %ax - addb $0x10, %ah - movw %ax, %es - xorw %bx, %bx -set_next_fin: - ret - -bad_rt: - pushw %ax # save error code - call print_all # %ah = error, %al = read - xorb %ah, %ah - xorb %dl, %dl - int $0x13 - addw $10, %sp - popa - jmp read_track - -# print_all is for debugging purposes. -# -# it will print out all of the registers. The assumption is that this is -# called from a routine, with a stack frame like -# -# %dx -# %cx -# %bx -# %ax -# (error) -# ret <- %sp - -print_all: - movw $5, %cx # error code + 4 registers - movw %sp, %bp -print_loop: - pushw %cx # save count remaining - call print_nl # <-- for readability - cmpb $5, %cl - jae no_reg # see if register name is needed + int $0x16 + int $0x19 - movw $0xe05 + 'A' - 1, %ax - subb %cl, %al - int $0x10 - movb $'X', %al - int $0x10 - movb $':', %al - int $0x10 -no_reg: - addw $2, %bp # next register - call print_hex # print it - popw %cx - loop print_loop - ret - -print_nl: - movw $0xe0d, %ax # CR - int $0x10 - movb $0xa, %al # LF - int $0x10 - ret - -# print_hex is for debugging purposes, and prints the word -# pointed to by %ss:%bp in hexadecimal. - -print_hex: - movw $4, %cx # 4 hex digits - movw (%bp), %dx # load word into %dx -print_digit: - rolw $4, %dx # rotate to use low 4 bits - movw $0xe0f, %ax # %ah = request - andb %dl, %al # %al = mask for nybble - addb $0x90, %al # convert %al to ascii hex - daa # in only four instructions! - adc $0x40, %al - daa - int $0x10 - loop print_digit - ret - -# This procedure turns off the floppy drive motor, so -# that we enter the kernel in a known state, and -# don't have to worry about it later. -# NOTE: Doesn't save %ax or %dx; do it yourself if you need to. - -kill_motor: - movw $0x3f2, %dx - xorb %al, %al - outb %al, %dx - ret - -sectors: .word 0 -disksizes: .byte 36, 18, 15, 9 -msg1: .byte 13, 10 - .ascii "Loading" + # int 0x19 should never return. In case it does anyway, + # invoke the BIOS reset code... + ljmp $0xf000,$0xfff0 + + +bugger_off_msg: + .ascii "Direct booting from floppy is no longer supported.\r\n" + .ascii "Please use a boot loader program instead.\r\n" + .ascii "\n" + .ascii "Remove disk and press any key to reboot . . .\r\n" + .byte 0 + -# XXX: This is a fairly snug fit. + # Kernel attributes; used by setup -.org 497 + .org 497 setup_sects: .byte SETUPSECTS root_flags: .word ROOT_RDONLY syssize: .word SYSSIZE diff -Nru a/arch/x86_64/boot/mtools.conf.in b/arch/x86_64/boot/mtools.conf.in --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/x86_64/boot/mtools.conf.in Fri Feb 14 00:27:30 2003 @@ -0,0 +1,17 @@ +# +# mtools configuration file for "make (b)zdisk" +# + +# Actual floppy drive +drive a: + file="/dev/fd0" + +# 1.44 MB floppy disk image +drive v: + file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter + +# 2.88 MB floppy disk image (mostly for virtual uses) +drive w: + file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter + + diff -Nru a/arch/x86_64/boot/tools/build.c b/arch/x86_64/boot/tools/build.c --- a/arch/x86_64/boot/tools/build.c Fri Feb 14 00:27:27 2003 +++ b/arch/x86_64/boot/tools/build.c Fri Feb 14 00:27:27 2003 @@ -150,13 +150,10 @@ sz = sb.st_size; fprintf (stderr, "System is %d kB\n", sz/1024); sys_size = (sz + 15) / 16; - /* 0x28000*16 = 2.5 MB, conservative estimate for the current maximum */ - if (sys_size > (is_big_kernel ? 0x28000 : DEF_SYSSIZE)) + /* 0x40000*16 = 4.0 MB, reasonable estimate for the current maximum */ + if (sys_size > (is_big_kernel ? 0x40000 : DEF_SYSSIZE)) die("System is too big. Try using %smodules.", is_big_kernel ? "" : "bzImage or "); - if (sys_size > 0xefff) - fprintf(stderr,"warning: kernel is too big for standalone boot " - "from floppy\n"); while (sz > 0) { int l, n; diff -Nru a/arch/x86_64/defconfig b/arch/x86_64/defconfig --- a/arch/x86_64/defconfig Fri Feb 14 00:27:29 2003 +++ b/arch/x86_64/defconfig Fri Feb 14 00:27:29 2003 @@ -5,7 +5,6 @@ CONFIG_X86=y CONFIG_MMU=y CONFIG_SWAP=y -CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_X86_CMPXCHG=y CONFIG_EARLY_PRINTK=y @@ -22,12 +21,6 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -# CONFIG_LOG_BUF_SHIFT_17 is not set -CONFIG_LOG_BUF_SHIFT_16=y -# CONFIG_LOG_BUF_SHIFT_15 is not set -# CONFIG_LOG_BUF_SHIFT_14 is not set -# CONFIG_LOG_BUF_SHIFT_13 is not set -# CONFIG_LOG_BUF_SHIFT_12 is not set CONFIG_LOG_BUF_SHIFT=16 # @@ -37,6 +30,7 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set # CONFIG_KMOD is not set # @@ -103,6 +97,7 @@ # CONFIG_BINFMT_MISC is not set CONFIG_IA32_EMULATION=y CONFIG_COMPAT=y +CONFIG_UID16=y # # Memory Technology Devices (MTD) @@ -290,6 +285,7 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set @@ -490,6 +486,7 @@ # CONFIG_DRM is not set # CONFIG_MWAVE is not set CONFIG_RAW_DRIVER=y +# CONFIG_HANGCHECK_TIMER is not set # # Misc devices @@ -615,7 +612,6 @@ # CONFIG_DEBUG_SLAB is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_DEBUG_SPINLOCK is not set -CONFIG_CHECKING=y # CONFIG_INIT_DEBUG is not set CONFIG_KALLSYMS=y # CONFIG_FRAME_POINTER is not set diff -Nru a/arch/x86_64/ia32/fpu32.c b/arch/x86_64/ia32/fpu32.c --- a/arch/x86_64/ia32/fpu32.c Fri Feb 14 00:27:26 2003 +++ b/arch/x86_64/ia32/fpu32.c Fri Feb 14 00:27:26 2003 @@ -146,6 +146,7 @@ return -1; } tsk->thread.i387.fxsave.mxcsr &= 0xffbf; + current->used_math = 1; return convert_fxsr_from_user(&tsk->thread.i387.fxsave, buf); } diff -Nru a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c --- a/arch/x86_64/ia32/ia32_signal.c Fri Feb 14 00:27:30 2003 +++ b/arch/x86_64/ia32/ia32_signal.c Fri Feb 14 00:27:30 2003 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -134,7 +135,7 @@ int sig; struct sigcontext_ia32 sc; struct _fpstate_ia32 fpstate; - unsigned int extramask[_IA32_NSIG_WORDS-1]; + unsigned int extramask[_COMPAT_NSIG_WORDS-1]; char retcode[8]; }; @@ -237,7 +238,7 @@ if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__get_user(set.sig[0], &frame->sc.oldmask) - || (_IA32_NSIG_WORDS > 1 + || (_COMPAT_NSIG_WORDS > 1 && __copy_from_user((((char *) &set.sig) + 4), &frame->extramask, sizeof(frame->extramask)))) goto badframe; @@ -373,7 +374,7 @@ } void ia32_setup_frame(int sig, struct k_sigaction *ka, - sigset32_t *set, struct pt_regs * regs) + compat_sigset_t *set, struct pt_regs * regs) { struct sigframe *frame; int err = 0; @@ -399,7 +400,7 @@ if (err) goto give_sigsegv; - if (_IA32_NSIG_WORDS > 1) { + if (_COMPAT_NSIG_WORDS > 1) { err |= __copy_to_user(frame->extramask, &set->sig[1], sizeof(frame->extramask)); } @@ -460,7 +461,7 @@ } void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - sigset32_t *set, struct pt_regs * regs) + compat_sigset_t *set, struct pt_regs * regs) { struct rt_sigframe *frame; int err = 0; diff -Nru a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S --- a/arch/x86_64/ia32/ia32entry.S Fri Feb 14 00:27:28 2003 +++ b/arch/x86_64/ia32/ia32entry.S Fri Feb 14 00:27:28 2003 @@ -273,7 +273,7 @@ .quad sys_setreuid16 /* 70 */ .quad sys_setregid16 .quad stub32_sigsuspend - .quad sys32_sigpending + .quad compat_sys_sigpending .quad sys_sethostname .quad sys32_setrlimit /* 75 */ .quad sys32_old_getrlimit /* old_getrlimit */ @@ -326,7 +326,7 @@ .quad sys32_modify_ldt .quad sys32_adjtimex .quad sys32_mprotect /* 125 */ - .quad sys32_sigprocmask + .quad compat_sys_sigprocmask .quad sys32_module_warning /* create_module */ .quad sys_init_module .quad sys_delete_module @@ -450,7 +450,7 @@ .quad sys32_io_getevents .quad sys32_io_submit .quad sys_io_cancel - .quad sys_ni_syscall /* 250 alloc_huge_pages */ + .quad sys_fadvise64 .quad sys_ni_syscall /* free_huge_pages */ .quad sys_exit_group /* exit_group */ .quad sys_lookup_dcookie diff -Nru a/arch/x86_64/ia32/ipc32.c b/arch/x86_64/ia32/ipc32.c --- a/arch/x86_64/ia32/ipc32.c Fri Feb 14 00:27:28 2003 +++ b/arch/x86_64/ia32/ipc32.c Fri Feb 14 00:27:28 2003 @@ -626,9 +626,7 @@ return -E2BIG; if (!access_ok(VERIFY_READ, sb, nsops * sizeof(struct sembuf))) return -EFAULT; - if (ts32 && - (get_user(ts.tv_sec, &ts32->tv_sec) || - __get_user(ts.tv_nsec, &ts32->tv_nsec))) + if (ts32 && get_compat_timespec(&ts, ts32)) return -EFAULT; set_fs(KERNEL_DS); diff -Nru a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c --- a/arch/x86_64/ia32/sys_ia32.c Fri Feb 14 00:27:28 2003 +++ b/arch/x86_64/ia32/sys_ia32.c Fri Feb 14 00:27:28 2003 @@ -276,10 +276,10 @@ { struct k_sigaction new_ka, old_ka; int ret; - sigset32_t set32; + compat_sigset_t set32; /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset32_t)) + if (sigsetsize != sizeof(compat_sigset_t)) return -EINVAL; if (act) { @@ -287,10 +287,10 @@ __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) || __get_user(new_ka.sa.sa_flags, &act->sa_flags) || __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer)|| - __copy_from_user(&set32, &act->sa_mask, sizeof(sigset32_t))) + __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t))) return -EFAULT; - /* FIXME: here we rely on _IA32_NSIG_WORS to be >= than _NSIG_WORDS << 1 */ + /* FIXME: here we rely on _COMPAT_NSIG_WORS to be >= than _NSIG_WORDS << 1 */ switch (_NSIG_WORDS) { case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32); @@ -306,7 +306,7 @@ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); if (!ret && oact) { - /* FIXME: here we rely on _IA32_NSIG_WORS to be >= than _NSIG_WORDS << 1 */ + /* FIXME: here we rely on _COMPAT_NSIG_WORS to be >= than _NSIG_WORDS << 1 */ switch (_NSIG_WORDS) { case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); @@ -325,7 +325,7 @@ __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) || __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) || __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || - __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset32_t))) + __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t))) return -EFAULT; } @@ -339,7 +339,7 @@ int ret; if (act) { - old_sigset32_t mask; + compat_old_sigset_t mask; if (verify_area(VERIFY_READ, act, sizeof(*act)) || __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) || @@ -368,16 +368,16 @@ size_t sigsetsize); asmlinkage long -sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset, +sys32_rt_sigprocmask(int how, compat_sigset_t *set, compat_sigset_t *oset, unsigned int sigsetsize) { sigset_t s; - sigset32_t s32; + compat_sigset_t s32; int ret; mm_segment_t old_fs = get_fs(); if (set) { - if (copy_from_user (&s32, set, sizeof(sigset32_t))) + if (copy_from_user (&s32, set, sizeof(compat_sigset_t))) return -EFAULT; switch (_NSIG_WORDS) { case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); @@ -398,7 +398,7 @@ case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; } - if (copy_to_user (oset, &s32, sizeof(sigset32_t))) + if (copy_to_user (oset, &s32, sizeof(compat_sigset_t))) return -EFAULT; } return 0; @@ -1219,55 +1219,18 @@ set_fs (KERNEL_DS); ret = sys_sched_rr_get_interval(pid, &t); set_fs (old_fs); - if (verify_area(VERIFY_WRITE, interval, sizeof(struct compat_timespec)) || - __put_user (t.tv_sec, &interval->tv_sec) || - __put_user (t.tv_nsec, &interval->tv_nsec)) + if (put_compat_timespec(&t, interval)) return -EFAULT; return ret; } -extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set, - old_sigset_t *oset); - -asmlinkage long -sys32_sigprocmask(int how, old_sigset32_t *set, old_sigset32_t *oset) -{ - old_sigset_t s; - int ret; - mm_segment_t old_fs = get_fs(); - - if (set && get_user (s, set)) return -EFAULT; - set_fs (KERNEL_DS); - ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL); - set_fs (old_fs); - if (ret) return ret; - if (oset && put_user (s, oset)) return -EFAULT; - return 0; -} - -extern asmlinkage long sys_sigpending(old_sigset_t *set); - -asmlinkage long -sys32_sigpending(old_sigset32_t *set) -{ - old_sigset_t s; - int ret; - mm_segment_t old_fs = get_fs(); - - set_fs (KERNEL_DS); - ret = sys_sigpending(&s); - set_fs (old_fs); - if (put_user (s, set)) return -EFAULT; - return ret; -} - extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize); asmlinkage long -sys32_rt_sigpending(sigset32_t *set, compat_size_t sigsetsize) +sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize) { sigset_t s; - sigset32_t s32; + compat_sigset_t s32; int ret; mm_segment_t old_fs = get_fs(); @@ -1281,7 +1244,7 @@ case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; } - if (copy_to_user (set, &s32, sizeof(sigset32_t))) + if (copy_to_user (set, &s32, sizeof(compat_sigset_t))) return -EFAULT; } return ret; @@ -1369,18 +1332,18 @@ const struct timespec *uts, size_t sigsetsize); asmlinkage long -sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo, +sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo, struct compat_timespec *uts, compat_size_t sigsetsize) { sigset_t s; - sigset32_t s32; + compat_sigset_t s32; struct timespec t; int ret; mm_segment_t old_fs = get_fs(); siginfo_t info; siginfo_t32 info32; - if (copy_from_user (&s32, uthese, sizeof(sigset32_t))) + if (copy_from_user (&s32, uthese, sizeof(compat_sigset_t))) return -EFAULT; switch (_NSIG_WORDS) { case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); @@ -1388,14 +1351,11 @@ case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); } - if (uts) { - if (verify_area(VERIFY_READ, uts, sizeof(struct compat_timespec)) || - __get_user (t.tv_sec, &uts->tv_sec) || - __get_user (t.tv_nsec, &uts->tv_nsec)) - return -EFAULT; - } + if (uts && get_compat_timespec(&t, uts)) + return -EFAULT; set_fs (KERNEL_DS); - ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize); + ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL, + sigsetsize); set_fs (old_fs); if (ret >= 0 && uinfo) { if (copy_to_user (uinfo, siginfo64to32(&info32, &info), @@ -2248,20 +2208,13 @@ mm_segment_t oldfs = get_fs(); int err; - if (utime32) { - if (verify_area(VERIFY_READ, utime32, sizeof(*utime32))) - return -EFAULT; - - if (__get_user(t.tv_sec, &utime32->tv_sec) || - __get_user(t.tv_nsec, &utime32->tv_nsec)) - return -EFAULT; - - } + if (utime32 && get_compat_timespec(&t, utime32)) + return -EFAULT; /* the set_fs is safe because futex doesn't use the seg limit for valid page checking of uaddr. */ set_fs(KERNEL_DS); - err = sys_futex(uaddr, op, val, &t); + err = sys_futex(uaddr, op, val, utime32 ? &t : NULL); set_fs(oldfs); return err; } @@ -2340,22 +2293,18 @@ { long ret; mm_segment_t oldfs; - struct timespec t32; + struct timespec t; /* Harden against bogus ptrace */ if (nr >= 0xffffffff || !access_ok(VERIFY_WRITE, events, nr * sizeof(struct io_event))) return -EFAULT; - if (timeout && - (get_user(t32.tv_sec, &timeout->tv_sec) || - __get_user(t32.tv_nsec, &timeout->tv_nsec))) + if (timeout && get_compat_timespec(&t, timeout)) return -EFAULT; oldfs = get_fs(); set_fs(KERNEL_DS); - ret = sys_io_getevents(ctx_id,min_nr,nr,events,timeout ? &t32 : NULL); + ret = sys_io_getevents(ctx_id,min_nr,nr,events,timeout ? &t : NULL); set_fs(oldfs); - if (timeout && - (__put_user(t32.tv_sec, &timeout->tv_sec) || - __put_user(t32.tv_nsec, &timeout->tv_nsec))) + if (timeout && put_compat_timespec(&t, timeout)) return -EFAULT; return ret; } diff -Nru a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile --- a/arch/x86_64/kernel/Makefile Fri Feb 14 00:27:29 2003 +++ b/arch/x86_64/kernel/Makefile Fri Feb 14 00:27:29 2003 @@ -17,7 +17,7 @@ obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o suspend_asm.o obj-$(CONFIG_ACPI) += acpi.o -#obj-$(CONFIG_ACPI_SLEEP) += acpi_wakeup.o +obj-$(CONFIG_ACPI_SLEEP) += wakeup.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o diff -Nru a/arch/x86_64/kernel/acpi.c b/arch/x86_64/kernel/acpi.c --- a/arch/x86_64/kernel/acpi.c Fri Feb 14 00:27:27 2003 +++ b/arch/x86_64/kernel/acpi.c Fri Feb 14 00:27:27 2003 @@ -44,6 +44,9 @@ #include #include #include +#include +#include +#include extern int acpi_disabled; @@ -70,7 +73,6 @@ if (phys_addr < (end_pfn_map << PAGE_SHIFT)) return __va(phys_addr); - printk("acpi mapping beyond end_pfn: %lx > %lx\n", phys_addr, end_pfn< -#endif +extern void acpi_prepare_wakeup(void); +extern unsigned char acpi_wakeup[], acpi_wakeup_end[], s3_prot16[]; /* address in low memory of the wakeup routine. */ -unsigned long acpi_wakeup_address = 0; - -/* new page directory that we will be using */ -static pmd_t *pmd; - -/* saved page directory */ -static pmd_t saved_pmd; - -/* page which we'll use for the new page directory */ -static pte_t *ptep; - -extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); - -/* - * acpi_create_identity_pmd - * - * Create a new, identity mapped pmd. - * - * Do this by creating new page directory, and marking all the pages as R/W - * Then set it as the new Page Middle Directory. - * And, of course, flush the TLB so it takes effect. - * - * We save the address of the old one, for later restoration. - */ -static void acpi_create_identity_pmd (void) -{ - pgd_t *pgd; - int i; - - ptep = (pte_t*)__get_free_page(GFP_KERNEL); - - /* fill page with low mapping */ - for (i = 0; i < PTRS_PER_PTE; i++) - set_pte(ptep + i, mk_pte_phys(i << PAGE_SHIFT, PAGE_SHARED)); - - pgd = pgd_offset(current->active_mm, 0); - pmd = pmd_alloc(current->mm,pgd, 0); - - /* save the old pmd */ - saved_pmd = *pmd; - - /* set the new one */ - set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(ptep))); - - /* flush the TLB */ - local_flush_tlb(); -} - -/* - * acpi_restore_pmd - * - * Restore the old pmd saved by acpi_create_identity_pmd and - * free the page that said function alloc'd - */ -static void acpi_restore_pmd (void) -{ - set_pmd(pmd, saved_pmd); - local_flush_tlb(); - free_page((unsigned long)ptep); -} +unsigned long acpi_wakeup_address; /** * acpi_save_state_mem - save kernel state - * - * Create an identity mapped page table and copy the wakeup routine to - * low memory. */ int acpi_save_state_mem (void) { - acpi_create_identity_pmd(); - acpi_copy_wakeup_routine(acpi_wakeup_address); + if (!acpi_wakeup_address) + return -1; + memcpy((void*)acpi_wakeup_address, acpi_wakeup, acpi_wakeup_end - acpi_wakeup); return 0; } /** * acpi_save_state_disk - save kernel state to disk * + * Assume preemption/interrupts are already turned off and that we're running + * on the BP (note this doesn't imply SMP is handled correctly) */ int acpi_save_state_disk (void) { + unsigned long pbase = read_cr3() & PAGE_MASK; + if (pbase >= 0xffffffffUL) { + printk(KERN_ERR "ACPI: High page table. Suspend disabled.\n"); return 1; + } + set_seg_base(smp_processor_id(), GDT_ENTRY_KERNELCS16, s3_prot16); + swap_low_mappings(); + acpi_prepare_wakeup(); + return 0; } /* @@ -537,13 +484,13 @@ */ void acpi_restore_state_mem (void) { - acpi_restore_pmd(); + swap_low_mappings(); } /** * acpi_reserve_bootmem - do _very_ early ACPI initialisation * - * We allocate a page in low memory for the wakeup + * We allocate a page in 1MB low memory for the real-mode wakeup * routine for when we come back from a sleep state. The * runtime allocator allows specification of <16M pages, but not * <1M pages. @@ -551,7 +498,10 @@ void __init acpi_reserve_bootmem(void) { acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); - printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address); + if (!acpi_wakeup_address) { + printk(KERN_ERR "ACPI: Cannot allocate lowmem. S3 disabled.\n"); + return; + } } #endif /*CONFIG_ACPI_SLEEP*/ diff -Nru a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c --- a/arch/x86_64/kernel/aperture.c Fri Feb 14 00:27:29 2003 +++ b/arch/x86_64/kernel/aperture.c Fri Feb 14 00:27:29 2003 @@ -57,7 +57,7 @@ printk("Cannot allocate aperture memory hole (%p,%uK)\n", p, aper_size>>10); if (p) - free_bootmem((unsigned long)p, aper_size); + free_bootmem_node(nd0, (unsigned long)p, aper_size); return 0; } printk("Mapping aperture over %d KB of RAM @ %lx\n", diff -Nru a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c --- a/arch/x86_64/kernel/apic.c Fri Feb 14 00:27:27 2003 +++ b/arch/x86_64/kernel/apic.c Fri Feb 14 00:27:27 2003 @@ -1026,7 +1026,7 @@ irq_exit(); } -int disable_apic __initdata; +int disable_apic; /* * This initializes the IO-APIC and APIC hardware if this is @@ -1038,8 +1038,10 @@ printk(KERN_INFO "Apic disabled\n"); return -1; } - if (!smp_found_config && !cpu_has_apic) + if (!smp_found_config && !cpu_has_apic) { + disable_apic = 1; return -1; + } /* * Complain if the BIOS pretends there is one. @@ -1047,6 +1049,7 @@ if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_id])) { printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", boot_cpu_id); + disable_apic = 1; return -1; } diff -Nru a/arch/x86_64/kernel/bluesmoke.c b/arch/x86_64/kernel/bluesmoke.c --- a/arch/x86_64/kernel/bluesmoke.c Fri Feb 14 00:27:30 2003 +++ b/arch/x86_64/kernel/bluesmoke.c Fri Feb 14 00:27:30 2003 @@ -1,5 +1,9 @@ /* * arch/x86_64/kernel/bluesmoke.c - x86-64 Machine Check Exception Reporting + * + +RED-PEN: need to add power management to restore after S3 wakeup. + */ #include diff -Nru a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c --- a/arch/x86_64/kernel/e820.c Fri Feb 14 00:27:27 2003 +++ b/arch/x86_64/kernel/e820.c Fri Feb 14 00:27:27 2003 @@ -19,13 +19,17 @@ #include #include -extern unsigned long table_start, table_end; extern char _end[]; /* + * PFN of last memory page. + */ +unsigned long end_pfn; + +/* * end_pfn only includes RAM, while end_pfn_map includes all e820 entries. * The direct mapping extends to end_pfn_map, so that we can directly access - * ACPI and other tables without having to play with fixmaps. + * apertures, ACPI and other tables without having to play with fixmaps. */ unsigned long end_pfn_map; @@ -42,18 +46,16 @@ unsigned long addr = *addrp, last = addr + size; /* various gunk below that needed for SMP startup */ - if (addr < 7*PAGE_SIZE) { - *addrp = 7*PAGE_SIZE; + if (addr < 0x8000) { + *addrp = 0x8000; return 1; } -#if 0 /* direct mapping tables of the kernel */ if (last >= table_start< end_pfn_map) end_pfn = end_pfn_map; + + return end_pfn; } /* diff -Nru a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c --- a/arch/x86_64/kernel/early_printk.c Fri Feb 14 00:27:29 2003 +++ b/arch/x86_64/kernel/early_printk.c Fri Feb 14 00:27:29 2003 @@ -3,6 +3,7 @@ #include #include #include +#include /* Simple VGA output */ @@ -104,9 +105,9 @@ s = strsep(&opt, ","); if (s != NULL) { unsigned port; - if (!strncmp(s,"0x",2)) + if (!strncmp(s,"0x",2)) { early_serial_base = simple_strtoul(s, &e, 16); - else { + } else { static int bases[] = { 0x3f8, 0x2f8 }; if (!strncmp(s,"ttyS",4)) s+=4; diff -Nru a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S --- a/arch/x86_64/kernel/entry.S Fri Feb 14 00:27:27 2003 +++ b/arch/x86_64/kernel/entry.S Fri Feb 14 00:27:27 2003 @@ -512,8 +512,7 @@ * Exception entry point. This expects an error code/orig_rax on the stack * and the exception handler in %rax. */ - ALIGN -error_entry: +ENTRY(error_entry) /* rdi slot contains rax, oldrax contains error code */ pushq %rsi movq 8(%rsp),%rsi /* load rax */ @@ -532,10 +531,7 @@ xorl %ebx,%ebx swapgs error_sti: - bt $9,EFLAGS(%rsp) - jnc 1f - sti -1: movq %rdi,RDI(%rsp) + movq %rdi,RDI(%rsp) movq %rsp,%rdi movq ORIG_RAX(%rsp),%rsi /* get error code */ movq $-1,ORIG_RAX(%rsp) @@ -573,7 +569,8 @@ swapgs gs_change: movl %edi,%gs -2: swapgs +2: sfence /* workaround */ + swapgs popf ret diff -Nru a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S --- a/arch/x86_64/kernel/head.S Fri Feb 14 00:27:29 2003 +++ b/arch/x86_64/kernel/head.S Fri Feb 14 00:27:29 2003 @@ -72,8 +72,7 @@ /* Setup EFER (Extended Feature Enable Register) */ movl $MSR_EFER, %ecx rdmsr - /* Fool rdmsr and reset %eax to avoid dependences */ - xorl %eax, %eax + /* Enable Long Mode */ btsl $_EFER_LME, %eax /* Enable System Call */ @@ -112,7 +111,6 @@ jnz second /* Load new GDT with the 64bit segment using 32bit descriptor */ - /* to avoid 32bit relocations we use fixed adresses here */ movl $(pGDT32 - __START_KERNEL_map), %eax lgdt (%eax) @@ -349,17 +347,14 @@ .quad 0x00cffe000000ffff /* __USER32_CS */ .quad 0x00cff2000000ffff /* __USER_DS, __USER32_DS */ .quad 0x00affa000000ffff /* __USER_CS */ - .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) - .word 0 # base address = 0 - .word 0x9A00 # code read/exec - .word 0x00CF # granularity = 4096, 386 - # (+5th nibble of limit) - /* __KERNEL32_CS */ + .quad 0x00cf9a000000ffff /* __KERNEL32_CS */ .quad 0,0 /* TSS */ .quad 0 /* LDT */ .quad 0,0,0 /* three TLS descriptors */ - .quad 0x00cff2000000ffff /* dummy descriptor for long base */ - .quad 0 /* pad to cache line boundary */ + .quad 0 /* unused now */ + .quad 0x00009a000000ffff /* __KERNEL16_CS - 16bit PM for S3 wakeup. */ + /* base must be patched for real base address. */ + /* This should be a multiple of the cache line size */ gdt_end: .globl gdt_end diff -Nru a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c --- a/arch/x86_64/kernel/head64.c Fri Feb 14 00:27:28 2003 +++ b/arch/x86_64/kernel/head64.c Fri Feb 14 00:27:28 2003 @@ -13,6 +13,8 @@ #include #include +#include +#include /* Don't add a printk in there. printk relies on the PDA which is not initialized yet. */ @@ -70,9 +72,6 @@ boot_cpu_data.x86_mask = eax & 0xf; } -extern void start_kernel(void), pda_init(int), setup_early_printk(char *); -extern int disable_apic; - void __init x86_64_start_kernel(char * real_mode_data) { char *s; @@ -83,6 +82,11 @@ s = strstr(saved_command_line, "earlyprintk="); if (s != NULL) setup_early_printk(s+12); +#ifdef CONFIG_DISCONTIGMEM + s = strstr(saved_command_line, "numa="); + if (s != NULL) + numa_setup(s+5); +#endif #ifdef CONFIG_X86_IO_APIC if (strstr(saved_command_line, "disableapic")) disable_apic = 1; diff -Nru a/arch/x86_64/kernel/init_task.c b/arch/x86_64/kernel/init_task.c --- a/arch/x86_64/kernel/init_task.c Fri Feb 14 00:27:28 2003 +++ b/arch/x86_64/kernel/init_task.c Fri Feb 14 00:27:28 2003 @@ -11,6 +11,7 @@ static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); /* diff -Nru a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c --- a/arch/x86_64/kernel/irq.c Fri Feb 14 00:27:28 2003 +++ b/arch/x86_64/kernel/irq.c Fri Feb 14 00:27:28 2003 @@ -137,7 +137,8 @@ struct irqaction * action; seq_printf(p, " "); - for_each_cpu(j) + for (j=0; jnext) { + for (prevp = &mod_vmlist ; (map = *prevp) ; prevp = &map->next) { if ((unsigned long)map->addr == addr) { *prevp = map->next; write_unlock(&vmlist_lock); @@ -81,7 +86,7 @@ write_lock(&vmlist_lock); addr = (void *) MODULES_VADDR; - for (p = &vmlist; (tmp = *p); p = &tmp->next) { + for (p = &mod_vmlist; (tmp = *p); p = &tmp->next) { void *next; DEBUGP("vmlist %p %lu addr %p\n", tmp->addr, tmp->size, addr); if (size + (unsigned long) addr + PAGE_SIZE < (unsigned long) tmp->addr) diff -Nru a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c --- a/arch/x86_64/kernel/mpparse.c Fri Feb 14 00:27:27 2003 +++ b/arch/x86_64/kernel/mpparse.c Fri Feb 14 00:27:27 2003 @@ -29,6 +29,7 @@ #include #include #include +#include /* Have we found an MP table */ int smp_found_config; @@ -83,7 +84,6 @@ * Intel MP BIOS table parsing routines: */ -#ifndef CONFIG_X86_VISWS_APIC /* * Checksum an MP configuration block. */ @@ -582,9 +582,9 @@ smp_found_config = 1; printk("found SMP MP-table at %08lx\n", virt_to_phys(mpf)); - reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE); + reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE); if (mpf->mpf_physptr) - reserve_bootmem(mpf->mpf_physptr, PAGE_SIZE); + reserve_bootmem_generic(mpf->mpf_physptr, PAGE_SIZE); mpf_found = mpf; return 1; } @@ -632,37 +632,13 @@ printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.kernel.org if you experience SMP problems!\n"); } -#else - -/* - * The Visual Workstation is Intel MP compliant in the hardware - * sense, but it doesnt have a BIOS(-configuration table). - * No problem for Linux. - */ -void __init find_visws_smp(void) -{ - smp_found_config = 1; - - phys_cpu_present_map |= 2; /* or in id 1 */ - apic_version[1] |= 0x10; /* integrated APIC */ - apic_version[0] |= 0x10; - - mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; -} - -#endif - /* * - Intel MP Configuration Table - * - or SGI Visual Workstation configuration */ void __init find_smp_config (void) { #ifdef CONFIG_X86_LOCAL_APIC find_intel_smp(); -#endif -#ifdef CONFIG_VISWS - find_visws_smp(); #endif } diff -Nru a/arch/x86_64/kernel/msr.c b/arch/x86_64/kernel/msr.c --- a/arch/x86_64/kernel/msr.c Fri Feb 14 00:27:27 2003 +++ b/arch/x86_64/kernel/msr.c Fri Feb 14 00:27:27 2003 @@ -22,6 +22,9 @@ * * This driver uses /dev/cpu/%d/msr where %d is the minor number, and on * an SMP box will direct the access to CPU %d. + +RED-PEN: need to get power management for S3 restore + */ #include diff -Nru a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c --- a/arch/x86_64/kernel/nmi.c Fri Feb 14 00:27:28 2003 +++ b/arch/x86_64/kernel/nmi.c Fri Feb 14 00:27:28 2003 @@ -24,6 +24,7 @@ #include #include #include +#include extern void default_do_nmi(struct pt_regs *); @@ -71,13 +72,14 @@ printk(KERN_INFO "testing NMI watchdog ... "); - for_each_cpu(cpu) { + for (cpu = 0; cpu < NR_CPUS; cpu++) counts[cpu] = cpu_pda[cpu].__nmi_count; - } local_irq_enable(); mdelay((10*1000)/nmi_hz); // wait 10 ticks - for_each_cpu(cpu) { + for (cpu = 0; cpu < NR_CPUS; cpu++) { + if (!cpu_online(cpu)) + continue; if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) { printk("CPU#%d: NMI appears to be stuck (%d)!\n", cpu, @@ -173,7 +175,7 @@ * Original code written by Keith Owens. */ -static void __pminit setup_k7_watchdog(void) +static void setup_k7_watchdog(void) { int i; unsigned int evntsel; @@ -183,8 +185,10 @@ nmi_perfctr_msr = MSR_K7_PERFCTR0; for(i = 0; i < 4; ++i) { - wrmsr(MSR_K7_EVNTSEL0+i, 0, 0); - wrmsr(MSR_K7_PERFCTR0+i, 0, 0); + /* Simulator may not support it */ + if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL)) + return; + wrmsrl(MSR_K7_PERFCTR0+i, 0UL); } evntsel = K7_EVNTSEL_INT @@ -200,15 +204,11 @@ wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); } -void __pminit setup_apic_nmi_watchdog (void) +void setup_apic_nmi_watchdog (void) { switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: if (boot_cpu_data.x86 < 6) - return; - /* Simics masquerades as AMD, but does not support - performance counters */ - if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) return; setup_k7_watchdog(); break; diff -Nru a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c --- a/arch/x86_64/kernel/process.c Fri Feb 14 00:27:26 2003 +++ b/arch/x86_64/kernel/process.c Fri Feb 14 00:27:26 2003 @@ -366,12 +366,15 @@ also reload when it has changed. when prev process used 64bit base always reload to avoid an information leak. */ - if (unlikely((fsindex | next->fsindex) || prev->fs)) + if (unlikely(fsindex | next->fsindex | prev->fs)) { loadsegment(fs, next->fsindex); - /* check if the user changed the selector - if yes clear 64bit base. */ - if (unlikely(fsindex != prev->fsindex)) + /* check if the user used a selector != 0 + * if yes clear 64bit base, since overloaded base + * is always mapped to the Null selector + */ + if (fsindex) prev->fs = 0; + } /* when next process has a 64bit base use it */ if (next->fs) wrmsrl(MSR_FS_BASE, next->fs); @@ -380,10 +383,11 @@ { unsigned gsindex; asm volatile("movl %%gs,%0" : "=g" (gsindex)); - if (unlikely((gsindex | next->gsindex) || prev->gs)) + if (unlikely(gsindex | next->gsindex | prev->gs)) { load_gs_index(next->gsindex); - if (unlikely(gsindex != prev->gsindex)) + if (gsindex) prev->gs = 0; + } if (next->gs) wrmsrl(MSR_KERNEL_GS_BASE, next->gs); prev->gsindex = gsindex; @@ -537,29 +541,23 @@ switch (code) { case ARCH_SET_GS: -#if 1 - /* For now. We still have one unsolved bug in long gs base context - switch handling. */ - return -EINVAL; -#else if (addr >= TASK_SIZE) return -EPERM; get_cpu(); - load_gs_index(__USER_LONGBASE); - current->thread.gsindex = __USER_LONGBASE; + load_gs_index(0); + current->thread.gsindex = 0; current->thread.gs = addr; ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); put_cpu(); break; -#endif case ARCH_SET_FS: /* Not strictly needed for fs, but do it for symmetry with gs */ if (addr >= TASK_SIZE) return -EPERM; get_cpu(); - asm volatile("movl %0,%%fs" :: "r" (__USER_LONGBASE)); - current->thread.fsindex = __USER_LONGBASE; + asm volatile("movl %0,%%fs" :: "r" (0)); + current->thread.fsindex = 0; current->thread.fs = addr; ret = checking_wrmsrl(MSR_FS_BASE, addr); put_cpu(); diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c --- a/arch/x86_64/kernel/setup.c Fri Feb 14 00:27:26 2003 +++ b/arch/x86_64/kernel/setup.c Fri Feb 14 00:27:26 2003 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,8 @@ #include #include +#define Dprintk(x...) printk(x) + /* * Machine setup.. */ @@ -236,6 +239,8 @@ { int i; + Dprintk("setup_arch\n"); + ROOT_DEV = ORIG_ROOT_DEV; drive_info = DRIVE_INFO; screen_info = SCREEN_INFO; @@ -263,34 +268,34 @@ parse_cmdline_early(cmdline_p); -#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define PFN_PHYS(x) ((x) << PAGE_SHIFT) - -#define MAXMEM (120UL * 1024 * 1024 * 1024 * 1024) /* 120TB */ -#define MAXMEM_PFN PFN_DOWN(MAXMEM) -#define MAX_NONPAE_PFN (1 << 20) - /* * partially used pages are not usable - thus * we are rounding upwards: */ - start_pfn = PFN_UP(__pa_symbol(&_end)); - - e820_end_of_ram(); + end_pfn = e820_end_of_ram(); init_memory_mapping(); +#ifdef CONFIG_DISCONTIGMEM + numa_initmem_init(0, end_pfn); +#else contig_initmem_init(); +#endif + + /* Reserve direct mapping */ + reserve_bootmem_generic(table_start << PAGE_SHIFT, + (table_end - table_start) << PAGE_SHIFT); /* reserve kernel */ - reserve_bootmem(HIGH_MEMORY, PFN_PHYS(start_pfn) - HIGH_MEMORY); + unsigned long kernel_end; + kernel_end = round_up(__pa_symbol(&_end),PAGE_SIZE); + reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY); /* * reserve physical page 0 - it's a special BIOS page on many boxes, * enabling clean reboots, SMP operation, laptop functions. */ - reserve_bootmem(0, PAGE_SIZE); + reserve_bootmem_generic(0, PAGE_SIZE); #ifdef CONFIG_SMP /* @@ -298,8 +303,12 @@ * FIXME: Don't need the extra page at 4K, but need to fix * trampoline before removing it. (see the GDT stuff) */ - reserve_bootmem(PAGE_SIZE, PAGE_SIZE); + reserve_bootmem_generic(PAGE_SIZE, PAGE_SIZE); + + /* Reserve SMP trampoline */ + reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, PAGE_SIZE); #endif + #ifdef CONFIG_ACPI_SLEEP /* * Reserve low memory region for sleep support. @@ -315,7 +324,7 @@ #ifdef CONFIG_BLK_DEV_INITRD if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) { - reserve_bootmem(INITRD_START, INITRD_SIZE); + reserve_bootmem_generic(INITRD_START, INITRD_SIZE); initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0; initrd_end = initrd_start+INITRD_SIZE; @@ -330,14 +339,6 @@ } #endif - /* - * NOTE: before this point _nobody_ is allowed to allocate - * any memory using the bootmem allocator. - */ - -#ifdef CONFIG_SMP - smp_alloc_memory(); /* AP processor realmode stacks in low memory*/ -#endif paging_init(); #ifdef CONFIG_ACPI_BOOT /* @@ -347,7 +348,7 @@ * of MADT). */ if (!acpi_disabled) - acpi_boot_init(*cmdline_p); + acpi_boot_init(); #endif #ifdef CONFIG_X86_LOCAL_APIC /* diff -Nru a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c --- a/arch/x86_64/kernel/setup64.c Fri Feb 14 00:27:27 2003 +++ b/arch/x86_64/kernel/setup64.c Fri Feb 14 00:27:27 2003 @@ -1,7 +1,7 @@ /* * X86-64 specific CPU setup. * Copyright (C) 1995 Linus Torvalds - * Copyright 2001, 2002 SuSE Labs / Andi Kleen. + * Copyright 2001, 2002, 2003 SuSE Labs / Andi Kleen. * See setup.c for older changelog. * $Id: setup64.c,v 1.12 2002/03/21 10:09:17 ak Exp $ */ @@ -90,6 +90,17 @@ pml4_t *level4; struct x8664_pda *pda = &cpu_pda[cpu]; + /* Setup up data that may be needed in __get_free_pages early */ + asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0)); + wrmsrl(MSR_GS_BASE, cpu_pda + cpu); + + pda->me = pda; + pda->cpunumber = cpu; + pda->irqcount = -1; + pda->cpudata_offset = 0; + pda->kernelstack = + (unsigned long)current_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; + if (cpu == 0) { /* others are initialized in smpboot.c */ pda->pcurrent = &init_task; @@ -112,18 +123,8 @@ asm volatile("movq %0,%%cr3" :: "r" (__pa(level4))); pda->irqstackptr += IRQSTACKSIZE-64; - pda->cpunumber = cpu; - pda->irqcount = -1; - pda->kernelstack = - (unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; - pda->me = pda; - pda->cpudata_offset = 0; - pda->active_mm = &init_mm; pda->mmu_state = 0; - - asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0)); - wrmsrl(MSR_GS_BASE, cpu_pda + cpu); } #define EXCEPTION_STK_ORDER 0 /* >= N_EXCEPTION_STACKS*EXCEPTION_STKSZ */ @@ -150,10 +151,10 @@ /* CPU 0 is initialised in head64.c */ if (cpu != 0) { + pda_init(cpu); estacks = (char *)__get_free_pages(GFP_ATOMIC, 0); if (!estacks) panic("Can't allocate exception stacks for CPU %d\n",cpu); - pda_init(cpu); } else estacks = boot_exception_stacks; diff -Nru a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c --- a/arch/x86_64/kernel/signal.c Fri Feb 14 00:27:29 2003 +++ b/arch/x86_64/kernel/signal.c Fri Feb 14 00:27:29 2003 @@ -353,7 +353,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) { - struct k_sigaction *ka = ¤t->sig->action[sig-1]; + struct k_sigaction *ka = ¤t->sighand->action[sig-1]; #if DEBUG_SIG printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", current->pid, sig, @@ -437,7 +437,7 @@ if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { /* Reenable any watchpoints before delivering the * signal to user space. The processor register will diff -Nru a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c --- a/arch/x86_64/kernel/smp.c Fri Feb 14 00:27:27 2003 +++ b/arch/x86_64/kernel/smp.c Fri Feb 14 00:27:27 2003 @@ -3,6 +3,7 @@ * * (c) 1995 Alan Cox, Building #3 * (c) 1998-99, 2000 Ingo Molnar + * (c) 2002,2003 Andi Kleen, SuSE Labs. * * This code is released under the GNU General Public License version 2 or * later. @@ -491,3 +492,24 @@ } } + +/* Slow. Should be only used for debugging. */ +int slow_smp_processor_id(void) +{ + int stack_location; + unsigned long sp = (unsigned long)&stack_location; + int cpu; + unsigned long mask; + + for_each_cpu(cpu, mask) { + if (sp >= (u64)cpu_pda[cpu].irqstackptr - IRQSTACKSIZE && + sp <= (u64)cpu_pda[cpu].irqstackptr) + return cpu; + + unsigned long estack = init_tss[cpu].ist[0] - EXCEPTION_STKSZ; + if (sp >= estack && sp <= estack+(1<<(PAGE_SHIFT+EXCEPTION_STK_ORDER))) + return cpu; + } + + return stack_smp_processor_id(); +} diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c --- a/arch/x86_64/kernel/smpboot.c Fri Feb 14 00:27:30 2003 +++ b/arch/x86_64/kernel/smpboot.c Fri Feb 14 00:27:30 2003 @@ -51,13 +51,10 @@ #include #include -/* Bitmask of currently online CPUs */ -unsigned long cpu_online_map; +extern int disable_apic; -/* which CPU (physical APIC ID) maps to which logical CPU number */ -volatile int x86_apicid_to_cpu[NR_CPUS]; -/* which logical CPU number maps to which CPU (physical APIC ID) */ -volatile int x86_cpu_to_apicid[NR_CPUS]; +/* Bitmask of currently online CPUs */ +unsigned long cpu_online_map = 1; static volatile unsigned long cpu_callin_map; volatile unsigned long cpu_callout_map; @@ -75,7 +72,6 @@ extern unsigned char trampoline_data []; extern unsigned char trampoline_end []; -static unsigned char *trampoline_base; /* * Currently trivial. Write the real->protected mode @@ -85,25 +81,11 @@ static unsigned long __init setup_trampoline(void) { + void *tramp = __va(SMP_TRAMPOLINE_BASE); extern volatile __u32 tramp_gdt_ptr; tramp_gdt_ptr = __pa_symbol(&cpu_gdt_table); - memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data); - return virt_to_phys(trampoline_base); -} - -/* - * We are called very early to get the low memory for the - * SMP bootup trampoline page. - */ -void __init smp_alloc_memory(void) -{ - trampoline_base = (void *) alloc_bootmem_low_pages(PAGE_SIZE); - /* - * Has to be in very low memory so we can execute - * real-mode AP code. - */ - if (__pa(trampoline_base) >= 0x9F000) - BUG(); + memcpy(tramp, trampoline_data, trampoline_end - trampoline_data); + return virt_to_phys(tramp); } /* @@ -174,6 +156,7 @@ */ atomic_inc(&tsc_count_start); + sync_core(); rdtscll(tsc_values[smp_processor_id()]); /* * We clear the TSC in the last loop: @@ -245,6 +228,7 @@ atomic_inc(&tsc_count_start); while (atomic_read(&tsc_count_start) != num_booting_cpus()) mb(); + sync_core(); rdtscll(tsc_values[smp_processor_id()]); if (i == NR_LOOPS-1) write_tsc(0, 0); @@ -369,6 +353,9 @@ cpu_init(); smp_callin(); + /* otherwise gcc will move up the smp_processor_id before the cpu_init */ + barrier(); + Dprintk("cpu %d: waiting for commence\n", smp_processor_id()); while (!test_bit(smp_processor_id(), &smp_commenced_mask)) rep_nop(); @@ -620,8 +607,6 @@ */ init_idle(idle,cpu); - x86_cpu_to_apicid[cpu] = apicid; - x86_apicid_to_cpu[apicid] = cpu; idle->thread.rip = (unsigned long)start_secondary; // idle->thread.rsp = (unsigned long)idle->thread_info + THREAD_SIZE - 512; @@ -713,8 +698,6 @@ } } if (boot_error) { - x86_cpu_to_apicid[cpu] = -1; - x86_apicid_to_cpu[apicid] = -1; clear_bit(cpu, &cpu_callout_map); /* was set here (do_boot_cpu()) */ clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ cpucount--; @@ -777,22 +760,12 @@ int apicid, cpu; /* - * Initialize the logical to physical CPU number mapping - */ - - for (apicid = 0; apicid < NR_CPUS; apicid++) { - x86_apicid_to_cpu[apicid] = -1; - } - - /* * Setup boot CPU information */ smp_store_cpu_info(0); /* Final full version of the data */ printk("CPU%d: ", 0); print_cpu_info(&cpu_data[0]); - x86_apicid_to_cpu[boot_cpu_id] = 0; - x86_cpu_to_apicid[0] = boot_cpu_id; current_thread_info()->cpu = 0; smp_tune_scheduling(); @@ -837,6 +810,7 @@ io_apic_irqs = 0; cpu_online_map = phys_cpu_present_map = 1; phys_cpu_present_map = 1; + disable_apic = 1; return; } @@ -851,6 +825,7 @@ io_apic_irqs = 0; cpu_online_map = phys_cpu_present_map = 1; phys_cpu_present_map = 1; + disable_apic = 1; return; } @@ -878,13 +853,6 @@ continue; do_boot_cpu(apicid); - - /* - * Make sure we unmap all failed CPUs - */ - if ((x86_apicid_to_cpu[apicid] == -1) && - (phys_cpu_present_map & (1 << apicid))) - printk("phys CPU #%d not responding - cannot use it.\n",apicid); } /* diff -Nru a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c --- a/arch/x86_64/kernel/sys_x86_64.c Fri Feb 14 00:27:29 2003 +++ b/arch/x86_64/kernel/sys_x86_64.c Fri Feb 14 00:27:29 2003 @@ -55,7 +55,6 @@ if (!file) goto out; } - down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT); up_write(¤t->mm->mmap_sem); diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c --- a/arch/x86_64/kernel/time.c Fri Feb 14 00:27:29 2003 +++ b/arch/x86_64/kernel/time.c Fri Feb 14 00:27:29 2003 @@ -9,6 +9,7 @@ * Copyright (c) 1996 Ingo Molnar * Copyright (c) 1998 Andrea Arcangeli * Copyright (c) 2002 Vojtech Pavlik + * Copyright (c) 2003 Andi Kleen * */ @@ -25,9 +26,14 @@ #include #include #include +#ifdef CONFIG_X86_LOCAL_APIC +#include +#endif u64 jiffies_64; +extern int using_apic_timer; + spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; extern int using_apic_timer; @@ -56,12 +62,10 @@ * together by xtime_lock. */ -static spinlock_t time_offset_lock = SPIN_LOCK_UNLOCKED; -static unsigned long timeoffset = 0; - inline unsigned int do_gettimeoffset(void) { unsigned long t; + sync_core(); rdtscll(t); return (t - hpet.last_tsc) * (1000000L / HZ) / hpet.ticks + hpet.offset; } @@ -74,10 +78,9 @@ void do_gettimeofday(struct timeval *tv) { - unsigned long flags, t, seq; + unsigned long seq, t; unsigned int sec, usec; - spin_lock_irqsave(&time_offset_lock, flags); do { seq = read_seqbegin(&xtime_lock); @@ -85,11 +88,9 @@ usec = xtime.tv_nsec / 1000; t = (jiffies - wall_jiffies) * (1000000L / HZ) + do_gettimeoffset(); - if (t > timeoffset) timeoffset = t; - usec += timeoffset; + usec += t; } while (read_seqretry(&xtime_lock, seq)); - spin_unlock_irqrestore(&time_offset_lock, flags); tv->tv_sec = sec + usec / 1000000; tv->tv_usec = usec % 1000000; @@ -104,7 +105,6 @@ void do_settimeofday(struct timeval *tv) { write_seqlock_irq(&xtime_lock); - vxtime_lock(); tv->tv_usec -= do_gettimeoffset() + (jiffies - wall_jiffies) * tick_usec; @@ -116,7 +116,6 @@ xtime.tv_sec = tv->tv_sec; xtime.tv_nsec = (tv->tv_usec * 1000); - vxtime_unlock(); time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; @@ -207,11 +206,11 @@ */ write_seqlock(&xtime_lock); - vxtime_lock(); { unsigned long t; + sync_core(); rdtscll(t); hpet.offset = (t - hpet.last_tsc) * (1000000L / HZ) / hpet.ticks + hpet.offset - 1000000L / HZ; if (hpet.offset >= 1000000L / HZ) @@ -219,7 +218,6 @@ hpet.ticks = min_t(long, max_t(long, (t - hpet.last_tsc) * (1000000L / HZ) / (1000000L / HZ - hpet.offset), cpu_khz * 1000/HZ * 15 / 16), cpu_khz * 1000/HZ * 16 / 15); hpet.last_tsc = t; - timeoffset = 0; } /* @@ -255,7 +253,6 @@ rtc_update = xtime.tv_sec + 660; } - vxtime_unlock(); write_sequnlock(&xtime_lock); } @@ -348,8 +345,9 @@ outb((1193182 / (1000 / 50)) & 0xff, 0x42); outb((1193182 / (1000 / 50)) >> 8, 0x42); rdtscll(start); - + sync_core(); while ((inb(0x61) & 0x20) == 0); + sync_core(); rdtscll(end); @@ -382,12 +380,12 @@ pit_init(); printk(KERN_INFO "time.c: Using 1.1931816 MHz PIT timer.\n"); - setup_irq(0, &irq0); cpu_khz = pit_calibrate_tsc(); printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); hpet.ticks = cpu_khz * (1000 / HZ); rdtscll(hpet.last_tsc); + setup_irq(0, &irq0); } __setup("report_lost_ticks", time_setup); diff -Nru a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c --- a/arch/x86_64/kernel/traps.c Fri Feb 14 00:27:26 2003 +++ b/arch/x86_64/kernel/traps.c Fri Feb 14 00:27:26 2003 @@ -77,6 +77,12 @@ struct notifier_block *die_chain; +static inline void conditional_sti(struct pt_regs *regs) +{ + if (regs->eflags & X86_EFLAGS_IF) + local_irq_enable(); +} + static int kstack_depth_to_print = 10; #ifdef CONFIG_KALLSYMS @@ -128,8 +134,7 @@ { unsigned long addr; unsigned long *irqstack, *irqstack_end, *estack_end; - /* FIXME: should read the cpuid from the APIC; to still work with bogus %gs */ - const int cpu = smp_processor_id(); + const int cpu = safe_smp_processor_id(); int i; printk("\nCall Trace:"); @@ -210,7 +215,7 @@ { unsigned long *stack; int i; - const int cpu = smp_processor_id(); + const int cpu = safe_smp_processor_id(); unsigned long *irqstack_end = (unsigned long *) (cpu_pda[cpu].irqstackptr); unsigned long *irqstack = (unsigned long *) (cpu_pda[cpu].irqstackptr - IRQSTACKSIZE); @@ -252,12 +257,7 @@ int i; int in_kernel = (regs->cs & 3) == 0; unsigned long rsp; -#ifdef CONFIG_SMP - /* For SMP should get the APIC id here, just to protect against corrupted GS */ - const int cpu = smp_processor_id(); -#else - const int cpu = 0; -#endif + const int cpu = safe_smp_processor_id(); struct task_struct *cur = cpu_pda[cpu].pcurrent; rsp = regs->rsp; @@ -330,7 +330,7 @@ bust_spinlocks(1); handle_BUG(regs); printk("%s: %04lx\n", str, err & 0xffff); - cpu = smp_processor_id(); + cpu = safe_smp_processor_id(); /* racy, but better than risking deadlock. */ local_irq_disable(); if (!spin_trylock(&die_lock)) { @@ -365,10 +365,12 @@ static void do_trap(int trapnr, int signr, char *str, struct pt_regs * regs, long error_code, siginfo_t *info) { + conditional_sti(regs); + #ifdef CONFIG_CHECKING { unsigned long gs; - struct x8664_pda *pda = cpu_pda + stack_smp_processor_id(); + struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); rdmsrl(MSR_GS_BASE, gs); if (gs != (unsigned long)pda) { wrmsrl(MSR_GS_BASE, pda); @@ -454,10 +456,12 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) { + conditional_sti(regs); + #ifdef CONFIG_CHECKING { unsigned long gs; - struct x8664_pda *pda = cpu_pda + hard_smp_processor_id(); + struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); rdmsrl(MSR_GS_BASE, gs); if (gs != (unsigned long)pda) { wrmsrl(MSR_GS_BASE, pda); @@ -565,7 +569,7 @@ #ifdef CONFIG_CHECKING { unsigned long gs; - struct x8664_pda *pda = cpu_pda + stack_smp_processor_id(); + struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); rdmsrl(MSR_GS_BASE, gs); if (gs != (unsigned long)pda) { wrmsrl(MSR_GS_BASE, pda); @@ -576,6 +580,8 @@ asm("movq %%db6,%0" : "=r" (condition)); + conditional_sti(regs); + if (notify_die(DIE_DEBUG, "debug", regs, error_code) == NOTIFY_BAD) return; @@ -636,7 +642,6 @@ struct task_struct * task; siginfo_t info; unsigned short cwd, swd; - /* * Save the info for the exception handler and clear the error. */ @@ -688,6 +693,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code) { + conditional_sti(regs); math_error((void *)regs->rip); } @@ -747,6 +753,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs, long error_code) { + conditional_sti(regs); simd_math_error((void *)regs->rip); } diff -Nru a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c --- a/arch/x86_64/kernel/vsyscall.c Fri Feb 14 00:27:29 2003 +++ b/arch/x86_64/kernel/vsyscall.c Fri Feb 14 00:27:29 2003 @@ -2,6 +2,7 @@ * linux/arch/x86_64/kernel/vsyscall.c * * Copyright (C) 2001 Andrea Arcangeli SuSE + * Copyright 2003 Andi Kleen, SuSE Labs. * * Thanks to hpa@transmeta.com for some useful hint. * Special thanks to Ingo Molnar for his early experience with @@ -12,7 +13,8 @@ * vsyscalls. One vsyscall can reserve more than 1 slot to avoid * jumping out of line if necessary. * - * $Id: vsyscall.c,v 1.9 2002/03/21 13:42:58 ak Exp $ + * Note: the concept clashes with user mode linux. If you use UML just + * set the kernel.vsyscall sysctl to 0. */ /* @@ -29,6 +31,9 @@ * broken programs will segfault and there's no security risk until we choose to * fix it. * + * Add HPET support (port from 2.4). Still needed? + * Nop out vsyscall syscall to avoid anchor for buffer overflows when sysctl off. + * * These are not urgent things that we need to address only before shipping the first * production binary kernels. */ @@ -37,6 +42,7 @@ #include #include #include +#include #include #include @@ -44,19 +50,13 @@ #include #include - #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) -#define NO_VSYSCALL 1 +int __sysctl_vsyscall __section_sysctl_vsyscall = 1; +seqlock_t __xtime_lock __section_xtime_lock = SEQLOCK_UNLOCKED; -#ifdef NO_VSYSCALL #include -static int errno __section_vxtime_sequence; - -static inline _syscall2(int,gettimeofday,struct timeval *,tv,struct timezone *,tz) - -#else static inline void timeval_normalize(struct timeval * tv) { time_t __sec; @@ -69,63 +69,60 @@ } } -long __vxtime_sequence[2] __section_vxtime_sequence; - - static inline void do_vgettimeofday(struct timeval * tv) { long sequence, t; unsigned long sec, usec; do { - sequence = __vxtime_sequence[1]; - rmb(); + sequence = read_seqbegin(&__xtime_lock); + sync_core(); rdtscll(t); sec = __xtime.tv_sec; - usec = __xtime.tv_usec + + usec = (__xtime.tv_nsec * 1000) + (__jiffies - __wall_jiffies) * (1000000 / HZ) + (t - __hpet.last_tsc) * (1000000 / HZ) / __hpet.ticks + __hpet.offset; - rmb(); - } while (sequence != __vxtime_sequence[0]); + } while (read_seqretry(&__xtime_lock, sequence)); tv->tv_sec = sec + usec / 1000000; tv->tv_usec = usec % 1000000; } +/* RED-PEN may want to readd seq locking, but then the variable should be write-once. */ static inline void do_get_tz(struct timezone * tz) { - long sequence; - - do { - sequence = __vxtime_sequence[1]; - rmb(); - *tz = __sys_tz; +} - rmb(); - } while (sequence != __vxtime_sequence[0]); +static inline int gettimeofday(struct timeval *tv, struct timezone *tz) +{ + int ret; + asm volatile("syscall" + : "=a" (ret) + : "0" (__NR_gettimeofday),"D" (tv),"S" (tz) : __syscall_clobber ); + return ret; } -#endif static int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz) { -#ifdef NO_VSYSCALL + if (unlikely(!__sysctl_vsyscall)) return gettimeofday(tv,tz); -#else if (tv) do_vgettimeofday(tv); if (tz) do_get_tz(tz); return 0; -#endif } static time_t __vsyscall(1) vtime(time_t * t) { struct timeval tv; - vgettimeofday(&tv,NULL); + if (unlikely(!__sysctl_vsyscall)) + gettimeofday(&tv, NULL); + else + do_vgettimeofday(&tv); if (t) *t = tv.tv_sec; return tv.tv_sec; @@ -139,12 +136,13 @@ static long __vsyscall(3) venosys_1(void) { return -ENOSYS; + } static void __init map_vsyscall(void) { extern char __vsyscall_0; - unsigned long physaddr_page0 = (unsigned long) &__vsyscall_0 - __START_KERNEL_map; + unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0); __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_page0, PAGE_KERNEL_VSYSCALL); } diff -Nru a/arch/x86_64/kernel/wakeup.S b/arch/x86_64/kernel/wakeup.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/x86_64/kernel/wakeup.S Fri Feb 14 00:27:30 2003 @@ -0,0 +1,306 @@ +/* + * ACPI S3 entry/exit handling. + * + * Notes: + * Relies on kernel being loaded below 4GB. + * Needs restore_low_mappings called before. + * + * Copyright 2003 by Andi Kleen, SuSE Labs. + * + * Long mode entry losely based on example code in chapter 14 of the x86-64 system + * programmer's manual. + * + * Notebook: + + FIXME need to interface with suspend.c properly. do_magic. check i386. rename to suspend64.S + + Need to fix vgacon,mtrr,bluesmoke to do resume + + Interrupts should be off until the io-apic code has reinited the APIC. + Need support for that in the pm frame work or a special hack? + + SMP support is non existent. Need to somehow restart the other CPUs again. + If CPU hotplug was working it could be used. Save/Restore needs to run on the same CPU. + + Should check magic like i386 code + + suspend code copies something. check what it is. + */ + +#include + +#include +#include +#include + +#define O(x) (x-acpi_wakeup) + + .text + .code16 +ENTRY(acpi_wakeup) + /* 16bit real mode entered from ACPI BIOS */ + /* The machine is just through BIOS setup after power down and everything set up + by Linux needs to be restored. */ + /* The code here needs to be position independent or manually relocated, + because it is copied to a <1MB page for real mode execution */ + + /* A20 enabled (according to ACPI spec) */ + /* cs = acpi_wakeup >> 4 ; eip = acpi_wakeup & 0xF */ + + movw %cs,%ax + movw %ax,%ds /* make %ds point to acpi_wakeup */ + movw %ax,%ss + movw $O(wakeup_stack),%sp /* setup stack */ + + pushl $0 + popfl /* clear EFLAGS */ + + lgdt %ds:O(pGDT) /* load kernel GDT */ + + movl $0x1,%eax /* enable protected mode */ + movl %eax,%cr0 + + movl %ds:O(wakeup_page_table),%edi + ljmpl $__KERNEL16_CS,$0 /* -> s3_prot16 (filled in earlier by caller) */ + + /* patched by s3_restore_state below */ +pGDT: + .short 0 + .quad 0 + + .align 4 + .globl wakeup_page_table +wakeup_page_table: + .long 0 + + .align 8 +wakeup_stack: + .fill 128,1,0 + .globl acpi_wakeup_end +acpi_wakeup_end: + /* end of real mode trampoline */ + + /* pointed to by __KERNEL16_CS:0 */ + .code16 +ENTRY(s3_prot16) + /* Now in 16bit protected mode, still no paging, stack/data segments invalid */ + + /* Prepare everything for 64bit paging, but still keep it turned off */ + movl %cr4,%eax + bts $5,%eax /* set PAE bit */ + movl %eax,%cr4 + + movl %edi,%cr3 /* load kernel page table */ + + movl $0x80000001,%eax + cpuid /* no execute supported ? */ + movl %edx,%esi + + movl $MSR_EFER,%ecx + rdmsr + bts $8,%eax /* long mode */ + bt $20,%esi /* NX supported ? */ + jnc 1f + bt $_EFER_NX,%eax +1: + wrmsr /* set temporary efer - real one is restored a bit later */ + + movl %cr0,%eax + bts $31,%eax /* paging */ + movl %eax,%cr0 + + /* running in identity mapping now */ + + /* go to 64bit code segment */ + ljmpl $__KERNEL_CS,$s3_restore_state-__START_KERNEL_map + + .code64 + .macro SAVEMSR msr,target + movl $\msr,%ecx + rdmsr + shlq $32,%rdx + orq %rax,%rdx + movq %rdx,\target(%rip) + .endm + + .macro RESTMSR msr,src + movl $\msr,%ecx + movq \src(%rip),%rax + movq %rax,%rdx + shrq $32,%rdx + wrmsr + .endm + + .macro SAVECTL reg + movq %\reg,%rax + movq %rax,saved_\reg(%rip) + .endm + + .macro RESTCTL reg + movq saved_\reg(%rip),%rax + movq %rax,%\reg + .endm + + /* Running in identity mapping, long mode */ +s3_restore_state_low: + movq $s3_restore_state,%rax + jmpq *%rax + + /* Running in real kernel mapping now */ +s3_restore_state: + xorl %eax,%eax + movl %eax,%ds + movq saved_rsp(%rip),%rsp + movw saved_ss(%rip),%ss + movw saved_fs(%rip),%fs + movw saved_gs(%rip),%gs + movw saved_es(%rip),%es + movw saved_ds(%rip),%ds + + lidt saved_idt + ltr saved_tr + lldt saved_ldt + /* gdt is already loaded */ + + RESTCTL cr0 + RESTCTL cr4 + /* cr3 is already loaded */ + + RESTMSR MSR_EFER,saved_efer + RESTMSR MSR_LSTAR,saved_lstar + RESTMSR MSR_CSTAR,saved_cstar + RESTMSR MSR_FS_BASE,saved_fs_base + RESTMSR MSR_GS_BASE,saved_gs_base + RESTMSR MSR_KERNEL_GS_BASE,saved_kernel_gs_base + RESTMSR MSR_SYSCALL_MASK,saved_syscall_mask + + fxrstor fpustate(%rip) + + RESTCTL dr0 + RESTCTL dr1 + RESTCTL dr2 + RESTCTL dr3 + RESTCTL dr6 + RESTCTL dr7 + + movq saved_rflags(%rip),%rax + pushq %rax + popfq + + movq saved_rbp(%rip),%rbp + movq saved_rbx(%rip),%rbx + movq saved_r12(%rip),%r12 + movq saved_r13(%rip),%r13 + movq saved_r14(%rip),%r14 + movq saved_r15(%rip),%r15 + ret + +ENTRY(acpi_prepare_wakeup) + sgdt saved_gdt + + /* copy gdt descr and page table to low level wakeup code so that it can + reload them early. */ + movq acpi_wakeup_address(%rip),%rax + movw saved_gdt+8(%rip),%cx + movw %cx,O(pGDT)+8(%rax) + movq saved_gdt(%rip),%rcx + movq %rcx,O(pGDT)(%rax) + + movq %cr3,%rdi + movl %edi,O(wakeup_page_table)(%rax) + ret + + /* Save CPU state. */ + /* Everything saved here needs to be restored above. */ +ENTRY(do_suspend_lowlevel) + testl %edi,%edi + jnz s3_restore_state + + SAVECTL cr0 + SAVECTL cr4 + SAVECTL cr3 + + str saved_tr + sidt saved_idt + sgdt saved_gdt + sldt saved_ldt + + SAVEMSR MSR_EFER,saved_efer + SAVEMSR MSR_LSTAR,saved_lstar + SAVEMSR MSR_CSTAR,saved_cstar + SAVEMSR MSR_FS_BASE,saved_fs_base + SAVEMSR MSR_GS_BASE,saved_gs_base + SAVEMSR MSR_KERNEL_GS_BASE,saved_kernel_gs_base + SAVEMSR MSR_SYSCALL_MASK,saved_syscall_mask + + movw %ds,saved_ds(%rip) + movw %es,saved_es(%rip) + movw %fs,saved_fs(%rip) + movw %gs,saved_gs(%rip) + movw %ss,saved_ss(%rip) + movq %rsp,saved_rsp(%rip) + + pushfq + popq %rax + movq %rax,saved_rflags(%rip) + + SAVECTL dr0 + SAVECTL dr1 + SAVECTL dr2 + SAVECTL dr3 + SAVECTL dr6 + SAVECTL dr7 + + fxsave fpustate(%rip) + + /* finally save callee saved registers */ + movq %rbp,saved_rbp(%rip) + movq %rbx,saved_rbx(%rip) + movq %r12,saved_r12(%rip) + movq %r13,saved_r13(%rip) + movq %r14,saved_r14(%rip) + movq %r15,saved_r15(%rip) + movq $3,%rdi + call acpi_enter_sleep_state + ret /* should not happen */ + + .data + .align 8 +saved_efer: .quad 0 +saved_lstar: .quad 0 +saved_cstar: .quad 0 +saved_cr4: .quad 0 +saved_cr3: .quad 0 +saved_cr0: .quad 0 +saved_rbp: .quad 0 +saved_rbx: .quad 0 +saved_rsp: .quad 0 +saved_r12: .quad 0 +saved_r13: .quad 0 +saved_r14: .quad 0 +saved_r15: .quad 0 +saved_rflags: .quad 0 +saved_gs_base: .quad 0 +saved_fs_base: .quad 0 +saved_kernel_gs_base: .quad 0 +saved_syscall_mask: .quad 0 +saved_dr0: .quad 0 +saved_dr1: .quad 0 +saved_dr2: .quad 0 +saved_dr3: .quad 0 +saved_dr6: .quad 0 +saved_dr7: .quad 0 +saved_ds: .short 0 +saved_fs: .short 0 +saved_gs: .short 0 +saved_es: .short 0 +saved_ss: .short 0 +saved_idt: .short 0 + .quad 0 +saved_ldt: .short 0 +saved_gdt: .short 0 + .quad 0 +saved_tr: .short 0 + + .align 16 +fpustate: .fill 512,1,0 diff -Nru a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile --- a/arch/x86_64/mm/Makefile Fri Feb 14 00:27:29 2003 +++ b/arch/x86_64/mm/Makefile Fri Feb 14 00:27:29 2003 @@ -1,6 +1,8 @@ # -# Makefile for the linux i386-specific parts of the memory manager. +# Makefile for the linux x86_64-specific parts of the memory manager. # obj-y := init.o fault.o ioremap.o extable.o pageattr.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o +obj-$(CONFIG_DISCONTIGMEM) += numa.o +obj-$(CONFIG_K8_NUMA) += k8topology.o diff -Nru a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c --- a/arch/x86_64/mm/fault.c Fri Feb 14 00:27:26 2003 +++ b/arch/x86_64/mm/fault.c Fri Feb 14 00:27:26 2003 @@ -121,7 +121,10 @@ /* get the address */ __asm__("movq %%cr2,%0":"=r" (address)); - if (page_fault_trace) + if (likely(regs->eflags & X86_EFLAGS_IF)) + local_irq_enable(); + + if (unlikely(page_fault_trace)) printk("pagefault rip:%lx rsp:%lx cs:%lu ss:%lu address %lx error %lx\n", regs->rip,regs->rsp,regs->cs,regs->ss,address,error_code); @@ -139,7 +142,7 @@ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (unlikely(in_atomic() || !mm)) goto no_context; again: @@ -148,7 +151,7 @@ vma = find_vma(mm, address); if (!vma) goto bad_area; - if (vma->vm_start <= address) + if (likely(vma->vm_start <= address)) goto good_area; if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; @@ -222,7 +225,8 @@ return; } #endif - printk("%s[%d] segfault at rip:%lx rsp:%lx adr:%lx err:%lx\n", + printk(KERN_INFO + "%s[%d] segfault at rip:%lx rsp:%lx adr:%lx err:%lx\n", tsk->comm, tsk->pid, regs->rip, regs->rsp, address, error_code); diff -Nru a/arch/x86_64/mm/hugetlbpage.c b/arch/x86_64/mm/hugetlbpage.c --- a/arch/x86_64/mm/hugetlbpage.c Fri Feb 14 00:27:28 2003 +++ b/arch/x86_64/mm/hugetlbpage.c Fri Feb 14 00:27:28 2003 @@ -86,6 +86,18 @@ set_pte(page_table, entry); } +/* + * This function checks for proper alignment of input addr and len parameters. + */ +int is_aligned_hugepage_range(unsigned long addr, unsigned long len) +{ + if (len & ~HPAGE_MASK) + return -EINVAL; + if (addr & ~HPAGE_MASK) + return -EINVAL; + return 0; +} + int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma) @@ -150,6 +162,37 @@ return i; } +struct page * +follow_huge_addr(struct mm_struct *mm, + struct vm_area_struct *vma, unsigned long address, int write) +{ + return NULL; +} + +struct vm_area_struct *hugepage_vma(struct mm_struct *mm, unsigned long addr) +{ + return NULL; +} + +int pmd_huge(pmd_t pmd) +{ + return !!(pmd_val(pmd) & _PAGE_PSE); +} + +struct page * +follow_huge_pmd(struct mm_struct *mm, unsigned long address, + pmd_t *pmd, int write) +{ + struct page *page; + + page = pte_page(*(pte_t *)pmd); + if (page) { + page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT); + get_page(page); + } + return page; +} + void free_huge_page(struct page *page) { BUG_ON(page_count(page)); @@ -181,8 +224,6 @@ BUG_ON(start & (HPAGE_SIZE - 1)); BUG_ON(end & (HPAGE_SIZE - 1)); - spin_lock(&htlbpage_lock); - spin_unlock(&htlbpage_lock); for (address = start; address < end; address += HPAGE_SIZE) { pte = huge_pte_offset(mm, address); page = pte_page(*pte); @@ -204,7 +245,6 @@ int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) { struct mm_struct *mm = current->mm; - struct inode = mapping->host; unsigned long addr; int ret = 0; @@ -228,7 +268,6 @@ + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); page = find_get_page(mapping, idx); if (!page) { - loff_t i_size; page = alloc_hugetlb_page(); if (!page) { @@ -241,9 +280,6 @@ free_huge_page(page); goto out; } - i_size = (loff_t)(idx + 1) * HPAGE_SIZE; - if (i_size > inode->i_size) - inode->i_size = i_size; } set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE); } diff -Nru a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c --- a/arch/x86_64/mm/init.c Fri Feb 14 00:27:27 2003 +++ b/arch/x86_64/mm/init.c Fri Feb 14 00:27:27 2003 @@ -3,7 +3,7 @@ * * Copyright (C) 1995 Linus Torvalds * Copyright (C) 2000 Pavel Machek - * Copyright (C) 2002 Andi Kleen + * Copyright (C) 2002,2003 Andi Kleen */ #include @@ -37,8 +37,9 @@ #include #include #include +#include -unsigned long start_pfn, end_pfn; +#define Dprintk(x...) printk(x) struct mmu_gather mmu_gathers[NR_CPUS]; @@ -90,9 +91,11 @@ if (after_bootmem) ptr = (void *) get_zeroed_page(GFP_ATOMIC); else - ptr = alloc_bootmem_low(PAGE_SIZE); - if (!ptr) + ptr = alloc_bootmem_pages(PAGE_SIZE); + if (!ptr || ((unsigned long)ptr & ~PAGE_MASK)) panic("set_pte_phys: cannot allocate page data %s\n", after_bootmem?"after bootmem":""); + + Dprintk("spp_getpage %p\n", ptr); return ptr; } @@ -104,6 +107,8 @@ pmd_t *pmd; pte_t *pte; + Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys); + level4 = pml4_offset_k(vaddr); if (pml4_none(*level4)) { printk("PML4 FIXMAP MISSING, it should be setup in head.S!\n"); @@ -114,7 +119,7 @@ pmd = (pmd_t *) spp_getpage(); set_pgd(pgd, __pgd(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER)); if (pmd != pmd_offset(pgd, 0)) { - printk("PAGETABLE BUG #01!\n"); + printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pgd,0)); return; } } @@ -128,6 +133,7 @@ } } pte = pte_offset_kernel(pmd, vaddr); + /* CHECKME: */ if (pte_val(*pte)) pte_ERROR(*pte); set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); @@ -151,7 +157,8 @@ set_pte_phys(address, phys, prot); } -extern unsigned long start_pfn, end_pfn; +unsigned long __initdata table_start, table_end; + extern pmd_t temp_boot_pmds[]; static struct temp_map { @@ -168,21 +175,21 @@ { struct temp_map *ti; int i; - unsigned long pfn = start_pfn++, paddr; + unsigned long pfn = table_end++, paddr; void *adr; - if (pfn >= end_pfn_map) + if (pfn >= end_pfn) panic("alloc_low_page: ran out of memory"); for (i = 0; temp_mappings[i].allocated; i++) { if (!temp_mappings[i].pmd) panic("alloc_low_page: ran out of temp mappings"); } ti = &temp_mappings[i]; - paddr = (pfn & (~511)) << PAGE_SHIFT; + paddr = (pfn << PAGE_SHIFT) & PMD_MASK; set_pmd(ti->pmd, __pmd(paddr | _KERNPG_TABLE | _PAGE_PSE)); ti->allocated = 1; __flush_tlb(); - adr = ti->address + (pfn & 511)*PAGE_SIZE; + adr = ti->address + ((pfn << PAGE_SHIFT) & ~PMD_MASK); *index = i; *phys = pfn * PAGE_SIZE; return adr; @@ -203,20 +210,26 @@ pgd = pgd + i; for (; i < PTRS_PER_PGD; pgd++, i++) { int map; - unsigned long paddr = i*PGDIR_SIZE, pmd_phys; + unsigned long paddr, pmd_phys; pmd_t *pmd; + paddr = (address & PML4_MASK) + i*PGDIR_SIZE; if (paddr >= end) { for (; i < PTRS_PER_PGD; i++, pgd++) set_pgd(pgd, __pgd(0)); break; } + + if (!e820_mapped(paddr, paddr+PGDIR_SIZE, 0)) { + set_pgd(pgd, __pgd(0)); + continue; + } + pmd = alloc_low_page(&map, &pmd_phys); set_pgd(pgd, __pgd(pmd_phys | _KERNPG_TABLE)); - for (j = 0; j < PTRS_PER_PMD; pmd++, j++) { + for (j = 0; j < PTRS_PER_PMD; pmd++, j++, paddr += PMD_SIZE) { unsigned long pe; - paddr = i*PGDIR_SIZE + j*PMD_SIZE; if (paddr >= end) { for (; j < PTRS_PER_PMD; j++, pmd++) set_pmd(pmd, __pmd(0)); @@ -239,13 +252,37 @@ unsigned long adr; unsigned long end; unsigned long next; + unsigned long pgds, pmds, tables; + + Dprintk("init_memory_mapping\n"); + + end = end_pfn_map << PAGE_SHIFT; + + /* + * Find space for the kernel direct mapping tables. + * Later we should allocate these tables in the local node of the memory + * mapped. Unfortunately this is done currently before the nodes are + * discovered. + */ + + pgds = (end + PGDIR_SIZE - 1) >> PGDIR_SHIFT; + pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; + tables = round_up(pgds*8, PAGE_SIZE) + round_up(pmds * 8, PAGE_SIZE); + + table_start = find_e820_area(0x8000, __pa_symbol(&_text), tables); + if (table_start == -1UL) + panic("Cannot find space for the kernel page tables"); + + table_start >>= PAGE_SHIFT; + table_end = table_start; + + end += __PAGE_OFFSET; /* turn virtual */ - end = PAGE_OFFSET + (end_pfn_map * PAGE_SIZE); for (adr = PAGE_OFFSET; adr < end; adr = next) { int map; unsigned long pgd_phys; pgd_t *pgd = alloc_low_page(&map, &pgd_phys); - next = adr + (512UL * 1024 * 1024 * 1024); + next = adr + PML4_SIZE; if (next > end) next = end; phys_pgd_init(pgd, adr-PAGE_OFFSET, next-PAGE_OFFSET); @@ -254,20 +291,35 @@ } asm volatile("movq %%cr4,%0" : "=r" (mmu_cr4_features)); __flush_tlb_all(); + early_printk("kernel direct mapping tables upto %lx @ %lx-%lx\n", end, + table_start<> 10, reservedpages << (PAGE_SHIFT-10), datasize >> 10, @@ -392,3 +453,16 @@ } } #endif + +void __init reserve_bootmem_generic(unsigned long phys, unsigned len) +{ + /* Should check here against the e820 map to avoid double free */ +#ifdef CONFIG_DISCONTIGMEM + int nid = phys_to_nid(phys); + if (phys < HIGH_MEMORY && nid) + panic("reserve of %lx at node %d", phys, nid); + reserve_bootmem_node(NODE_DATA(nid), phys, len); +#else + reserve_bootmem(phys, len); +#endif +} diff -Nru a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c --- a/arch/x86_64/mm/ioremap.c Fri Feb 14 00:27:30 2003 +++ b/arch/x86_64/mm/ioremap.c Fri Feb 14 00:27:30 2003 @@ -133,14 +133,16 @@ */ if (phys_addr < virt_to_phys(high_memory)) { char *t_addr, *t_end; - struct page *page; t_addr = __va(phys_addr); t_end = t_addr + (size - 1); +#ifndef CONFIG_DISCONTIGMEM + struct page *page; for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++) if(!PageReserved(page)) return NULL; +#endif } /* diff -Nru a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/x86_64/mm/k8topology.c Fri Feb 14 00:27:30 2003 @@ -0,0 +1,141 @@ +/* + * AMD K8 NUMA support. + * Discover the memory map and associated nodes. + * + * Doesn't use the ACPI SRAT table because it has a questionable license. + * Instead the northbridge registers are read directly. + * XXX in 2.5 we could use the generic SRAT code + * + * Copyright 2002,2003 Andi Kleen, SuSE Labs. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int find_northbridge(void) +{ + int num; + + for (num = 0; num < 32; num++) { + u32 header; + + header = read_pci_config(0, num, 0, 0x00); + if (header != (PCI_VENDOR_ID_AMD | (0x1100<<16))) + continue; + + header = read_pci_config(0, num, 1, 0x00); + if (header != (PCI_VENDOR_ID_AMD | (0x1101<<16))) + continue; + return num; + } + + return -1; +} + +int __init k8_scan_nodes(unsigned long start, unsigned long end) +{ + unsigned long prevbase; + struct node nodes[MAXNODE]; + int nodeid, numnodes, maxnode, i, nb; + + nb = find_northbridge(); + if (nb < 0) + return nb; + + printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb); + + numnodes = (read_pci_config(0, nb, 0, 0x60 ) >> 4) & 3; + + memset(&nodes,0,sizeof(nodes)); + prevbase = 0; + maxnode = -1; + for (i = 0; i < MAXNODE; i++) { + unsigned long base,limit; + + base = read_pci_config(0, nb, 1, 0x40 + i*8); + limit = read_pci_config(0, nb, 1, 0x44 + i*8); + + nodeid = limit & 3; + if (!limit) { + printk(KERN_INFO "Skipping node entry %d (base %lx)\n", i, base); + continue; + } + if ((base >> 8) & 3 || (limit >> 8) & 3) { + printk(KERN_ERR "Node %d using interleaving mode %lx/%lx\n", + nodeid, (base>>8)&3, (limit>>8) & 3); + return -1; + } + if (nodeid > maxnode) + maxnode = nodeid; + if ((1UL << nodeid) & nodes_present) { + printk("Node %d already present. Skipping\n", nodeid); + continue; + } + + limit >>= 16; + limit <<= 24; + + if (limit > end_pfn_map << PAGE_SHIFT) + limit = end_pfn_map << PAGE_SHIFT; + if (limit <= base) { + printk(KERN_INFO "Node %d beyond memory map\n", nodeid); + continue; + } + + base >>= 16; + base <<= 24; + + if (base < start) + base = start; + if (limit > end) + limit = end; + if (limit == base) + continue; + if (limit < base) { + printk(KERN_INFO"Node %d bogus settings %lx-%lx. Ignored.\n", + nodeid, base, limit); + continue; + } + + /* Could sort here, but pun for now. Should not happen anyroads. */ + if (prevbase > base) { + printk(KERN_INFO "Node map not sorted %lx,%lx\n", + prevbase,base); + return -1; + } + + printk(KERN_INFO "Node %d MemBase %016lx Limit %016lx\n", + nodeid, base, limit); + + nodes[nodeid].start = base; + nodes[nodeid].end = limit; + + prevbase = base; + } + + if (maxnode <= 0) + return -1; + + memnode_shift = compute_hash_shift(nodes,maxnode,end); + if (memnode_shift < 0) { + printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); + return -1; + } + printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift); + + early_for_all_nodes(i) { + setup_node_bootmem(i, nodes[i].start, nodes[i].end); + } + + return 0; +} + diff -Nru a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/x86_64/mm/numa.c Fri Feb 14 00:27:30 2003 @@ -0,0 +1,207 @@ +/* + * Generic VM initialization for x86-64 NUMA setups. + * Copyright 2002,2003 Andi Kleen, SuSE Labs. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define Dprintk(x...) printk(x) + +struct pglist_data *node_data[MAXNODE]; +bootmem_data_t plat_node_bdata[MAX_NUMNODES]; + +int memnode_shift; +u8 memnodemap[NODEMAPSIZE]; + +static int numa_off __initdata; + +unsigned long nodes_present; +int maxnode; + +static int emunodes __initdata; + +int compute_hash_shift(struct node *nodes, int numnodes, u64 maxmem) +{ + int i; + int shift = 24; + u64 addr; + + /* When in doubt use brute force. */ + while (shift < 48) { + memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); + early_for_all_nodes (i) { + for (addr = nodes[i].start; + addr < nodes[i].end; + addr += (1UL << shift)) { + if (memnodemap[addr >> shift] != 0xff) { + printk("node %d shift %d addr %Lx conflict %d\n", + i, shift, addr, memnodemap[addr>>shift]); + goto next; + } + memnodemap[addr >> shift] = i; + } + } + return shift; + next: + shift++; + } + memset(memnodemap,0,sizeof(*memnodemap) * NODEMAPSIZE); + return -1; +} + +/* Initialize bootmem allocator for a node */ +void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) +{ + unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size, bootmap_start; + unsigned long nodedata_phys; + const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE); + + start = round_up(start, ZONE_ALIGN); + + printk("Bootmem setup node %d %016lx-%016lx\n", nodeid, start, end); + + start_pfn = start >> PAGE_SHIFT; + end_pfn = end >> PAGE_SHIFT; + + nodedata_phys = find_e820_area(start, end, pgdat_size); + if (nodedata_phys == -1L) + panic("Cannot find memory pgdat in node %d\n", nodeid); + + Dprintk("nodedata_phys %lx\n", nodedata_phys); + + node_data[nodeid] = phys_to_virt(nodedata_phys); + memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t)); + NODE_DATA(nodeid)->bdata = &plat_node_bdata[nodeid]; + NODE_DATA(nodeid)->node_start_pfn = start_pfn; + NODE_DATA(nodeid)->node_size = end_pfn - start_pfn; + + /* Find a place for the bootmem map */ + bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); + bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE); + bootmap_start = find_e820_area(bootmap_start, end, bootmap_pages<> PAGE_SHIFT, + start_pfn, end_pfn); + + e820_bootmem_free(NODE_DATA(nodeid), start, end); + + reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); + reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages< maxnode) + maxnode = nodeid; + nodes_present |= (1UL << nodeid); +} + +/* Initialize final allocator for a zone */ +void __init setup_node_zones(int nodeid) +{ + unsigned long start_pfn, end_pfn; + unsigned long zones[MAX_NR_ZONES]; + unsigned long dma_end_pfn; + + memset(zones, 0, sizeof(unsigned long) * MAX_NR_ZONES); + + start_pfn = node_start_pfn(nodeid); + end_pfn = node_end_pfn(nodeid); + + printk("setting up node %d %lx-%lx\n", nodeid, start_pfn, end_pfn); + + /* All nodes > 0 have a zero length zone DMA */ + dma_end_pfn = __pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT; + if (start_pfn < dma_end_pfn) { + zones[ZONE_DMA] = dma_end_pfn - start_pfn; + zones[ZONE_NORMAL] = end_pfn - dma_end_pfn; + } else { + zones[ZONE_NORMAL] = end_pfn - start_pfn; + } + + free_area_init_node(nodeid, NODE_DATA(nodeid), NULL, zones, + start_pfn, NULL); +} + +int fake_node; + +int __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn) +{ +#ifdef CONFIG_K8_NUMA + if (!numa_off && !k8_scan_nodes(start_pfn< 0) { + struct node nodes[MAXNODE]; + unsigned long nodesize = (end_pfn << PAGE_SHIFT) / emunodes; + int i; + if (emunodes > MAXNODE) + emunodes = MAXNODE; + printk(KERN_INFO "Faking %d nodes of size %ld MB\n", emunodes, nodesize>>20); + for (i = 0; i < emunodes; i++) { + unsigned long end = (i+1)*nodesize; + if (i == emunodes-1) + end = end_pfn << PAGE_SHIFT; + nodes[i].start = i * nodesize; + nodes[i].end = end; + setup_node_bootmem(i, nodes[i].start, nodes[i].end); + } + memnode_shift = compute_hash_shift(nodes, emunodes, nodes[i-1].end); + return 0; + } + + printk(KERN_INFO "Faking a node at %016lx-%016lx\n", + start_pfn << PAGE_SHIFT, + end_pfn << PAGE_SHIFT); + /* setup dummy node covering all memory */ + fake_node = 1; + memnode_shift = 63; + memnodemap[0] = 0; + setup_node_bootmem(0, start_pfn< #include #include -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define ACPI_AC_COMPONENT 0x00020000 diff -Nru a/drivers/acpi/acpi_ksyms.c b/drivers/acpi/acpi_ksyms.c --- a/drivers/acpi/acpi_ksyms.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/acpi_ksyms.c Fri Feb 14 00:27:27 2003 @@ -26,7 +26,7 @@ #include #include #include -#include "acpi_bus.h" +#include #ifdef CONFIG_ACPI_INTERPRETER diff -Nru a/drivers/acpi/battery.c b/drivers/acpi/battery.c --- a/drivers/acpi/battery.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/battery.c Fri Feb 14 00:27:29 2003 @@ -28,8 +28,8 @@ #include #include #include -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF diff -Nru a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c --- a/drivers/acpi/blacklist.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/blacklist.c Fri Feb 14 00:27:26 2003 @@ -29,7 +29,7 @@ #include #include #include -#include "acpi_bus.h" +#include enum acpi_blacklist_predicates { diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c --- a/drivers/acpi/bus.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/bus.c Fri Feb 14 00:27:28 2003 @@ -32,8 +32,8 @@ #ifdef CONFIG_X86 #include #endif -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define _COMPONENT ACPI_BUS_COMPONENT diff -Nru a/drivers/acpi/button.c b/drivers/acpi/button.c --- a/drivers/acpi/button.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/button.c Fri Feb 14 00:27:26 2003 @@ -29,8 +29,8 @@ #include #include #include -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define ACPI_BUTTON_COMPONENT 0x00080000 diff -Nru a/drivers/acpi/debug.c b/drivers/acpi/debug.c --- a/drivers/acpi/debug.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/debug.c Fri Feb 14 00:27:29 2003 @@ -5,7 +5,7 @@ #include #include #include -#include "acpi_drivers.h" +#include #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME ("debug") diff -Nru a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c --- a/drivers/acpi/dispatcher/dsfield.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/dispatcher/dsfield.c Fri Feb 14 00:27:27 2003 @@ -23,12 +23,12 @@ */ -#include "acpi.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acparser.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER diff -Nru a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c --- a/drivers/acpi/dispatcher/dsinit.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/dispatcher/dsinit.c Fri Feb 14 00:27:30 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acdispat.h" -#include "acnamesp.h" +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME ("dsinit") diff -Nru a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c --- a/drivers/acpi/dispatcher/dsmethod.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/dispatcher/dsmethod.c Fri Feb 14 00:27:28 2003 @@ -23,12 +23,12 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER diff -Nru a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c --- a/drivers/acpi/dispatcher/dsmthdat.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/dispatcher/dsmthdat.c Fri Feb 14 00:27:27 2003 @@ -23,11 +23,11 @@ */ -#include "acpi.h" -#include "acdispat.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acinterp.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER diff -Nru a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c --- a/drivers/acpi/dispatcher/dsobject.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/dispatcher/dsobject.c Fri Feb 14 00:27:26 2003 @@ -23,12 +23,12 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acnamesp.h" -#include "acinterp.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME ("dsobject") diff -Nru a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c --- a/drivers/acpi/dispatcher/dsopcode.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/dispatcher/dsopcode.c Fri Feb 14 00:27:29 2003 @@ -24,13 +24,13 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acevents.h" +#include +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME ("dsopcode") diff -Nru a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c --- a/drivers/acpi/dispatcher/dsutils.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/dispatcher/dsutils.c Fri Feb 14 00:27:28 2003 @@ -23,13 +23,13 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acdebug.h" +#include +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME ("dsutils") diff -Nru a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c --- a/drivers/acpi/dispatcher/dswexec.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/dispatcher/dswexec.c Fri Feb 14 00:27:30 2003 @@ -24,13 +24,13 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acdebug.h" +#include +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER diff -Nru a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c --- a/drivers/acpi/dispatcher/dswload.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/dispatcher/dswload.c Fri Feb 14 00:27:27 2003 @@ -23,13 +23,13 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acevents.h" +#include +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER diff -Nru a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c --- a/drivers/acpi/dispatcher/dswscope.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/dispatcher/dswscope.c Fri Feb 14 00:27:30 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acdispat.h" +#include +#include #define _COMPONENT ACPI_DISPATCHER diff -Nru a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c --- a/drivers/acpi/dispatcher/dswstate.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/dispatcher/dswstate.c Fri Feb 14 00:27:29 2003 @@ -23,10 +23,10 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "acnamesp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME ("dswstate") diff -Nru a/drivers/acpi/ec.c b/drivers/acpi/ec.c --- a/drivers/acpi/ec.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/ec.c Fri Feb 14 00:27:28 2003 @@ -30,8 +30,8 @@ #include #include #include -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define _COMPONENT ACPI_EC_COMPONENT diff -Nru a/drivers/acpi/event.c b/drivers/acpi/event.c --- a/drivers/acpi/event.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/event.c Fri Feb 14 00:27:26 2003 @@ -10,7 +10,7 @@ #include #include #include -#include "acpi_drivers.h" +#include #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME ("event") diff -Nru a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c --- a/drivers/acpi/events/evevent.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/events/evevent.c Fri Feb 14 00:27:29 2003 @@ -22,8 +22,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "acpi.h" -#include "acevents.h" +#include +#include #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evevent") diff -Nru a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c --- a/drivers/acpi/events/evgpe.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/events/evgpe.c Fri Feb 14 00:27:28 2003 @@ -22,9 +22,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "acpi.h" -#include "acevents.h" -#include "acnamesp.h" +#include +#include +#include #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evgpe") diff -Nru a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c --- a/drivers/acpi/events/evmisc.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/events/evmisc.c Fri Feb 14 00:27:28 2003 @@ -22,10 +22,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "acpi.h" -#include "acevents.h" -#include "acnamesp.h" -#include "acinterp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evmisc") diff -Nru a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c --- a/drivers/acpi/events/evregion.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/events/evregion.c Fri Feb 14 00:27:27 2003 @@ -23,10 +23,10 @@ */ -#include "acpi.h" -#include "acevents.h" -#include "acnamesp.h" -#include "acinterp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evregion") diff -Nru a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c --- a/drivers/acpi/events/evrgnini.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/events/evrgnini.c Fri Feb 14 00:27:27 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acevents.h" -#include "acnamesp.h" +#include +#include +#include #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evrgnini") diff -Nru a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c --- a/drivers/acpi/events/evsci.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/events/evsci.c Fri Feb 14 00:27:29 2003 @@ -23,8 +23,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "acpi.h" -#include "acevents.h" +#include +#include #define _COMPONENT ACPI_EVENTS diff -Nru a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c --- a/drivers/acpi/events/evxface.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/events/evxface.c Fri Feb 14 00:27:28 2003 @@ -23,10 +23,10 @@ */ -#include "acpi.h" -#include "acnamesp.h" -#include "acevents.h" -#include "acinterp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evxface") diff -Nru a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c --- a/drivers/acpi/events/evxfevnt.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/events/evxfevnt.c Fri Feb 14 00:27:27 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acevents.h" +#include +#include #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evxfevnt") diff -Nru a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c --- a/drivers/acpi/events/evxfregn.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/events/evxfregn.c Fri Feb 14 00:27:27 2003 @@ -24,10 +24,10 @@ */ -#include "acpi.h" -#include "acnamesp.h" -#include "acevents.h" -#include "acinterp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evxfregn") diff -Nru a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c --- a/drivers/acpi/executer/exconfig.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/executer/exconfig.c Fri Feb 14 00:27:28 2003 @@ -23,12 +23,12 @@ */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acevents.h" -#include "actables.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c --- a/drivers/acpi/executer/exconvrt.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/executer/exconvrt.c Fri Feb 14 00:27:26 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c --- a/drivers/acpi/executer/excreate.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/executer/excreate.c Fri Feb 14 00:27:30 2003 @@ -23,12 +23,12 @@ */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acevents.h" -#include "actables.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c --- a/drivers/acpi/executer/exdump.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/executer/exdump.c Fri Feb 14 00:27:27 2003 @@ -23,11 +23,11 @@ */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acparser.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME ("exdump") diff -Nru a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c --- a/drivers/acpi/executer/exfield.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/executer/exfield.c Fri Feb 14 00:27:26 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acdispat.h" -#include "acinterp.h" +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c --- a/drivers/acpi/executer/exfldio.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/executer/exfldio.c Fri Feb 14 00:27:27 2003 @@ -23,11 +23,11 @@ */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acevents.h" -#include "acdispat.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c --- a/drivers/acpi/executer/exmisc.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/executer/exmisc.c Fri Feb 14 00:27:29 2003 @@ -24,9 +24,9 @@ */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c --- a/drivers/acpi/executer/exmutex.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/executer/exmutex.c Fri Feb 14 00:27:29 2003 @@ -24,8 +24,8 @@ */ -#include "acpi.h" -#include "acinterp.h" +#include +#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME ("exmutex") diff -Nru a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c --- a/drivers/acpi/executer/exnames.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/executer/exnames.c Fri Feb 14 00:27:27 2003 @@ -24,9 +24,9 @@ */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" +#include +#include +#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME ("exnames") diff -Nru a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c --- a/drivers/acpi/executer/exoparg1.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/executer/exoparg1.c Fri Feb 14 00:27:30 2003 @@ -24,12 +24,12 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c --- a/drivers/acpi/executer/exoparg2.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/executer/exoparg2.c Fri Feb 14 00:27:28 2003 @@ -23,11 +23,11 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "acinterp.h" -#include "acevents.h" -#include "amlcode.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c --- a/drivers/acpi/executer/exoparg3.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/executer/exoparg3.c Fri Feb 14 00:27:26 2003 @@ -24,10 +24,10 @@ */ -#include "acpi.h" -#include "acinterp.h" -#include "acparser.h" -#include "amlcode.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c --- a/drivers/acpi/executer/exoparg6.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/executer/exoparg6.c Fri Feb 14 00:27:29 2003 @@ -24,10 +24,10 @@ */ -#include "acpi.h" -#include "acinterp.h" -#include "acparser.h" -#include "amlcode.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c --- a/drivers/acpi/executer/exprep.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/executer/exprep.c Fri Feb 14 00:27:27 2003 @@ -24,10 +24,10 @@ */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c --- a/drivers/acpi/executer/exregion.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/executer/exregion.c Fri Feb 14 00:27:27 2003 @@ -24,8 +24,8 @@ */ -#include "acpi.h" -#include "acinterp.h" +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c --- a/drivers/acpi/executer/exresnte.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/executer/exresnte.c Fri Feb 14 00:27:27 2003 @@ -24,10 +24,10 @@ */ -#include "acpi.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c --- a/drivers/acpi/executer/exresolv.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/executer/exresolv.c Fri Feb 14 00:27:28 2003 @@ -24,11 +24,11 @@ */ -#include "acpi.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c --- a/drivers/acpi/executer/exresop.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/executer/exresop.c Fri Feb 14 00:27:30 2003 @@ -24,10 +24,10 @@ */ -#include "acpi.h" -#include "amlcode.h" -#include "acparser.h" -#include "acinterp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c --- a/drivers/acpi/executer/exstore.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/executer/exstore.c Fri Feb 14 00:27:28 2003 @@ -24,11 +24,11 @@ */ -#include "acpi.h" -#include "acdispat.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c --- a/drivers/acpi/executer/exstoren.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/executer/exstoren.c Fri Feb 14 00:27:27 2003 @@ -25,8 +25,8 @@ */ -#include "acpi.h" -#include "acinterp.h" +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c --- a/drivers/acpi/executer/exstorob.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/executer/exstorob.c Fri Feb 14 00:27:30 2003 @@ -24,8 +24,8 @@ */ -#include "acpi.h" -#include "acinterp.h" +#include +#include #define _COMPONENT ACPI_EXECUTER diff -Nru a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c --- a/drivers/acpi/executer/exsystem.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/executer/exsystem.c Fri Feb 14 00:27:29 2003 @@ -24,9 +24,9 @@ */ -#include "acpi.h" -#include "acinterp.h" -#include "acevents.h" +#include +#include +#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME ("exsystem") diff -Nru a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c --- a/drivers/acpi/executer/exutils.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/executer/exutils.c Fri Feb 14 00:27:27 2003 @@ -40,10 +40,10 @@ #define DEFINE_AML_GLOBALS -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acevents.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME ("exutils") diff -Nru a/drivers/acpi/fan.c b/drivers/acpi/fan.c --- a/drivers/acpi/fan.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/fan.c Fri Feb 14 00:27:26 2003 @@ -28,8 +28,8 @@ #include #include #include -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define ACPI_FAN_COMPONENT 0x00200000 diff -Nru a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c --- a/drivers/acpi/hardware/hwacpi.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/hardware/hwacpi.c Fri Feb 14 00:27:26 2003 @@ -24,7 +24,7 @@ */ -#include "acpi.h" +#include #define _COMPONENT ACPI_HARDWARE diff -Nru a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c --- a/drivers/acpi/hardware/hwgpe.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/hardware/hwgpe.c Fri Feb 14 00:27:26 2003 @@ -23,8 +23,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "acpi.h" -#include "acevents.h" +#include +#include #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME ("hwgpe") diff -Nru a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c --- a/drivers/acpi/hardware/hwregs.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/hardware/hwregs.c Fri Feb 14 00:27:29 2003 @@ -25,8 +25,8 @@ */ -#include "acpi.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME ("hwregs") diff -Nru a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c --- a/drivers/acpi/hardware/hwsleep.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/hardware/hwsleep.c Fri Feb 14 00:27:27 2003 @@ -23,7 +23,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "acpi.h" +#include #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME ("hwsleep") diff -Nru a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c --- a/drivers/acpi/hardware/hwtimer.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/hardware/hwtimer.c Fri Feb 14 00:27:27 2003 @@ -23,7 +23,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "acpi.h" +#include #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME ("hwtimer") diff -Nru a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c --- a/drivers/acpi/namespace/nsaccess.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/namespace/nsaccess.c Fri Feb 14 00:27:30 2003 @@ -23,10 +23,10 @@ */ -#include "acpi.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acdispat.h" +#include +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c --- a/drivers/acpi/namespace/nsalloc.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/namespace/nsalloc.c Fri Feb 14 00:27:28 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c --- a/drivers/acpi/namespace/nsdump.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/namespace/nsdump.c Fri Feb 14 00:27:30 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acnamesp.h" -#include "acparser.h" +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c --- a/drivers/acpi/namespace/nsdumpdv.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/namespace/nsdumpdv.c Fri Feb 14 00:27:26 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c --- a/drivers/acpi/namespace/nseval.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/namespace/nseval.c Fri Feb 14 00:27:28 2003 @@ -24,10 +24,10 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "acinterp.h" -#include "acnamesp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c --- a/drivers/acpi/namespace/nsinit.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/namespace/nsinit.c Fri Feb 14 00:27:27 2003 @@ -23,10 +23,10 @@ */ -#include "acpi.h" -#include "acnamesp.h" -#include "acdispat.h" -#include "acinterp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME ("nsinit") diff -Nru a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c --- a/drivers/acpi/namespace/nsload.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/namespace/nsload.c Fri Feb 14 00:27:30 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acnamesp.h" -#include "acdispat.h" +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c --- a/drivers/acpi/namespace/nsnames.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/namespace/nsnames.c Fri Feb 14 00:27:30 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c --- a/drivers/acpi/namespace/nsobject.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/namespace/nsobject.c Fri Feb 14 00:27:28 2003 @@ -24,8 +24,8 @@ */ -#include "acpi.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c --- a/drivers/acpi/namespace/nsparse.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/namespace/nsparse.c Fri Feb 14 00:27:27 2003 @@ -23,10 +23,10 @@ */ -#include "acpi.h" -#include "acnamesp.h" -#include "acparser.h" -#include "acdispat.h" +#include +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c --- a/drivers/acpi/namespace/nssearch.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/namespace/nssearch.c Fri Feb 14 00:27:30 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c --- a/drivers/acpi/namespace/nsutils.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/namespace/nsutils.c Fri Feb 14 00:27:28 2003 @@ -24,10 +24,10 @@ */ -#include "acpi.h" -#include "acnamesp.h" -#include "amlcode.h" -#include "actables.h" +#include +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME ("nsutils") diff -Nru a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c --- a/drivers/acpi/namespace/nswalk.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/namespace/nswalk.c Fri Feb 14 00:27:30 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c --- a/drivers/acpi/namespace/nsxfeval.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/namespace/nsxfeval.c Fri Feb 14 00:27:30 2003 @@ -24,8 +24,8 @@ */ -#include "acpi.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c --- a/drivers/acpi/namespace/nsxfname.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/namespace/nsxfname.c Fri Feb 14 00:27:27 2003 @@ -24,8 +24,8 @@ */ -#include "acpi.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c --- a/drivers/acpi/namespace/nsxfobj.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/namespace/nsxfobj.c Fri Feb 14 00:27:26 2003 @@ -24,8 +24,8 @@ */ -#include "acpi.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE diff -Nru a/drivers/acpi/numa.c b/drivers/acpi/numa.c --- a/drivers/acpi/numa.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/numa.c Fri Feb 14 00:27:29 2003 @@ -29,7 +29,7 @@ #include #include #include -#include "acpi_bus.h" +#include extern int __init acpi_table_parse_madt_family (enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler); diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c --- a/drivers/acpi/osl.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/osl.c Fri Feb 14 00:27:29 2003 @@ -37,7 +37,7 @@ #include #include #include -#include "acpi_bus.h" +#include #ifdef CONFIG_ACPI_EFI #include @@ -143,9 +143,9 @@ #ifdef CONFIG_ACPI_EFI addr->pointer_type = ACPI_PHYSICAL_POINTER; if (efi.acpi20) - addr->pointer.physical = (ACPI_PHYSICAL_ADDRESS) virt_to_phys(efi.acpi20); + addr->pointer.physical = (acpi_physical_address) virt_to_phys(efi.acpi20); else if (efi.acpi) - addr->pointer.physical = (ACPI_PHYSICAL_ADDRESS) virt_to_phys(efi.acpi); + addr->pointer.physical = (acpi_physical_address) virt_to_phys(efi.acpi); else { printk(KERN_ERR PREFIX "System description tables not found\n"); return AE_NOT_FOUND; diff -Nru a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c --- a/drivers/acpi/parser/psargs.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/parser/psargs.c Fri Feb 14 00:27:27 2003 @@ -23,10 +23,10 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME ("psargs") diff -Nru a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c --- a/drivers/acpi/parser/psopcode.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/parser/psopcode.c Fri Feb 14 00:27:27 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" +#include +#include +#include #define _COMPONENT ACPI_PARSER diff -Nru a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c --- a/drivers/acpi/parser/psparse.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/parser/psparse.c Fri Feb 14 00:27:27 2003 @@ -32,12 +32,12 @@ * templates in aml_op_info[] */ -#include "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acinterp.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME ("psparse") diff -Nru a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c --- a/drivers/acpi/parser/psscope.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/parser/psscope.c Fri Feb 14 00:27:26 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acparser.h" +#include +#include #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME ("psscope") diff -Nru a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c --- a/drivers/acpi/parser/pstree.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/parser/pstree.c Fri Feb 14 00:27:27 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" +#include +#include +#include #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME ("pstree") diff -Nru a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c --- a/drivers/acpi/parser/psutils.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/parser/psutils.c Fri Feb 14 00:27:28 2003 @@ -23,10 +23,10 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME ("psutils") diff -Nru a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c --- a/drivers/acpi/parser/pswalk.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/parser/pswalk.c Fri Feb 14 00:27:29 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "acdispat.h" +#include +#include +#include #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME ("pswalk") diff -Nru a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c --- a/drivers/acpi/parser/psxface.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/parser/psxface.c Fri Feb 14 00:27:29 2003 @@ -23,11 +23,11 @@ */ -#include "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_PARSER diff -Nru a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c --- a/drivers/acpi/pci_bind.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/pci_bind.c Fri Feb 14 00:27:29 2003 @@ -32,8 +32,8 @@ #include #include #include -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define _COMPONENT ACPI_PCI_COMPONENT @@ -185,7 +185,7 @@ */ data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function)); if (!data->dev) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", data->id.segment, data->id.bus, data->id.device, data->id.function)); diff -Nru a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c --- a/drivers/acpi/pci_irq.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/pci_irq.c Fri Feb 14 00:27:28 2003 @@ -36,8 +36,8 @@ #ifdef CONFIG_X86_IO_APIC #include #endif -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define _COMPONENT ACPI_PCI_COMPONENT diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c --- a/drivers/acpi/pci_link.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/pci_link.c Fri Feb 14 00:27:27 2003 @@ -38,8 +38,8 @@ #include #include -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define _COMPONENT ACPI_PCI_COMPONENT diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c --- a/drivers/acpi/pci_root.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/pci_root.c Fri Feb 14 00:27:27 2003 @@ -32,8 +32,8 @@ #include #include #include -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define _COMPONENT ACPI_PCI_COMPONENT diff -Nru a/drivers/acpi/power.c b/drivers/acpi/power.c --- a/drivers/acpi/power.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/power.c Fri Feb 14 00:27:28 2003 @@ -29,8 +29,8 @@ #include #include #include -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define _COMPONENT ACPI_POWER_COMPONENT diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c --- a/drivers/acpi/processor.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/processor.c Fri Feb 14 00:27:29 2003 @@ -44,9 +44,9 @@ #include #include -#include "acpi_bus.h" -#include "acpi_drivers.h" -#include "processor.h" +#include +#include +#include #define ACPI_PROCESSOR_COMPONENT 0x01000000 diff -Nru a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c --- a/drivers/acpi/resources/rsaddr.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/resources/rsaddr.c Fri Feb 14 00:27:28 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME ("rsaddr") diff -Nru a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c --- a/drivers/acpi/resources/rscalc.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/resources/rscalc.c Fri Feb 14 00:27:28 2003 @@ -23,10 +23,10 @@ */ -#include "acpi.h" -#include "acresrc.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME ("rscalc") diff -Nru a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c --- a/drivers/acpi/resources/rscreate.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/resources/rscreate.c Fri Feb 14 00:27:27 2003 @@ -23,10 +23,10 @@ */ -#include "acpi.h" -#include "acresrc.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME ("rscreate") diff -Nru a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c --- a/drivers/acpi/resources/rsdump.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/resources/rsdump.c Fri Feb 14 00:27:28 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME ("rsdump") diff -Nru a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c --- a/drivers/acpi/resources/rsio.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/resources/rsio.c Fri Feb 14 00:27:26 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME ("rsio") diff -Nru a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c --- a/drivers/acpi/resources/rsirq.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/resources/rsirq.c Fri Feb 14 00:27:30 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME ("rsirq") diff -Nru a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c --- a/drivers/acpi/resources/rslist.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/resources/rslist.c Fri Feb 14 00:27:30 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME ("rslist") diff -Nru a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c --- a/drivers/acpi/resources/rsmemory.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/resources/rsmemory.c Fri Feb 14 00:27:29 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME ("rsmemory") diff -Nru a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c --- a/drivers/acpi/resources/rsmisc.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/resources/rsmisc.c Fri Feb 14 00:27:27 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME ("rsmisc") diff -Nru a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c --- a/drivers/acpi/resources/rsutils.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/resources/rsutils.c Fri Feb 14 00:27:27 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acnamesp.h" -#include "acresrc.h" +#include +#include +#include #define _COMPONENT ACPI_RESOURCES diff -Nru a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c --- a/drivers/acpi/resources/rsxface.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/resources/rsxface.c Fri Feb 14 00:27:29 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME ("rsxface") diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c --- a/drivers/acpi/scan.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/scan.c Fri Feb 14 00:27:28 2003 @@ -5,7 +5,7 @@ #include #include -#include "acpi_drivers.h" +#include #include /* for acpi_ex_eisa_id_to_string() */ @@ -295,15 +295,15 @@ ACPI_FUNCTION_TRACE("acpi_driver_attach"); spin_lock(&acpi_device_lock); - list_for_each_safe(node,next,&acpi_device_list) { - struct acpi_device * dev = container_of(node,struct acpi_device,g_list); + list_for_each_safe(node, next, &acpi_device_list) { + struct acpi_device * dev = container_of(node, struct acpi_device, g_list); if (dev->driver || !dev->status.present) continue; spin_unlock(&acpi_device_lock); - if (!acpi_bus_match(dev,drv)) { - if (!acpi_bus_driver_init(dev,drv)) { + if (!acpi_bus_match(dev, drv)) { + if (!acpi_bus_driver_init(dev, drv)) { atomic_inc(&drv->references); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", drv->name, dev->pnp.bus_id)); diff -Nru a/drivers/acpi/sleep/Makefile b/drivers/acpi/sleep/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/acpi/sleep/Makefile Fri Feb 14 00:27:30 2003 @@ -0,0 +1,5 @@ +obj-y := poweroff.o +obj-$(CONFIG_ACPI_SLEEP) += main.o +obj-$(CONFIG_ACPI_SLEEP_PROC_FS) += proc.o + +EXTRA_CFLAGS += $(ACPI_CFLAGS) diff -Nru a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/acpi/sleep/main.c Fri Feb 14 00:27:26 2003 @@ -0,0 +1,277 @@ +/* + * sleep.c - ACPI sleep support. + * + * Copyright (c) 2000-2003 Patrick Mochel + * + * Portions are + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + */ + +#include +#include +#include +#include +#include +#include +#include "sleep.h" + +#define _COMPONENT ACPI_SYSTEM_COMPONENT +ACPI_MODULE_NAME ("sleep") + +u8 sleep_states[ACPI_S_STATE_COUNT]; + +/** + * acpi_system_restore_state - OS-specific restoration of state + * @state: sleep state we're exiting + * + * Note that if we're coming back from S4, the memory image should have already + * been loaded from the disk and is already in place. (Otherwise how else would we + * be here?). + */ +acpi_status +acpi_system_restore_state ( + u32 state) +{ + /* restore processor state + * We should only be here if we're coming back from STR or STD. + * And, in the case of the latter, the memory image should have already + * been loaded from disk. + */ + if (state > ACPI_STATE_S1) + acpi_restore_state_mem(); + + /* wait for power to come back */ + mdelay(10); + + /* turn all the devices back on */ + device_resume(RESUME_POWER_ON); + + /* enable interrupts once again */ + ACPI_ENABLE_IRQS(); + + /* restore device context */ + device_resume(RESUME_RESTORE_STATE); + + if (dmi_broken & BROKEN_INIT_AFTER_S1) { + printk("Broken toshiba laptop -> kicking interrupts\n"); + init_8259A(0); + } + + return AE_OK; +} + +/** + * acpi_system_save_state - save OS specific state and power down devices + * @state: sleep state we're entering. + * + * This handles saving all context to memory, and possibly disk. + * First, we call to the device driver layer to save device state. + * Once we have that, we save whatevery processor and kernel state we + * need to memory. + * If we're entering S4, we then write the memory image to disk. + * + * Only then is it safe for us to power down devices, since we may need + * the disks and upstream buses to write to. + */ +acpi_status +acpi_system_save_state( + u32 state) +{ + int error = 0; + + /* Send notification to devices that they will be suspended. + * If any device or driver cannot make the transition, either up + * or down, we'll get an error back. + */ + error = device_suspend(state, SUSPEND_NOTIFY); + if (error) + return AE_ERROR; + + if (state < ACPI_STATE_S5) { + + /* Tell devices to stop I/O and actually save their state. + * It is theoretically possible that something could fail, + * so handle that gracefully.. + */ + error = device_suspend(state, SUSPEND_SAVE_STATE); + if (error) { + /* tell devices to restore state if they have + * it saved and to start taking I/O requests. + */ + device_resume(RESUME_RESTORE_STATE); + return error; + } + + /* flush caches */ + ACPI_FLUSH_CPU_CACHE(); + + /* Do arch specific saving of state. */ + if (state > ACPI_STATE_S1) { + error = acpi_save_state_mem(); + + if (!error && (state == ACPI_STATE_S4)) + error = acpi_save_state_disk(); + + if (error) { + device_resume(RESUME_RESTORE_STATE); + return error; + } + } + } + + /* disable interrupts + * Note that acpi_suspend -- our caller -- will do this once we return. + * But, we want it done early, so we don't get any suprises during + * the device suspend sequence. + */ + ACPI_DISABLE_IRQS(); + + /* Unconditionally turn off devices. + * Obvious if we enter a sleep state. + * If entering S5 (soft off), this should put devices in a + * quiescent state. + */ + error = device_suspend(state, SUSPEND_POWER_DOWN); + + /* We're pretty screwed if we got an error from this. + * We try to recover by simply calling our own restore_state + * function; see above for definition. + * + * If it's S5 though, go through with it anyway.. + */ + if (error && state != ACPI_STATE_S5) + acpi_system_restore_state(state); + + return error ? AE_ERROR : AE_OK; +} + + +/**************************************************************************** + * + * FUNCTION: acpi_system_suspend + * + * PARAMETERS: %state: Sleep state to enter. + * + * RETURN: acpi_status, whether or not we successfully entered and + * exited sleep. + * + * DESCRIPTION: Perform OS-specific action to enter sleep state. + * This is the final step in going to sleep, per spec. If we + * know we're coming back (i.e. not entering S5), we save the + * processor flags. [ We'll have to save and restore them anyway, + * so we use the arch-agnostic save_flags and restore_flags + * here.] We then set the place to return to in arch-specific + * globals using arch_set_return_point. Finally, we call the + * ACPI function to write the proper values to I/O ports. + * + ****************************************************************************/ + +acpi_status +acpi_system_suspend( + u32 state) +{ + acpi_status status = AE_ERROR; + unsigned long flags = 0; + + local_irq_save(flags); + + switch (state) + { + case ACPI_STATE_S1: + barrier(); + status = acpi_enter_sleep_state(state); + break; + + case ACPI_STATE_S2: +#ifdef CONFIG_SOFTWARE_SUSPEND + case ACPI_STATE_S3: + do_suspend_lowlevel(0); +#endif + break; + } + local_irq_restore(flags); + + return status; +} + + +/** + * acpi_suspend - OS-agnostic system suspend/resume support (S? states) + * @state: state we're entering + * + */ +acpi_status +acpi_suspend ( + u32 state) +{ + acpi_status status; + + /* get out if state is invalid */ + if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5) + return AE_ERROR; + + freeze_processes(); /* device_suspend needs processes to be stopped */ + + /* do we have a wakeup address for S2 and S3? */ + if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3) { + if (!acpi_wakeup_address) + return AE_ERROR; + acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address); + } + + acpi_enter_sleep_state_prep(state); + + status = acpi_system_save_state(state); + if (!ACPI_SUCCESS(status)) + return status; + + /* disable interrupts and flush caches */ + ACPI_DISABLE_IRQS(); + ACPI_FLUSH_CPU_CACHE(); + + /* perform OS-specific sleep actions */ + status = acpi_system_suspend(state); + + /* Even if we failed to go to sleep, all of the devices are in an suspended + * mode. So, we run these unconditionaly to make sure we have a usable system + * no matter what. + */ + acpi_system_restore_state(state); + acpi_leave_sleep_state(state); + + /* make sure interrupts are enabled */ + ACPI_ENABLE_IRQS(); + + /* reset firmware waking vector */ + acpi_set_firmware_waking_vector((acpi_physical_address) 0); + thaw_processes(); + + return status; +} + +static int __init acpi_sleep_init(void) +{ + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_system_add_fs"); + + if (acpi_disabled) + return_VALUE(0); + + printk(KERN_INFO PREFIX "(supports"); + for (i=0; i +#include +#include + +static void +acpi_power_off (void) +{ + printk("%s called\n",__FUNCTION__); + acpi_enter_sleep_state_prep(ACPI_STATE_S5); + ACPI_DISABLE_IRQS(); + acpi_enter_sleep_state(ACPI_STATE_S5); +} + +static int acpi_poweroff_init(void) +{ + if (!acpi_disabled) { + u8 type_a, type_b; + acpi_status status; + + status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); + if (ACPI_SUCCESS(status)) + pm_power_off = acpi_power_off; + } + return 0; +} + +late_initcall(acpi_poweroff_init); diff -Nru a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/acpi/sleep/proc.c Fri Feb 14 00:27:30 2003 @@ -0,0 +1,397 @@ +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_X86 +#include +#endif + +#include "sleep.h" + +#define ACPI_SYSTEM_FILE_SLEEP "sleep" +#define ACPI_SYSTEM_FILE_ALARM "alarm" + +#define _COMPONENT ACPI_SYSTEM_COMPONENT +ACPI_MODULE_NAME ("sleep") + + +static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) +{ + int i; + + ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show"); + + for (i = 0; i <= ACPI_STATE_S5; i++) { + if (sleep_states[i]) + seq_printf(seq,"S%d ", i); + } + + seq_puts(seq, "\n"); + + return 0; +} + +static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data); +} + +static int +acpi_system_write_sleep ( + struct file *file, + const char *buffer, + size_t count, + loff_t *ppos) +{ + acpi_status status = AE_ERROR; + char state_string[12] = {'\0'}; + u32 state = 0; + + ACPI_FUNCTION_TRACE("acpi_system_write_sleep"); + + if (count > sizeof(state_string) - 1) + goto Done; + + if (copy_from_user(state_string, buffer, count)) + return_VALUE(-EFAULT); + + state_string[count] = '\0'; + + state = simple_strtoul(state_string, NULL, 0); + + if (state < 1 || state > 4) + goto Done; + + if (!sleep_states[state]) + goto Done; + +#ifdef CONFIG_SOFTWARE_SUSPEND + if (state == 4) { + software_suspend(); + goto Done; + } +#endif + status = acpi_suspend(state); + Done: + if (ACPI_FAILURE(status)) + return_VALUE(-EINVAL); + else + return_VALUE(count); +} + +static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) +{ + u32 sec, min, hr; + u32 day, mo, yr; + + ACPI_FUNCTION_TRACE("acpi_system_alarm_seq_show"); + + spin_lock(&rtc_lock); + + sec = CMOS_READ(RTC_SECONDS_ALARM); + min = CMOS_READ(RTC_MINUTES_ALARM); + hr = CMOS_READ(RTC_HOURS_ALARM); + +#if 0 /* If we ever get an FACP with proper values... */ + if (acpi_gbl_FADT->day_alrm) + day = CMOS_READ(acpi_gbl_FADT->day_alrm); + else + day = CMOS_READ(RTC_DAY_OF_MONTH); + if (acpi_gbl_FADT->mon_alrm) + mo = CMOS_READ(acpi_gbl_FADT->mon_alrm); + else + mo = CMOS_READ(RTC_MONTH);; + if (acpi_gbl_FADT->century) + yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR); + else + yr = CMOS_READ(RTC_YEAR); +#else + day = CMOS_READ(RTC_DAY_OF_MONTH); + mo = CMOS_READ(RTC_MONTH); + yr = CMOS_READ(RTC_YEAR); +#endif + + spin_unlock(&rtc_lock); + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hr); + BCD_TO_BIN(day); + BCD_TO_BIN(mo); + BCD_TO_BIN(yr); + +#if 0 + /* we're trusting the FADT (see above)*/ +#else + /* If we're not trusting the FADT, we should at least make it + * right for _this_ century... ehm, what is _this_ century? + * + * TBD: + * ASAP: find piece of code in the kernel, e.g. star tracker driver, + * which we can trust to determine the century correctly. Atom + * watch driver would be nice, too... + * + * if that has not happened, change for first release in 2050: + * if (yr<50) + * yr += 2100; + * else + * yr += 2000; // current line of code + * + * if that has not happened either, please do on 2099/12/31:23:59:59 + * s/2000/2100 + * + */ + yr += 2000; +#endif + + seq_printf(seq,"%4.4u-", yr); + (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); + (day > 31) ? seq_puts(seq, "** ") : seq_printf(seq, "%2.2u ", day); + (hr > 23) ? seq_puts(seq, "**:") : seq_printf(seq, "%2.2u:", hr); + (min > 59) ? seq_puts(seq, "**:") : seq_printf(seq, "%2.2u:", min); + (sec > 59) ? seq_puts(seq, "**\n") : seq_printf(seq, "%2.2u\n", sec); + + return 0; +} + +static int acpi_system_alarm_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_system_alarm_seq_show, PDE(inode)->data); +} + + +static int +get_date_field ( + char **p, + u32 *value) +{ + char *next = NULL; + char *string_end = NULL; + int result = -EINVAL; + + /* + * Try to find delimeter, only to insert null. The end of the + * string won't have one, but is still valid. + */ + next = strpbrk(*p, "- :"); + if (next) + *next++ = '\0'; + + *value = simple_strtoul(*p, &string_end, 10); + + /* Signal success if we got a good digit */ + if (string_end != *p) + result = 0; + + if (next) + *p = next; + + return result; +} + + +static int +acpi_system_write_alarm ( + struct file *file, + const char *buffer, + size_t count, + loff_t *ppos) +{ + int result = 0; + char alarm_string[30] = {'\0'}; + char *p = alarm_string; + u32 sec, min, hr, day, mo, yr; + int adjust = 0; + unsigned char rtc_control = 0; + + ACPI_FUNCTION_TRACE("acpi_system_write_alarm"); + + if (count > sizeof(alarm_string) - 1) + return_VALUE(-EINVAL); + + if (copy_from_user(alarm_string, buffer, count)) + return_VALUE(-EFAULT); + + alarm_string[count] = '\0'; + + /* check for time adjustment */ + if (alarm_string[0] == '+') { + p++; + adjust = 1; + } + + if ((result = get_date_field(&p, &yr))) + goto end; + if ((result = get_date_field(&p, &mo))) + goto end; + if ((result = get_date_field(&p, &day))) + goto end; + if ((result = get_date_field(&p, &hr))) + goto end; + if ((result = get_date_field(&p, &min))) + goto end; + if ((result = get_date_field(&p, &sec))) + goto end; + + if (sec > 59) { + min += 1; + sec -= 60; + } + if (min > 59) { + hr += 1; + min -= 60; + } + if (hr > 23) { + day += 1; + hr -= 24; + } + if (day > 31) { + mo += 1; + day -= 31; + } + if (mo > 12) { + yr += 1; + mo -= 12; + } + + spin_lock_irq(&rtc_lock); + + rtc_control = CMOS_READ(RTC_CONTROL); + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(yr); + BIN_TO_BCD(mo); + BIN_TO_BCD(day); + BIN_TO_BCD(hr); + BIN_TO_BCD(min); + BIN_TO_BCD(sec); + } + + if (adjust) { + yr += CMOS_READ(RTC_YEAR); + mo += CMOS_READ(RTC_MONTH); + day += CMOS_READ(RTC_DAY_OF_MONTH); + hr += CMOS_READ(RTC_HOURS); + min += CMOS_READ(RTC_MINUTES); + sec += CMOS_READ(RTC_SECONDS); + } + + spin_unlock_irq(&rtc_lock); + + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BCD_TO_BIN(yr); + BCD_TO_BIN(mo); + BCD_TO_BIN(day); + BCD_TO_BIN(hr); + BCD_TO_BIN(min); + BCD_TO_BIN(sec); + } + + if (sec > 59) { + min++; + sec -= 60; + } + if (min > 59) { + hr++; + min -= 60; + } + if (hr > 23) { + day++; + hr -= 24; + } + if (day > 31) { + mo++; + day -= 31; + } + if (mo > 12) { + yr++; + mo -= 12; + } + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(yr); + BIN_TO_BCD(mo); + BIN_TO_BCD(day); + BIN_TO_BCD(hr); + BIN_TO_BCD(min); + BIN_TO_BCD(sec); + } + + spin_lock_irq(&rtc_lock); + + /* write the fields the rtc knows about */ + CMOS_WRITE(hr, RTC_HOURS_ALARM); + CMOS_WRITE(min, RTC_MINUTES_ALARM); + CMOS_WRITE(sec, RTC_SECONDS_ALARM); + + /* + * If the system supports an enhanced alarm it will have non-zero + * offsets into the CMOS RAM here -- which for some reason are pointing + * to the RTC area of memory. + */ +#if 0 + if (acpi_gbl_FADT->day_alrm) + CMOS_WRITE(day, acpi_gbl_FADT->day_alrm); + if (acpi_gbl_FADT->mon_alrm) + CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm); + if (acpi_gbl_FADT->century) + CMOS_WRITE(yr/100, acpi_gbl_FADT->century); +#endif + /* enable the rtc alarm interrupt */ + if (!(rtc_control & RTC_AIE)) { + rtc_control |= RTC_AIE; + CMOS_WRITE(rtc_control,RTC_CONTROL); + CMOS_READ(RTC_INTR_FLAGS); + } + + spin_unlock_irq(&rtc_lock); + + acpi_set_register(ACPI_BITREG_RT_CLOCK_ENABLE, 1, ACPI_MTX_LOCK); + + file->f_pos += count; + + result = 0; +end: + return_VALUE(result ? result : count); +} + + +static struct file_operations acpi_system_sleep_fops = { + .open = acpi_system_sleep_open_fs, + .read = seq_read, + .write = acpi_system_write_sleep, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct file_operations acpi_system_alarm_fops = { + .open = acpi_system_alarm_open_fs, + .read = seq_read, + .write = acpi_system_write_alarm, + .llseek = seq_lseek, + .release = single_release, +}; + + +static int acpi_sleep_proc_init(void) +{ + struct proc_dir_entry *entry = NULL; + + /* 'sleep' [R/W]*/ + entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP, + S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir); + if (entry) + entry->proc_fops = &acpi_system_sleep_fops; + + /* 'alarm' [R/W] */ + entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM, + S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir); + if (entry) + entry->proc_fops = &acpi_system_alarm_fops; + return 0; +} + +late_initcall(acpi_sleep_proc_init); diff -Nru a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/acpi/sleep/sleep.h Fri Feb 14 00:27:30 2003 @@ -0,0 +1,5 @@ + +extern u8 sleep_states[]; + +extern acpi_status acpi_suspend (u32 state); + diff -Nru a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c --- a/drivers/acpi/sleep.c Fri Feb 14 00:27:26 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,707 +0,0 @@ -/* - * sleep.c - ACPI sleep support. - * - * Copyright (c) 2000-2002 Patrick Mochel - * - * Portions are - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "acpi_bus.h" -#include "acpi_drivers.h" - -#ifdef CONFIG_X86 -#include -#endif - -#define _COMPONENT ACPI_SYSTEM_COMPONENT -ACPI_MODULE_NAME ("sleep") - -#define ACPI_SYSTEM_FILE_SLEEP "sleep" -#define ACPI_SYSTEM_FILE_ALARM "alarm" - -static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file); -static int acpi_system_alarm_open_fs(struct inode *inode, struct file *file); - -static u8 sleep_states[ACPI_S_STATE_COUNT]; - -static struct file_operations acpi_system_sleep_fops = { - .open = acpi_system_sleep_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static struct file_operations acpi_system_alarm_fops = { - .open = acpi_system_alarm_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void -acpi_power_off (void) -{ - acpi_enter_sleep_state_prep(ACPI_STATE_S5); - ACPI_DISABLE_IRQS(); - acpi_enter_sleep_state(ACPI_STATE_S5); -} - -/** - * acpi_system_restore_state - OS-specific restoration of state - * @state: sleep state we're exiting - * - * Note that if we're coming back from S4, the memory image should have already - * been loaded from the disk and is already in place. (Otherwise how else would we - * be here?). - */ -acpi_status -acpi_system_restore_state ( - u32 state) -{ - /* restore processor state - * We should only be here if we're coming back from STR or STD. - * And, in the case of the latter, the memory image should have already - * been loaded from disk. - */ - if (state > ACPI_STATE_S1) - acpi_restore_state_mem(); - - /* wait for power to come back */ - mdelay(10); - - /* turn all the devices back on */ - device_resume(RESUME_POWER_ON); - - /* enable interrupts once again */ - ACPI_ENABLE_IRQS(); - - /* restore device context */ - device_resume(RESUME_RESTORE_STATE); - - if (dmi_broken & BROKEN_INIT_AFTER_S1) { - printk("Broken toshiba laptop -> kicking interrupts\n"); - init_8259A(0); - } - - return AE_OK; -} - -/** - * acpi_system_save_state - save OS specific state and power down devices - * @state: sleep state we're entering. - * - * This handles saving all context to memory, and possibly disk. - * First, we call to the device driver layer to save device state. - * Once we have that, we save whatevery processor and kernel state we - * need to memory. - * If we're entering S4, we then write the memory image to disk. - * - * Only then is it safe for us to power down devices, since we may need - * the disks and upstream buses to write to. - */ -acpi_status -acpi_system_save_state( - u32 state) -{ - int error = 0; - - /* Send notification to devices that they will be suspended. - * If any device or driver cannot make the transition, either up - * or down, we'll get an error back. - */ - error = device_suspend(state, SUSPEND_NOTIFY); - if (error) - return AE_ERROR; - - if (state < ACPI_STATE_S5) { - - /* Tell devices to stop I/O and actually save their state. - * It is theoretically possible that something could fail, - * so handle that gracefully.. - */ - error = device_suspend(state, SUSPEND_SAVE_STATE); - if (error) { - /* tell devices to restore state if they have - * it saved and to start taking I/O requests. - */ - device_resume(RESUME_RESTORE_STATE); - return error; - } - - /* flush caches */ - ACPI_FLUSH_CPU_CACHE(); - - /* Do arch specific saving of state. */ - if (state > ACPI_STATE_S1) { - error = acpi_save_state_mem(); - - if (!error && (state == ACPI_STATE_S4)) - error = acpi_save_state_disk(); - - if (error) { - device_resume(RESUME_RESTORE_STATE); - return error; - } - } - } - - /* disable interrupts - * Note that acpi_suspend -- our caller -- will do this once we return. - * But, we want it done early, so we don't get any suprises during - * the device suspend sequence. - */ - ACPI_DISABLE_IRQS(); - - /* Unconditionally turn off devices. - * Obvious if we enter a sleep state. - * If entering S5 (soft off), this should put devices in a - * quiescent state. - */ - error = device_suspend(state, SUSPEND_POWER_DOWN); - - /* We're pretty screwed if we got an error from this. - * We try to recover by simply calling our own restore_state - * function; see above for definition. - * - * If it's S5 though, go through with it anyway.. - */ - if (error && state != ACPI_STATE_S5) - acpi_system_restore_state(state); - - return error ? AE_ERROR : AE_OK; -} - - -/**************************************************************************** - * - * FUNCTION: acpi_system_suspend - * - * PARAMETERS: %state: Sleep state to enter. - * - * RETURN: acpi_status, whether or not we successfully entered and - * exited sleep. - * - * DESCRIPTION: Perform OS-specific action to enter sleep state. - * This is the final step in going to sleep, per spec. If we - * know we're coming back (i.e. not entering S5), we save the - * processor flags. [ We'll have to save and restore them anyway, - * so we use the arch-agnostic save_flags and restore_flags - * here.] We then set the place to return to in arch-specific - * globals using arch_set_return_point. Finally, we call the - * ACPI function to write the proper values to I/O ports. - * - ****************************************************************************/ - -acpi_status -acpi_system_suspend( - u32 state) -{ - acpi_status status = AE_ERROR; - unsigned long flags = 0; - - local_irq_save(flags); - - switch (state) - { - case ACPI_STATE_S1: - barrier(); - status = acpi_enter_sleep_state(state); - break; - - case ACPI_STATE_S2: -#ifdef CONFIG_SOFTWARE_SUSPEND - case ACPI_STATE_S3: - do_suspend_lowlevel(0); -#endif - break; - } - local_irq_restore(flags); - - return status; -} - - -/** - * acpi_suspend - OS-agnostic system suspend/resume support (S? states) - * @state: state we're entering - * - */ -acpi_status -acpi_suspend ( - u32 state) -{ - acpi_status status; - - /* get out if state is invalid */ - if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5) - return AE_ERROR; - - freeze_processes(); /* device_suspend needs processes to be stopped */ - - /* do we have a wakeup address for S2 and S3? */ - if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3) { - if (!acpi_wakeup_address) - return AE_ERROR; - acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address); - } - - acpi_enter_sleep_state_prep(state); - - status = acpi_system_save_state(state); - if (!ACPI_SUCCESS(status)) - return status; - - /* disable interrupts and flush caches */ - ACPI_DISABLE_IRQS(); - ACPI_FLUSH_CPU_CACHE(); - - /* perform OS-specific sleep actions */ - status = acpi_system_suspend(state); - - /* Even if we failed to go to sleep, all of the devices are in an suspended - * mode. So, we run these unconditionaly to make sure we have a usable system - * no matter what. - */ - acpi_system_restore_state(state); - acpi_leave_sleep_state(state); - - /* make sure interrupts are enabled */ - ACPI_ENABLE_IRQS(); - - /* reset firmware waking vector */ - acpi_set_firmware_waking_vector((acpi_physical_address) 0); - thaw_processes(); - - return status; -} - -static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) -{ - int i; - - ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show"); - - for (i = 0; i <= ACPI_STATE_S5; i++) { - if (sleep_states[i]) - seq_printf(seq,"S%d ", i); - } - - seq_puts(seq, "\n"); - - return 0; -} - -static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data); -} - -static int -acpi_system_write_sleep ( - struct file *file, - const char *buffer, - size_t count, - loff_t *ppos) -{ - acpi_status status = AE_OK; - char state_string[12] = {'\0'}; - u32 state = 0; - - ACPI_FUNCTION_TRACE("acpi_system_write_sleep"); - - if (count > sizeof(state_string) - 1) - return_VALUE(-EINVAL); - - if (copy_from_user(state_string, buffer, count)) - return_VALUE(-EFAULT); - - state_string[count] = '\0'; - - state = simple_strtoul(state_string, NULL, 0); - - if (!sleep_states[state]) - return_VALUE(-ENODEV); - -#ifdef CONFIG_SOFTWARE_SUSPEND - if (state == 4) { - software_suspend(); - return_VALUE(count); - } -#endif - status = acpi_suspend(state); - - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - return_VALUE(count); -} - -static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) -{ - u32 sec, min, hr; - u32 day, mo, yr; - - ACPI_FUNCTION_TRACE("acpi_system_alarm_seq_show"); - - spin_lock(&rtc_lock); - - sec = CMOS_READ(RTC_SECONDS_ALARM); - min = CMOS_READ(RTC_MINUTES_ALARM); - hr = CMOS_READ(RTC_HOURS_ALARM); - -#if 0 /* If we ever get an FACP with proper values... */ - if (acpi_gbl_FADT->day_alrm) - day = CMOS_READ(acpi_gbl_FADT->day_alrm); - else - day = CMOS_READ(RTC_DAY_OF_MONTH); - if (acpi_gbl_FADT->mon_alrm) - mo = CMOS_READ(acpi_gbl_FADT->mon_alrm); - else - mo = CMOS_READ(RTC_MONTH);; - if (acpi_gbl_FADT->century) - yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR); - else - yr = CMOS_READ(RTC_YEAR); -#else - day = CMOS_READ(RTC_DAY_OF_MONTH); - mo = CMOS_READ(RTC_MONTH); - yr = CMOS_READ(RTC_YEAR); -#endif - - spin_unlock(&rtc_lock); - - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hr); - BCD_TO_BIN(day); - BCD_TO_BIN(mo); - BCD_TO_BIN(yr); - -#if 0 - /* we're trusting the FADT (see above)*/ -#else - /* If we're not trusting the FADT, we should at least make it - * right for _this_ century... ehm, what is _this_ century? - * - * TBD: - * ASAP: find piece of code in the kernel, e.g. star tracker driver, - * which we can trust to determine the century correctly. Atom - * watch driver would be nice, too... - * - * if that has not happened, change for first release in 2050: - * if (yr<50) - * yr += 2100; - * else - * yr += 2000; // current line of code - * - * if that has not happened either, please do on 2099/12/31:23:59:59 - * s/2000/2100 - * - */ - yr += 2000; -#endif - - seq_printf(seq,"%4.4u-", yr); - (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); - (day > 31) ? seq_puts(seq, "** ") : seq_printf(seq, "%2.2u ", day); - (hr > 23) ? seq_puts(seq, "**:") : seq_printf(seq, "%2.2u:", hr); - (min > 59) ? seq_puts(seq, "**:") : seq_printf(seq, "%2.2u:", min); - (sec > 59) ? seq_puts(seq, "**\n") : seq_printf(seq, "%2.2u\n", sec); - - return 0; -} - -static int acpi_system_alarm_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_system_alarm_seq_show, PDE(inode)->data); -} - - -static int -get_date_field ( - char **p, - u32 *value) -{ - char *next = NULL; - char *string_end = NULL; - int result = -EINVAL; - - /* - * Try to find delimeter, only to insert null. The end of the - * string won't have one, but is still valid. - */ - next = strpbrk(*p, "- :"); - if (next) - *next++ = '\0'; - - *value = simple_strtoul(*p, &string_end, 10); - - /* Signal success if we got a good digit */ - if (string_end != *p) - result = 0; - - if (next) - *p = next; - - return result; -} - - -static int -acpi_system_write_alarm ( - struct file *file, - const char *buffer, - size_t count, - loff_t *ppos) -{ - int result = 0; - char alarm_string[30] = {'\0'}; - char *p = alarm_string; - u32 sec, min, hr, day, mo, yr; - int adjust = 0; - unsigned char rtc_control = 0; - - ACPI_FUNCTION_TRACE("acpi_system_write_alarm"); - - if (count > sizeof(alarm_string) - 1) - return_VALUE(-EINVAL); - - if (copy_from_user(alarm_string, buffer, count)) - return_VALUE(-EFAULT); - - alarm_string[count] = '\0'; - - /* check for time adjustment */ - if (alarm_string[0] == '+') { - p++; - adjust = 1; - } - - if ((result = get_date_field(&p, &yr))) - goto end; - if ((result = get_date_field(&p, &mo))) - goto end; - if ((result = get_date_field(&p, &day))) - goto end; - if ((result = get_date_field(&p, &hr))) - goto end; - if ((result = get_date_field(&p, &min))) - goto end; - if ((result = get_date_field(&p, &sec))) - goto end; - - if (sec > 59) { - min += 1; - sec -= 60; - } - if (min > 59) { - hr += 1; - min -= 60; - } - if (hr > 23) { - day += 1; - hr -= 24; - } - if (day > 31) { - mo += 1; - day -= 31; - } - if (mo > 12) { - yr += 1; - mo -= 12; - } - - spin_lock_irq(&rtc_lock); - - rtc_control = CMOS_READ(RTC_CONTROL); - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(yr); - BIN_TO_BCD(mo); - BIN_TO_BCD(day); - BIN_TO_BCD(hr); - BIN_TO_BCD(min); - BIN_TO_BCD(sec); - } - - if (adjust) { - yr += CMOS_READ(RTC_YEAR); - mo += CMOS_READ(RTC_MONTH); - day += CMOS_READ(RTC_DAY_OF_MONTH); - hr += CMOS_READ(RTC_HOURS); - min += CMOS_READ(RTC_MINUTES); - sec += CMOS_READ(RTC_SECONDS); - } - - spin_unlock_irq(&rtc_lock); - - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(yr); - BCD_TO_BIN(mo); - BCD_TO_BIN(day); - BCD_TO_BIN(hr); - BCD_TO_BIN(min); - BCD_TO_BIN(sec); - } - - if (sec > 59) { - min++; - sec -= 60; - } - if (min > 59) { - hr++; - min -= 60; - } - if (hr > 23) { - day++; - hr -= 24; - } - if (day > 31) { - mo++; - day -= 31; - } - if (mo > 12) { - yr++; - mo -= 12; - } - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(yr); - BIN_TO_BCD(mo); - BIN_TO_BCD(day); - BIN_TO_BCD(hr); - BIN_TO_BCD(min); - BIN_TO_BCD(sec); - } - - spin_lock_irq(&rtc_lock); - - /* write the fields the rtc knows about */ - CMOS_WRITE(hr, RTC_HOURS_ALARM); - CMOS_WRITE(min, RTC_MINUTES_ALARM); - CMOS_WRITE(sec, RTC_SECONDS_ALARM); - - /* - * If the system supports an enhanced alarm it will have non-zero - * offsets into the CMOS RAM here -- which for some reason are pointing - * to the RTC area of memory. - */ -#if 0 - if (acpi_gbl_FADT->day_alrm) - CMOS_WRITE(day, acpi_gbl_FADT->day_alrm); - if (acpi_gbl_FADT->mon_alrm) - CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm); - if (acpi_gbl_FADT->century) - CMOS_WRITE(yr/100, acpi_gbl_FADT->century); -#endif - /* enable the rtc alarm interrupt */ - if (!(rtc_control & RTC_AIE)) { - rtc_control |= RTC_AIE; - CMOS_WRITE(rtc_control,RTC_CONTROL); - CMOS_READ(RTC_INTR_FLAGS); - } - - spin_unlock_irq(&rtc_lock); - - acpi_set_register(ACPI_BITREG_RT_CLOCK_ENABLE, 1, ACPI_MTX_LOCK); - - file->f_pos += count; - - result = 0; -end: - return_VALUE(result ? result : count); -} - - -#if defined(CONFIG_MAGIC_SYSRQ) && defined(CONFIG_PM) - -/* Simple wrapper calling power down function. */ -static void acpi_sysrq_power_off(int key, struct pt_regs *pt_regs, - struct tty_struct *tty) -{ - acpi_power_off(); -} - -struct sysrq_key_op sysrq_acpi_poweroff_op = { - .handler = &acpi_sysrq_power_off, - .help_msg = "Off", - .action_msg = "Power Off\n" -}; - -#endif /* CONFIG_MAGIC_SYSRQ */ - -static int __init acpi_sleep_init(void) -{ - struct proc_dir_entry *entry = NULL; - acpi_status status = AE_OK; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_system_add_fs"); - - if (acpi_disabled) - return_VALUE(0); - - printk(KERN_INFO PREFIX "(supports"); - for (i=0; iproc_fops = &acpi_system_sleep_fops; - entry->proc_fops->write = acpi_system_write_sleep; - } - - /* 'alarm' [R/W] */ - entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM, - S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_SYSTEM_FILE_ALARM)); - else { - entry->proc_fops = &acpi_system_alarm_fops; - entry->proc_fops->write = acpi_system_write_alarm; - } - - /* Install the soft-off (S5) handler. */ - if (sleep_states[ACPI_STATE_S5]) { - pm_power_off = acpi_power_off; - register_sysrq_key('o', &sysrq_acpi_poweroff_op); - - /* workaround: some systems don't claim S4 support, but they - do support S5 (power-down). That is all we need, so - indicate support. */ - sleep_states[ACPI_STATE_S4] = 1; - } - - return_VALUE(0); -} - -subsys_initcall(acpi_sleep_init); diff -Nru a/drivers/acpi/system.c b/drivers/acpi/system.c --- a/drivers/acpi/system.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/system.c Fri Feb 14 00:27:28 2003 @@ -27,7 +27,7 @@ #include #include -#include "acpi_drivers.h" +#include #define _COMPONENT ACPI_SYSTEM_COMPONENT diff -Nru a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c --- a/drivers/acpi/tables/tbconvrt.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/tables/tbconvrt.c Fri Feb 14 00:27:28 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_TABLES diff -Nru a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c --- a/drivers/acpi/tables/tbget.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/tables/tbget.c Fri Feb 14 00:27:29 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_TABLES diff -Nru a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c --- a/drivers/acpi/tables/tbgetall.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/tables/tbgetall.c Fri Feb 14 00:27:29 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_TABLES diff -Nru a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c --- a/drivers/acpi/tables/tbinstal.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/tables/tbinstal.c Fri Feb 14 00:27:27 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_TABLES diff -Nru a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c --- a/drivers/acpi/tables/tbrsdt.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/tables/tbrsdt.c Fri Feb 14 00:27:29 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_TABLES diff -Nru a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c --- a/drivers/acpi/tables/tbutils.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/tables/tbutils.c Fri Feb 14 00:27:29 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_TABLES diff -Nru a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c --- a/drivers/acpi/tables/tbxface.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/tables/tbxface.c Fri Feb 14 00:27:30 2003 @@ -24,9 +24,9 @@ */ -#include "acpi.h" -#include "acnamesp.h" -#include "actables.h" +#include +#include +#include #define _COMPONENT ACPI_TABLES diff -Nru a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c --- a/drivers/acpi/tables/tbxfroot.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/tables/tbxfroot.c Fri Feb 14 00:27:29 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_TABLES diff -Nru a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c --- a/drivers/acpi/thermal.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/thermal.c Fri Feb 14 00:27:29 2003 @@ -39,8 +39,8 @@ #include #include #include -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define ACPI_THERMAL_COMPONENT 0x04000000 #define ACPI_THERMAL_CLASS "thermal_zone" @@ -82,8 +82,11 @@ static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); +static int acpi_thermal_write_trip_points (struct file*,const char *,size_t,loff_t *); static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); +static int acpi_thermal_write_cooling_mode (struct file*,const char *,size_t,loff_t *); static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); +static int acpi_thermal_write_polling(struct file*,const char *,size_t,loff_t *); static struct acpi_driver acpi_thermal_driver = { .name = ACPI_THERMAL_DRIVER_NAME, @@ -179,6 +182,7 @@ static struct file_operations acpi_thermal_trip_fops = { .open = acpi_thermal_trip_open_fs, .read = seq_read, + .write = acpi_thermal_write_trip_points, .llseek = seq_lseek, .release = single_release, }; @@ -186,6 +190,7 @@ static struct file_operations acpi_thermal_cooling_fops = { .open = acpi_thermal_cooling_open_fs, .read = seq_read, + .write = acpi_thermal_write_cooling_mode, .llseek = seq_lseek, .release = single_release, }; @@ -193,6 +198,7 @@ static struct file_operations acpi_thermal_polling_fops = { .open = acpi_thermal_polling_open_fs, .read = seq_read, + .write = acpi_thermal_write_polling, .llseek = seq_lseek, .release = single_release, }; @@ -947,10 +953,11 @@ struct file *file, const char *buffer, size_t count, - loff_t *data) + loff_t *ppos) { + struct seq_file *m = (struct seq_file *)file->private_data; + struct acpi_thermal *tz = (struct acpi_thermal *)m->private; int result = 0; - struct acpi_thermal *tz = (struct acpi_thermal *) data; char mode_string[12] = {'\0'}; ACPI_FUNCTION_TRACE("acpi_thermal_write_cooling_mode"); @@ -1007,10 +1014,11 @@ struct file *file, const char *buffer, size_t count, - loff_t *data) + loff_t *ppos) { + struct seq_file *m = (struct seq_file *)file->private_data; + struct acpi_thermal *tz = (struct acpi_thermal *)m->private; int result = 0; - struct acpi_thermal *tz = (struct acpi_thermal *) data; char polling_string[12] = {'\0'}; int seconds = 0; @@ -1084,7 +1092,6 @@ ACPI_THERMAL_FILE_TRIP_POINTS)); else { entry->proc_fops = &acpi_thermal_trip_fops; - entry->proc_fops->write = acpi_thermal_write_trip_points; entry->data = acpi_driver_data(device); } @@ -1097,7 +1104,6 @@ ACPI_THERMAL_FILE_COOLING_MODE)); else { entry->proc_fops = &acpi_thermal_cooling_fops; - entry->proc_fops->write = acpi_thermal_write_cooling_mode; entry->data = acpi_driver_data(device); } @@ -1110,7 +1116,6 @@ ACPI_THERMAL_FILE_POLLING_FREQ)); else { entry->proc_fops = &acpi_thermal_polling_fops; - entry->proc_fops->write = acpi_thermal_write_polling; entry->data = acpi_driver_data(device); } diff -Nru a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c --- a/drivers/acpi/toshiba_acpi.c Fri Feb 14 00:27:26 2003 +++ b/drivers/acpi/toshiba_acpi.c Fri Feb 14 00:27:26 2003 @@ -44,7 +44,7 @@ #include #include -#include +#include #define OLD_ACPI_INTERFACE (ACPI_CA_VERSION < 0x20020000) #if OLD_ACPI_INTERFACE @@ -52,7 +52,7 @@ extern struct proc_dir_entry* bm_proc_root; #define acpi_root_dir bm_proc_root #else -#include "acpi_drivers.h" +#include #endif MODULE_AUTHOR("John Belmonte"); diff -Nru a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c --- a/drivers/acpi/utilities/utalloc.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/utilities/utalloc.c Fri Feb 14 00:27:27 2003 @@ -23,7 +23,7 @@ */ -#include "acpi.h" +#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME ("utalloc") diff -Nru a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c --- a/drivers/acpi/utilities/utcopy.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/utilities/utcopy.c Fri Feb 14 00:27:28 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "amlcode.h" +#include +#include #define _COMPONENT ACPI_UTILITIES diff -Nru a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c --- a/drivers/acpi/utilities/utdebug.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/utilities/utdebug.c Fri Feb 14 00:27:29 2003 @@ -23,7 +23,7 @@ */ -#include "acpi.h" +#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME ("utdebug") diff -Nru a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c --- a/drivers/acpi/utilities/utdelete.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/utilities/utdelete.c Fri Feb 14 00:27:28 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" +#include +#include +#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME ("utdelete") diff -Nru a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c --- a/drivers/acpi/utilities/uteval.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/utilities/uteval.c Fri Feb 14 00:27:27 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acnamesp.h" -#include "acinterp.h" +#include +#include +#include #define _COMPONENT ACPI_UTILITIES diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c --- a/drivers/acpi/utilities/utglobal.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/utilities/utglobal.c Fri Feb 14 00:27:27 2003 @@ -24,8 +24,8 @@ #define DEFINE_ACPI_GLOBALS -#include "acpi.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME ("utglobal") diff -Nru a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c --- a/drivers/acpi/utilities/utinit.c Fri Feb 14 00:27:28 2003 +++ b/drivers/acpi/utilities/utinit.c Fri Feb 14 00:27:28 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acnamesp.h" -#include "acevents.h" +#include +#include +#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME ("utinit") diff -Nru a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c --- a/drivers/acpi/utilities/utmath.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/utilities/utmath.c Fri Feb 14 00:27:30 2003 @@ -23,7 +23,7 @@ */ -#include "acpi.h" +#include #define _COMPONENT ACPI_UTILITIES diff -Nru a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c --- a/drivers/acpi/utilities/utmisc.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/utilities/utmisc.c Fri Feb 14 00:27:27 2003 @@ -23,8 +23,8 @@ */ -#include "acpi.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_UTILITIES diff -Nru a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c --- a/drivers/acpi/utilities/utobject.c Fri Feb 14 00:27:29 2003 +++ b/drivers/acpi/utilities/utobject.c Fri Feb 14 00:27:29 2003 @@ -23,9 +23,9 @@ */ -#include "acpi.h" -#include "acnamesp.h" -#include "amlcode.h" +#include +#include +#include #define _COMPONENT ACPI_UTILITIES diff -Nru a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c --- a/drivers/acpi/utilities/utxface.c Fri Feb 14 00:27:27 2003 +++ b/drivers/acpi/utilities/utxface.c Fri Feb 14 00:27:27 2003 @@ -23,12 +23,12 @@ */ -#include "acpi.h" -#include "acevents.h" -#include "acnamesp.h" -#include "acparser.h" -#include "acdispat.h" -#include "acdebug.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME ("utxface") diff -Nru a/drivers/acpi/utils.c b/drivers/acpi/utils.c --- a/drivers/acpi/utils.c Fri Feb 14 00:27:30 2003 +++ b/drivers/acpi/utils.c Fri Feb 14 00:27:30 2003 @@ -27,8 +27,8 @@ #include #include #include -#include "acpi_bus.h" -#include "acpi_drivers.h" +#include +#include #define _COMPONENT ACPI_BUS_COMPONENT diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c --- a/drivers/block/DAC960.c Fri Feb 14 00:27:29 2003 +++ b/drivers/block/DAC960.c Fri Feb 14 00:27:29 2003 @@ -1731,12 +1731,17 @@ if (!DAC960_V2_NewLogicalDeviceInfo(Controller, LogicalDeviceNumber)) break; LogicalDeviceNumber = NewLogicalDeviceInfo->LogicalDeviceNumber; - if (LogicalDeviceNumber > DAC960_MaxLogicalDrives) - panic("DAC960: Logical Drive Number %d not supported\n", - LogicalDeviceNumber); - if (NewLogicalDeviceInfo->DeviceBlockSizeInBytes != DAC960_BlockSize) - panic("DAC960: Logical Drive Block Size %d not supported\n", - NewLogicalDeviceInfo->DeviceBlockSizeInBytes); + if (LogicalDeviceNumber >= DAC960_MaxLogicalDrives) { + DAC960_Error("DAC960: Logical Drive Number %d not supported\n", + Controller, LogicalDeviceNumber); + break; + } + if (NewLogicalDeviceInfo->DeviceBlockSizeInBytes != DAC960_BlockSize) { + DAC960_Error("DAC960: Logical Drive Block Size %d not supported\n", + Controller, NewLogicalDeviceInfo->DeviceBlockSizeInBytes); + LogicalDeviceNumber++; + continue; + } PhysicalDevice.Controller = 0; PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel; PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID; diff -Nru a/drivers/block/cciss.c b/drivers/block/cciss.c --- a/drivers/block/cciss.c Fri Feb 14 00:27:30 2003 +++ b/drivers/block/cciss.c Fri Feb 14 00:27:30 2003 @@ -345,7 +345,7 @@ printk(KERN_DEBUG "cciss_open %x (%x:%x)\n", inode->i_rdev, ctlr, dsk); #endif /* CCISS_DEBUG */ - if (ctlr > MAX_CTLR || hba[ctlr] == NULL) + if (ctlr >= MAX_CTLR || hba[ctlr] == NULL) return -ENXIO; /* * Root is allowed to open raw volume zero even if its not configured diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c --- a/drivers/block/genhd.c Fri Feb 14 00:27:28 2003 +++ b/drivers/block/genhd.c Fri Feb 14 00:27:28 2003 @@ -74,7 +74,7 @@ down_write(&block_subsys.rwsem); for (s = &probes[index]; *s; s = &(*s)->next) { struct blk_probe *p = *s; - if (p->dev == dev || p->range == range) { + if (p->dev == dev && p->range == range) { *s = p->next; kfree(p); break; @@ -299,7 +299,7 @@ static ssize_t disk_dev_read(struct gendisk * disk, char *page) { dev_t base = MKDEV(disk->major, disk->first_minor); - return sprintf(page, "%04x\n",base); + return sprintf(page, "%04x\n", (unsigned)base); } static ssize_t disk_range_read(struct gendisk * disk, char *page) { diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c --- a/drivers/block/ll_rw_blk.c Fri Feb 14 00:27:27 2003 +++ b/drivers/block/ll_rw_blk.c Fri Feb 14 00:27:27 2003 @@ -28,6 +28,7 @@ #include static void blk_unplug_work(void *data); +static void blk_unplug_timeout(unsigned long data); /* * For the allocated request tables @@ -247,6 +248,9 @@ init_timer(&q->unplug_timer); INIT_WORK(&q->unplug_work, blk_unplug_work, q); + q->unplug_timer.function = blk_unplug_timeout; + q->unplug_timer.data = (unsigned long)q; + /* * by default assume old behaviour and bounce for any highmem page */ @@ -677,7 +681,7 @@ "REQ_SENSE", "REQ_FAILED", "REQ_QUIET", - "REQ_SPECIAL" + "REQ_SPECIAL", "REQ_DRIVE_CMD", "REQ_DRIVE_TASK", "REQ_DRIVE_TASKFILE", @@ -1297,9 +1301,6 @@ blk_queue_make_request(q, __make_request); blk_queue_max_segment_size(q, MAX_SEGMENT_SIZE); - - q->unplug_timer.function = blk_unplug_timeout; - q->unplug_timer.data = (unsigned long)q; blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS); blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS); diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c --- a/drivers/block/loop.c Fri Feb 14 00:27:28 2003 +++ b/drivers/block/loop.c Fri Feb 14 00:27:28 2003 @@ -577,17 +577,11 @@ struct loop_device *lo = data; struct bio *bio; - daemonize(); + daemonize("loop%d", lo->lo_number); - sprintf(current->comm, "loop%d", lo->lo_number); current->flags |= PF_IOTHREAD; /* loop can be used in an encrypted device hence, it mustn't be stopped at all because it could be indirectly used during suspension */ - - spin_lock_irq(¤t->sighand->siglock); - sigfillset(¤t->blocked); - flush_signals(current); - spin_unlock_irq(¤t->sighand->siglock); set_user_nice(current, -20); diff -Nru a/drivers/block/nbd.c b/drivers/block/nbd.c --- a/drivers/block/nbd.c Fri Feb 14 00:27:27 2003 +++ b/drivers/block/nbd.c Fri Feb 14 00:27:27 2003 @@ -149,7 +149,7 @@ spin_lock_irqsave(¤t->sighand->siglock, flags); printk(KERN_WARNING "NBD (pid %d: %s) got signal %d\n", current->pid, current->comm, - dequeue_signal(¤t->blocked, &info)); + dequeue_signal(current, ¤t->blocked, &info)); spin_unlock_irqrestore(¤t->sighand->siglock, flags); result = -EINTR; break; diff -Nru a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig --- a/drivers/char/agp/Kconfig Fri Feb 14 00:27:28 2003 +++ b/drivers/char/agp/Kconfig Fri Feb 14 00:27:28 2003 @@ -61,16 +61,6 @@ You should say Y here if you use XFree86 3.3.6 or 4.x and want to use GLX or DRI. If unsure, say N. -config AGP_VIA_KT400 - tristate "VIA KT400 chipset support" - depends on AGP3 - help - This option gives you AGP support for the GLX component of the - XFree86 4.x on VIA KT400 AGP 3.0 chipsets. - - You should say Y here if you use XFree86 3.3.6 or 4.x and want to - use GLX or DRI. If unsure, say N. - config AGP_AMD tristate "AMD Irongate, 761, and 762 support" depends on AGP @@ -140,6 +130,11 @@ help This option gives you AGP GART support for the HP ZX1 chipset for IA64 processors. + +config AGP_ALPHA_CORE + tristate + depends on AGP && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL) + default AGP # Put AGP 3.0 entries below here. diff -Nru a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile --- a/drivers/char/agp/Makefile Fri Feb 14 00:27:27 2003 +++ b/drivers/char/agp/Makefile Fri Feb 14 00:27:27 2003 @@ -10,7 +10,6 @@ obj-$(CONFIG_AGP_INTEL) += intel-agp.o obj-$(CONFIG_AGP_VIA) += via-agp.o -obj-$(CONFIG_AGP_VIA_KT400) += via-kt400.o obj-$(CONFIG_AGP_AMD) += amd-k7-agp.o obj-$(CONFIG_AGP_SIS) += sis-agp.o obj-$(CONFIG_AGP_ALI) += ali-agp.o @@ -18,6 +17,7 @@ obj-$(CONFIG_AGP_I460) += i460-agp.o obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o obj-$(CONFIG_AGP_AMD_8151) += amd-k8-agp.o +obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o obj-$(CONFIG_AGP_I7x05) += i7x05-agp.o diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h --- a/drivers/char/agp/agp.h Fri Feb 14 00:27:28 2003 +++ b/drivers/char/agp/agp.h Fri Feb 14 00:27:28 2003 @@ -30,7 +30,7 @@ #include /* for flush_agp_cache() */ -extern struct agp_bridge_data agp_bridge; +extern struct agp_bridge_data *agp_bridge; #define PFX "agpgart: " @@ -128,6 +128,7 @@ int num_aperture_sizes; int capndx; int cant_use_aperture; + struct vm_operations_struct *vm_ops; /* Links to driver specific functions */ @@ -165,20 +166,20 @@ #define MB(x) (KB (KB (x))) #define GB(x) (MB (KB (x))) -#define CACHE_FLUSH agp_bridge.cache_flush +#define CACHE_FLUSH agp_bridge->cache_flush #define A_SIZE_8(x) ((struct aper_size_info_8 *) x) #define A_SIZE_16(x) ((struct aper_size_info_16 *) x) #define A_SIZE_32(x) ((struct aper_size_info_32 *) x) #define A_SIZE_LVL2(x) ((struct aper_size_info_lvl2 *) x) #define A_SIZE_FIX(x) ((struct aper_size_info_fixed *) x) -#define A_IDX8() (A_SIZE_8(agp_bridge.aperture_sizes) + i) -#define A_IDX16() (A_SIZE_16(agp_bridge.aperture_sizes) + i) -#define A_IDX32() (A_SIZE_32(agp_bridge.aperture_sizes) + i) -#define A_IDXLVL2() (A_SIZE_LVL2(agp_bridge.aperture_sizes) + i) -#define A_IDXFIX() (A_SIZE_FIX(agp_bridge.aperture_sizes) + i) +#define A_IDX8() (A_SIZE_8(agp_bridge->aperture_sizes) + i) +#define A_IDX16() (A_SIZE_16(agp_bridge->aperture_sizes) + i) +#define A_IDX32() (A_SIZE_32(agp_bridge->aperture_sizes) + i) +#define A_IDXLVL2() (A_SIZE_LVL2(agp_bridge->aperture_sizes) + i) +#define A_IDXFIX() (A_SIZE_FIX(agp_bridge->aperture_sizes) + i) #define MAXKEY (4096 * 32) -#define PGE_EMPTY(p) (!(p) || (p) == (unsigned long) agp_bridge.scratch_page) +#define PGE_EMPTY(p) (!(p) || (p) == (unsigned long) agp_bridge->scratch_page) /* intel register */ #define INTEL_APBASE 0x10 @@ -366,7 +367,7 @@ /* Generic routines. */ void agp_generic_agp_enable(u32 mode); -int agp_generic_agp_3_0_enable(u32 mode); +void agp_generic_agp_3_0_enable(u32 mode); int agp_generic_create_gatt_table(void); int agp_generic_free_gatt_table(void); agp_memory *agp_create_memory(int scratch_pages); diff -Nru a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c --- a/drivers/char/agp/ali-agp.c Fri Feb 14 00:27:29 2003 +++ b/drivers/char/agp/ali-agp.c Fri Feb 14 00:27:29 2003 @@ -17,15 +17,15 @@ u32 temp; struct aper_size_info_32 *values; - pci_read_config_dword(agp_bridge.dev, ALI_ATTBASE, &temp); + pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp); temp &= ~(0xfffffff0); - values = A_SIZE_32(agp_bridge.aperture_sizes); + values = A_SIZE_32(agp_bridge->aperture_sizes); - for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { if (temp == values[i].size_value) { - agp_bridge.previous_size = - agp_bridge.current_size = (void *) (values + i); - agp_bridge.aperture_size_idx = i; + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + i); + agp_bridge->aperture_size_idx = i; return values[i].size; } } @@ -37,9 +37,9 @@ { u32 temp; - pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp); + pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp); // clear tag - pci_write_config_dword(agp_bridge.dev, ALI_TAGCTRL, + pci_write_config_dword(agp_bridge->dev, ALI_TAGCTRL, ((temp & 0xfffffff0) | 0x00000001|0x00000002)); } @@ -48,15 +48,15 @@ struct aper_size_info_32 *previous_size; u32 temp; - previous_size = A_SIZE_32(agp_bridge.previous_size); + previous_size = A_SIZE_32(agp_bridge->previous_size); - pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp); + pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp); // clear tag - pci_write_config_dword(agp_bridge.dev, ALI_TAGCTRL, + pci_write_config_dword(agp_bridge->dev, ALI_TAGCTRL, ((temp & 0xffffff00) | 0x00000001|0x00000002)); - pci_read_config_dword(agp_bridge.dev, ALI_ATTBASE, &temp); - pci_write_config_dword(agp_bridge.dev, ALI_ATTBASE, + pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp); + pci_write_config_dword(agp_bridge->dev, ALI_ATTBASE, ((temp & 0x00000ff0) | previous_size->size_value)); } @@ -65,24 +65,24 @@ u32 temp; struct aper_size_info_32 *current_size; - current_size = A_SIZE_32(agp_bridge.current_size); + current_size = A_SIZE_32(agp_bridge->current_size); /* aperture size and gatt addr */ - pci_read_config_dword(agp_bridge.dev, ALI_ATTBASE, &temp); - temp = (((temp & 0x00000ff0) | (agp_bridge.gatt_bus_addr & 0xfffff000)) + pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp); + temp = (((temp & 0x00000ff0) | (agp_bridge->gatt_bus_addr & 0xfffff000)) | (current_size->size_value & 0xf)); - pci_write_config_dword(agp_bridge.dev, ALI_ATTBASE, temp); + pci_write_config_dword(agp_bridge->dev, ALI_ATTBASE, temp); /* tlb control */ - pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp); - pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL, ((temp & 0xffffff00) | 0x00000010)); + pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp); + pci_write_config_dword(agp_bridge->dev, ALI_TLBCTRL, ((temp & 0xffffff00) | 0x00000010)); /* address to map to */ - pci_read_config_dword(agp_bridge.dev, ALI_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(agp_bridge->dev, ALI_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); #if 0 - if (agp_bridge.type == ALI_M1541) { + if (agp_bridge->type == ALI_M1541) { u32 nlvm_addr = 0; switch (current_size->size_value) { @@ -101,15 +101,15 @@ nlvm_addr--; nlvm_addr&=0xfff00000; - nlvm_addr+= agp_bridge.gart_bus_addr; - nlvm_addr|=(agp_bridge.gart_bus_addr>>12); + nlvm_addr+= agp_bridge->gart_bus_addr; + nlvm_addr|=(agp_bridge->gart_bus_addr>>12); printk(KERN_INFO PFX "nlvm top &base = %8x\n",nlvm_addr); } #endif - pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp); + pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp); temp &= 0xffffff7f; //enable TLB - pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL, temp); + pci_write_config_dword(agp_bridge->dev, ALI_TLBCTRL, temp); return 0; } @@ -118,23 +118,23 @@ { /* Memory type is ignored */ - return addr | agp_bridge.masks[0].mask; + return addr | agp_bridge->masks[0].mask; } static void ali_cache_flush(void) { global_cache_flush(); - if (agp_bridge.type == ALI_M1541) { + if (agp_bridge->type == ALI_M1541) { int i, page_count; u32 temp; - page_count = 1 << A_SIZE_32(agp_bridge.current_size)->page_order; + page_count = 1 << A_SIZE_32(agp_bridge->current_size)->page_order; for (i = 0; i < PAGE_SIZE * page_count; i += PAGE_SIZE) { - pci_read_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL, &temp); - pci_write_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL, + pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); + pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | - (agp_bridge.gatt_bus_addr + i)) | + (agp_bridge->gatt_bus_addr + i)) | ALI_CACHE_FLUSH_EN)); } } @@ -148,9 +148,9 @@ if (adr == 0) return 0; - if (agp_bridge.type == ALI_M1541) { - pci_read_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL, &temp); - pci_write_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL, + if (agp_bridge->type == ALI_M1541) { + pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); + pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | virt_to_phys(adr)) | ALI_CACHE_FLUSH_EN )); @@ -167,9 +167,9 @@ global_cache_flush(); - if (agp_bridge.type == ALI_M1541) { - pci_read_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL, &temp); - pci_write_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL, + if (agp_bridge->type == ALI_M1541) { + pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); + pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN)); @@ -197,30 +197,30 @@ static int __init ali_generic_setup (struct pci_dev *pdev) { - agp_bridge.masks = ali_generic_masks; - agp_bridge.aperture_sizes = (void *) ali_generic_sizes; - agp_bridge.size_type = U32_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = ali_configure; - agp_bridge.fetch_size = ali_fetch_size; - agp_bridge.cleanup = ali_cleanup; - agp_bridge.tlb_flush = ali_tlbflush; - agp_bridge.mask_memory = ali_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = ali_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = ali_alloc_page; - agp_bridge.agp_destroy_page = ali_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = ali_generic_masks; + agp_bridge->aperture_sizes = (void *) ali_generic_sizes; + agp_bridge->size_type = U32_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = ali_configure; + agp_bridge->fetch_size = ali_fetch_size; + agp_bridge->cleanup = ali_cleanup; + agp_bridge->tlb_flush = ali_tlbflush; + agp_bridge->mask_memory = ali_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = ali_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = ali_alloc_page; + agp_bridge->agp_destroy_page = ali_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return 0; } @@ -313,7 +313,7 @@ printk (KERN_INFO PFX "Detected ALi %s chipset\n", devs[j].chipset_name); - agp_bridge.type = devs[j].chipset; + agp_bridge->type = devs[j].chipset; if (devs[j].chipset_setup != NULL) return devs[j].chipset_setup(pdev); @@ -327,7 +327,7 @@ if (agp_try_unsupported) { printk(KERN_WARNING PFX "Trying generic ALi routines" " for device id: %04x\n", pdev->device); - agp_bridge.type = ALI_GENERIC; + agp_bridge->type = ALI_GENERIC; return ali_generic_setup(pdev); } @@ -350,10 +350,10 @@ /* probe for known chipsets */ if (agp_lookup_host_bridge(dev) != -ENODEV) { - agp_bridge.dev = dev; - agp_bridge.capndx = cap_ptr; + agp_bridge->dev = dev; + agp_bridge->capndx = cap_ptr; /* Fill in the mode register */ - pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode); + pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode); ali_agp_driver.dev = dev; agp_register_driver(&ali_agp_driver); return 0; @@ -387,7 +387,7 @@ ret_val = pci_module_init(&agp_ali_pci_driver); if (ret_val) - agp_bridge.type = NOT_SUPPORTED; + agp_bridge->type = NOT_SUPPORTED; return ret_val; } diff -Nru a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/char/agp/alpha-agp.c Fri Feb 14 00:27:30 2003 @@ -0,0 +1,217 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include "../../../arch/alpha/kernel/pci_impl.h" + +#include "agp.h" + +static struct page *alpha_core_agp_vm_nopage(struct vm_area_struct *vma, + unsigned long address, + int write_access) +{ + alpha_agp_info *agp = agp_bridge->dev_private_data; + dma_addr_t dma_addr; + unsigned long pa; + struct page *page; + + dma_addr = address - vma->vm_start + agp->aperture.bus_base; + pa = agp->ops->translate(agp, dma_addr); + + if (pa == (unsigned long)-EINVAL) return NULL; /* no translation */ + + /* + * Get the page, inc the use count, and return it + */ + page = virt_to_page(__va(pa)); + get_page(page); + return page; +} + +static struct aper_size_info_fixed alpha_core_agp_sizes[] = +{ + { 0, 0, 0 }, /* filled in by alpha_core_agp_setup */ +}; + +static struct gatt_mask alpha_core_agp_masks[] = { + { .mask = 0, .type = 0 }, +}; + +struct vm_operations_struct alpha_core_agp_vm_ops = { + .nopage = alpha_core_agp_vm_nopage, +}; + + +static int alpha_core_agp_nop(void) +{ + /* just return success */ + return 0; +} + +static int alpha_core_agp_fetch_size(void) +{ + return alpha_core_agp_sizes[0].size; +} + +static int alpha_core_agp_configure(void) +{ + alpha_agp_info *agp = agp_bridge->dev_private_data; + agp_bridge->gart_bus_addr = agp->aperture.bus_base; + return 0; +} + +static void alpha_core_agp_cleanup(void) +{ + alpha_agp_info *agp = agp_bridge->dev_private_data; + + agp->ops->cleanup(agp); +} + +static void alpha_core_agp_tlbflush(agp_memory *mem) +{ + alpha_agp_info *agp = agp_bridge->dev_private_data; + alpha_mv.mv_pci_tbi(agp->hose, 0, -1); +} + +static unsigned long alpha_core_agp_mask_memory(unsigned long addr, int type) +{ + /* Memory type is ignored */ + return addr | agp_bridge->masks[0].mask; +} + +static void alpha_core_agp_enable(u32 mode) +{ + alpha_agp_info *agp = agp_bridge->dev_private_data; + + agp->mode.lw = agp_collect_device_status(mode, agp->capability.lw); + + agp->mode.bits.enable = 1; + agp->ops->configure(agp); + + agp_device_command(agp->mode.lw, 0); +} + +static int alpha_core_agp_insert_memory(agp_memory *mem, off_t pg_start, + int type) +{ + alpha_agp_info *agp = agp_bridge->dev_private_data; + int num_entries, status; + void *temp; + + temp = agp_bridge->current_size; + num_entries = A_SIZE_FIX(temp)->num_entries; + if ((pg_start + mem->page_count) > num_entries) return -EINVAL; + + status = agp->ops->bind(agp, pg_start, mem); + mb(); + agp_bridge->tlb_flush(mem); + + return status; +} + +static int alpha_core_agp_remove_memory(agp_memory *mem, off_t pg_start, + int type) +{ + alpha_agp_info *agp = agp_bridge->dev_private_data; + int status; + + status = agp->ops->unbind(agp, pg_start, mem); + agp_bridge->tlb_flush(mem); + return status; +} + + +static struct agp_driver alpha_core_agp_driver = { + .owner = THIS_MODULE, +}; + +int __init +alpha_core_agp_setup(void) +{ + alpha_agp_info *agp = alpha_mv.agp_info(); + struct aper_size_info_fixed *aper_size; + + if (!agp) return -ENODEV; + if (agp->ops->setup(agp)) return -ENODEV; + + /* + * Build the aperture size descriptor + */ + aper_size = alpha_core_agp_sizes; + if (!aper_size) return -ENOMEM; + aper_size->size = agp->aperture.size / (1024 * 1024); + aper_size->num_entries = agp->aperture.size / PAGE_SIZE; + aper_size->page_order = ffs(aper_size->num_entries / 1024) - 1; + + /* + * Build a fake pci_dev struct + */ + if (!(agp_bridge->dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL))) { + return -ENOMEM; + } + agp_bridge->dev->vendor = 0xffff; + agp_bridge->dev->device = 0xffff; + agp_bridge->dev->sysdata = agp->hose; + + /* + * Fill in the rest of the agp_bridge struct + */ + agp_bridge->masks = alpha_core_agp_masks; + agp_bridge->aperture_sizes = aper_size; + agp_bridge->current_size = aper_size; /* only one entry */ + agp_bridge->size_type = FIXED_APER_SIZE; + agp_bridge->num_aperture_sizes = 1; + agp_bridge->dev_private_data = agp; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = alpha_core_agp_configure; + agp_bridge->fetch_size = alpha_core_agp_fetch_size; + agp_bridge->cleanup = alpha_core_agp_cleanup; + agp_bridge->tlb_flush = alpha_core_agp_tlbflush; + agp_bridge->mask_memory = alpha_core_agp_mask_memory; + agp_bridge->agp_enable = alpha_core_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = alpha_core_agp_nop; + agp_bridge->free_gatt_table = alpha_core_agp_nop; + agp_bridge->insert_memory = alpha_core_agp_insert_memory; + agp_bridge->remove_memory = alpha_core_agp_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->mode = agp->capability.lw; + agp_bridge->cant_use_aperture = 1; + agp_bridgevm_ops = &alpha_core_agp_vm_ops; + + alpha_core_agp_driver.dev = agp_bridge->dev; + agp_register_driver(&alpha_core_agp_driver); + printk(KERN_INFO "Detected AGP on hose %d\n", agp->hose->index); + return 0; +} + +static int __init agp_alpha_core_init(void) +{ + int ret_val = -ENODEV; + if (alpha_mv.agp_info) { + agp_bridge->type = ALPHA_CORE_AGP; + ret_val = alpha_core_agp_setup(); + } + + return ret_val; +} + +static void __exit agp_alpha_core_cleanup(void) +{ + agp_unregister_driver(&alpha_core_agp_driver); + /* no pci driver for core */ +} + +module_init(agp_alpha_core_init); +module_exit(agp_alpha_core_cleanup); + +MODULE_AUTHOR("Jeff Wiedemeier "); +MODULE_LICENSE("GPL and additional rights"); diff -Nru a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c --- a/drivers/char/agp/amd-k7-agp.c Fri Feb 14 00:27:30 2003 +++ b/drivers/char/agp/amd-k7-agp.c Fri Feb 14 00:27:30 2003 @@ -45,7 +45,7 @@ CACHE_FLUSH(); for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) { - page_map->remapped[i] = agp_bridge.scratch_page; + page_map->remapped[i] = agp_bridge->scratch_page; } return 0; @@ -115,7 +115,7 @@ #define GET_PAGE_DIR_OFF(addr) (addr >> 22) #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \ - GET_PAGE_DIR_OFF(agp_bridge.gart_bus_addr)) + GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr)) #define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12) #define GET_GATT(addr) (amd_irongate_private.gatt_pages[\ GET_PAGE_DIR_IDX(addr)]->remapped) @@ -129,7 +129,7 @@ u32 temp; int i; - value = A_SIZE_LVL2(agp_bridge.current_size); + value = A_SIZE_LVL2(agp_bridge->current_size); retval = amd_create_page_map(&page_dir); if (retval != 0) { return retval; @@ -141,18 +141,18 @@ return retval; } - agp_bridge.gatt_table_real = (u32 *)page_dir.real; - agp_bridge.gatt_table = (u32 *)page_dir.remapped; - agp_bridge.gatt_bus_addr = virt_to_phys(page_dir.real); + agp_bridge->gatt_table_real = (u32 *)page_dir.real; + agp_bridge->gatt_table = (u32 *)page_dir.remapped; + agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); /* Get the address for the gart region. * This is a bus address even on the alpha, b/c its * used to program the agp master not the cpu */ - pci_read_config_dword(agp_bridge.dev, AMD_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AMD_APBASE, &temp); addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); - agp_bridge.gart_bus_addr = addr; + agp_bridge->gart_bus_addr = addr; /* Calculate the agp offset */ for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { @@ -168,8 +168,8 @@ { struct amd_page_map page_dir; - page_dir.real = (unsigned long *)agp_bridge.gatt_table_real; - page_dir.remapped = (unsigned long *)agp_bridge.gatt_table; + page_dir.real = (unsigned long *)agp_bridge->gatt_table_real; + page_dir.remapped = (unsigned long *)agp_bridge->gatt_table; amd_free_gatt_pages(); amd_free_page_map(&page_dir); @@ -182,15 +182,15 @@ u32 temp; struct aper_size_info_lvl2 *values; - pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp); + pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp); temp = (temp & 0x0000000e); - values = A_SIZE_LVL2(agp_bridge.aperture_sizes); - for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + values = A_SIZE_LVL2(agp_bridge->aperture_sizes); + for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { if (temp == values[i].size_value) { - agp_bridge.previous_size = - agp_bridge.current_size = (void *) (values + i); + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + i); - agp_bridge.aperture_size_idx = i; + agp_bridge->aperture_size_idx = i; return values[i].size; } } @@ -204,22 +204,22 @@ u32 temp; u16 enable_reg; - current_size = A_SIZE_LVL2(agp_bridge.current_size); + current_size = A_SIZE_LVL2(agp_bridge->current_size); /* Get the memory mapped registers */ - pci_read_config_dword(agp_bridge.dev, AMD_MMBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp); temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); amd_irongate_private.registers = (volatile u8 *) ioremap(temp, 4096); /* Write out the address of the gatt table */ OUTREG32(amd_irongate_private.registers, AMD_ATTBASE, - agp_bridge.gatt_bus_addr); + agp_bridge->gatt_bus_addr); /* Write the Sync register */ - pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL, 0x80); + pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL, 0x80); /* Set indexing mode */ - pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL2, 0x00); + pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL2, 0x00); /* Write the enable register */ enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE); @@ -227,10 +227,10 @@ OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg); /* Write out the size register */ - pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp); + pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp); temp = (((temp & ~(0x0000000e)) | current_size->size_value) | 0x00000001); - pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp); + pci_write_config_dword(agp_bridge->dev, AMD_APSIZE, temp); /* Flush the tlb */ OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001); @@ -244,16 +244,16 @@ u32 temp; u16 enable_reg; - previous_size = A_SIZE_LVL2(agp_bridge.previous_size); + previous_size = A_SIZE_LVL2(agp_bridge->previous_size); enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE); enable_reg = (enable_reg & ~(0x0004)); OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg); /* Write back the previous size and disable gart translation */ - pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp); + pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp); temp = ((temp & ~(0x0000000f)) | previous_size->size_value); - pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp); + pci_write_config_dword(agp_bridge->dev, AMD_APSIZE, temp); iounmap((void *) amd_irongate_private.registers); } @@ -274,7 +274,7 @@ { /* Only type 0 is supported by the irongate */ - return addr | agp_bridge.masks[0].mask; + return addr | agp_bridge->masks[0].mask; } static int amd_insert_memory(agp_memory * mem, @@ -284,7 +284,7 @@ unsigned long *cur_gatt; unsigned long addr; - num_entries = A_SIZE_LVL2(agp_bridge.current_size)->num_entries; + num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries; if (type != 0 || mem->type != 0) { return -EINVAL; @@ -295,7 +295,7 @@ j = pg_start; while (j < (pg_start + mem->page_count)) { - addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr; + addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; cur_gatt = GET_GATT(addr); if (!PGE_EMPTY(cur_gatt[GET_GATT_OFF(addr)])) { return -EBUSY; @@ -309,12 +309,12 @@ } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { - addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr; + addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; cur_gatt = GET_GATT(addr); cur_gatt[GET_GATT_OFF(addr)] = - agp_bridge.mask_memory(mem->memory[i], mem->type); + agp_bridge->mask_memory(mem->memory[i], mem->type); } - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return 0; } @@ -329,13 +329,13 @@ return -EINVAL; } for (i = pg_start; i < (mem->page_count + pg_start); i++) { - addr = (i * PAGE_SIZE) + agp_bridge.gart_bus_addr; + addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; cur_gatt = GET_GATT(addr); cur_gatt[GET_GATT_OFF(addr)] = - (unsigned long) agp_bridge.scratch_page; + (unsigned long) agp_bridge->scratch_page; } - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return 0; } @@ -357,30 +357,30 @@ static int __init amd_irongate_setup (struct pci_dev *pdev) { - agp_bridge.masks = amd_irongate_masks; - agp_bridge.aperture_sizes = (void *) amd_irongate_sizes; - agp_bridge.size_type = LVL2_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = (void *) &amd_irongate_private; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = amd_irongate_configure; - agp_bridge.fetch_size = amd_irongate_fetch_size; - agp_bridge.cleanup = amd_irongate_cleanup; - agp_bridge.tlb_flush = amd_irongate_tlbflush; - agp_bridge.mask_memory = amd_irongate_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = amd_create_gatt_table; - agp_bridge.free_gatt_table = amd_free_gatt_table; - agp_bridge.insert_memory = amd_insert_memory; - agp_bridge.remove_memory = amd_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = amd_irongate_masks; + agp_bridge->aperture_sizes = (void *) amd_irongate_sizes; + agp_bridge->size_type = LVL2_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = (void *) &amd_irongate_private; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = amd_irongate_configure; + agp_bridge->fetch_size = amd_irongate_fetch_size; + agp_bridge->cleanup = amd_irongate_cleanup; + agp_bridge->tlb_flush = amd_irongate_tlbflush; + agp_bridge->mask_memory = amd_irongate_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = amd_create_gatt_table; + agp_bridge->free_gatt_table = amd_free_gatt_table; + agp_bridge->insert_memory = amd_insert_memory; + agp_bridge->remove_memory = amd_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return 0; } @@ -416,7 +416,7 @@ while (devs[j].chipset_name != NULL) { if (pdev->device == devs[j].device_id) { printk (KERN_INFO PFX "Detected AMD %s chipset\n", devs[j].chipset_name); - agp_bridge.type = devs[j].chipset; + agp_bridge->type = devs[j].chipset; if (devs[j].chipset_setup != NULL) return devs[j].chipset_setup(pdev); @@ -430,7 +430,7 @@ if (agp_try_unsupported) { printk(KERN_WARNING PFX "Trying generic AMD routines" " for device id: %04x\n", pdev->device); - agp_bridge.type = AMD_GENERIC; + agp_bridge->type = AMD_GENERIC; return amd_irongate_setup(pdev); } @@ -455,10 +455,10 @@ return -ENODEV; if (agp_lookup_host_bridge(dev) != -ENODEV) { - agp_bridge.dev = dev; - agp_bridge.capndx = cap_ptr; + agp_bridge->dev = dev; + agp_bridge->capndx = cap_ptr; /* Fill in the mode register */ - pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode); + pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode); amd_k7_agp_driver.dev = dev; agp_register_driver(&amd_k7_agp_driver); return 0; @@ -492,7 +492,7 @@ ret_val = pci_module_init(&agp_amdk7_pci_driver); if (ret_val) - agp_bridge.type = NOT_SUPPORTED; + agp_bridge->type = NOT_SUPPORTED; return ret_val; } diff -Nru a/drivers/char/agp/amd-k8-agp.c b/drivers/char/agp/amd-k8-agp.c --- a/drivers/char/agp/amd-k8-agp.c Fri Feb 14 00:27:29 2003 +++ b/drivers/char/agp/amd-k8-agp.c Fri Feb 14 00:27:29 2003 @@ -20,34 +20,14 @@ #include #include "agp.h" -static u_int64_t pci_read64 (struct pci_dev *dev, int reg) -{ - union { - u64 full; - struct { - u32 high; - u32 low; - } split; - } tmp; - pci_read_config_dword(dev, reg, &tmp.split.high); - pci_read_config_dword(dev, reg+4, &tmp.split.low); - return tmp.full; -} - -static void pci_write64 (struct pci_dev *dev, int reg, u64 value) -{ - union { - u64 full; - struct { - u32 high; - u32 low; - } split; - } tmp; - tmp.full = value; - pci_write_config_dword(dev, reg, tmp.split.high); - pci_write_config_dword(dev, reg+4, tmp.split.low); -} +/* Will need to be increased if hammer ever goes >8-way. */ +#define MAX_HAMMER_GARTS 8 + +static int nr_garts; +static struct pci_dev * hammers[MAX_HAMMER_GARTS]; +static int gart_iterator; +#define for_each_nb() for(gart_iterator=0;gart_iteratorpage_count)) { - if (!PGE_EMPTY(agp_bridge.gatt_table[j])) + if (!PGE_EMPTY(agp_bridge->gatt_table[j])) return -EBUSY; j++; } @@ -81,7 +61,7 @@ } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { - addr = agp_bridge.mask_memory(mem->memory[i], mem->type); + addr = agp_bridge->mask_memory(mem->memory[i], mem->type); tmp = addr; BUG_ON(tmp & 0xffffff0000000ffc); @@ -89,9 +69,9 @@ pte |=(tmp & 0x00000000fffff000); pte |= 1<<1|1<<0; - agp_bridge.gatt_table[j] = pte; + agp_bridge->gatt_table[j] = pte; } - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return 0; } @@ -125,27 +105,23 @@ u32 temp; struct aper_size_info_32 *values; - pci_for_each_dev(dev) { - if (dev->bus->number==0 && - PCI_FUNC(dev->devfn)==3 && - PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) { - - pci_read_config_dword(dev, AMD_X86_64_GARTAPERTURECTL, &temp); - temp = (temp & 0xe); - values = A_SIZE_32(x86_64_aperture_sizes); - - for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { - if (temp == values[i].size_value) { - agp_bridge.previous_size = - agp_bridge.current_size = (void *) (values + i); - - agp_bridge.aperture_size_idx = i; - return values[i].size; - } - } + dev = hammers[0]; + if (dev==NULL) + return 0; + + pci_read_config_dword(dev, AMD_X86_64_GARTAPERTURECTL, &temp); + temp = (temp & 0xe); + values = A_SIZE_32(x86_64_aperture_sizes); + + for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { + if (temp == values[i].size_value) { + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + i); + + agp_bridge->aperture_size_idx = i; + return values[i].size; } } - /* erk, couldn't find an x86-64 ? */ return 0; } @@ -162,13 +138,8 @@ static void amd_x86_64_tlbflush(agp_memory * temp) { - struct pci_dev *dev; - - pci_for_each_dev(dev) { - if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 && - PCI_SLOT(dev->devfn) >=24 && PCI_SLOT(dev->devfn) <=31) { - flush_x86_64_tlb (dev); - } + for_each_nb() { + flush_x86_64_tlb (hammers[gart_iterator]); } } @@ -221,101 +192,33 @@ static int amd_8151_configure(void) { - struct pci_dev *dev, *hammer=NULL; - int current_size; - int tmp, tmp2, i; - u64 aperbar; - unsigned long gatt_bus = virt_to_phys(agp_bridge.gatt_table_real); + unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real); /* Configure AGP regs in each x86-64 host bridge. */ - pci_for_each_dev(dev) { - if (dev->bus->number==0 && - PCI_FUNC(dev->devfn)==3 && - PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) { - agp_bridge.gart_bus_addr = amd_x86_64_configure(dev,gatt_bus); - hammer = dev; - - /* - * TODO: Cache pci_dev's of x86-64's in private struct to save us - * having to scan the pci list each time. - */ - } - } - - if (hammer == NULL) { - return -ENODEV; - } - - /* Shadow x86-64 registers into 8151 registers. */ - - dev = agp_bridge.dev; - if (!dev) - return -ENODEV; - - current_size = amd_x86_64_fetch_size(); - - pci_read_config_dword(dev, AMD_8151_APERTURESIZE, &tmp); - tmp &= ~(0xfff); - - /* translate x86-64 size bits to 8151 size bits*/ - for (i=0 ; i<7; i++) { - if (amd_8151_sizes[i].size == current_size) - tmp |= (amd_8151_sizes[i].size_value) << 3; + for_each_nb() { + agp_bridge->gart_bus_addr = + amd_x86_64_configure(hammers[gart_iterator],gatt_bus); } - pci_write_config_dword(dev, AMD_8151_APERTURESIZE, tmp); - - pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &tmp); - aperbar = pci_read64 (dev, AMD_8151_VMAPERTURE); - aperbar |= (tmp & 0x7fff) <<25; - aperbar &= 0x000000ffffffffff; - aperbar |= 1<<2; /* This address is a 64bit ptr FIXME: Make conditional in 32bit mode */ - pci_write64 (dev, AMD_8151_VMAPERTURE, aperbar); - - pci_read_config_dword(dev, AMD_8151_AGP_CTL , &tmp); - tmp &= ~(AMD_8151_GTLBEN | AMD_8151_APEREN); - - pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp2); - if (tmp2 & AMD_X86_64_GARTEN) - tmp |= AMD_8151_APEREN; - // FIXME: bit 7 of AMD_8151_AGP_CTL (GTLBEN) must be copied if set. - // But where is it set ? - pci_write_config_dword(dev, AMD_8151_AGP_CTL, tmp); - return 0; } static void amd_8151_cleanup(void) { - struct pci_dev *dev; u32 tmp; - pci_for_each_dev(dev) { + for_each_nb() { /* disable gart translation */ - if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 && - (PCI_SLOT(dev->devfn) >=24) && (PCI_SLOT(dev->devfn) <=31)) { - - pci_read_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, &tmp); - tmp &= ~(AMD_X86_64_GARTEN); - pci_write_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, tmp); - } - - /* Now shadow the disable in the 8151 */ - if (dev->vendor == PCI_VENDOR_ID_AMD && - dev->device == PCI_DEVICE_ID_AMD_8151_0) { - - pci_read_config_dword (dev, AMD_8151_AGP_CTL, &tmp); - tmp &= ~(AMD_8151_APEREN); - pci_write_config_dword (dev, AMD_8151_AGP_CTL, tmp); - } + pci_read_config_dword (hammers[gart_iterator], AMD_X86_64_GARTAPERTURECTL, &tmp); + tmp &= ~(AMD_X86_64_GARTEN); + pci_write_config_dword (hammers[gart_iterator], AMD_X86_64_GARTAPERTURECTL, tmp); } } - static unsigned long amd_8151_mask_memory(unsigned long addr, int type) { - return addr | agp_bridge.masks[0].mask; + return addr | agp_bridge->masks[0].mask; } @@ -368,12 +271,12 @@ } - pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &command); + pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &command); command = agp_collect_device_status(mode, command); command |= 0x100; - pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_COMMAND, command); + pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_COMMAND, command); agp_device_command(command, 1); } @@ -381,30 +284,47 @@ static int __init amd_8151_setup (struct pci_dev *pdev) { - agp_bridge.masks = amd_8151_masks; - agp_bridge.aperture_sizes = (void *) amd_8151_sizes; - agp_bridge.size_type = U32_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = amd_8151_configure; - agp_bridge.fetch_size = amd_x86_64_fetch_size; - agp_bridge.cleanup = amd_8151_cleanup; - agp_bridge.tlb_flush = amd_x86_64_tlbflush; - agp_bridge.mask_memory = amd_8151_mask_memory; - agp_bridge.agp_enable = agp_x86_64_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = x86_64_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + struct pci_dev *dev; + int i=0; + + agp_bridge->masks = amd_8151_masks; + agp_bridge->aperture_sizes = (void *) amd_8151_sizes; + agp_bridge->size_type = U32_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = amd_8151_configure; + agp_bridge->fetch_size = amd_x86_64_fetch_size; + agp_bridge->cleanup = amd_8151_cleanup; + agp_bridge->tlb_flush = amd_x86_64_tlbflush; + agp_bridge->mask_memory = amd_8151_mask_memory; + agp_bridge->agp_enable = agp_x86_64_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = x86_64_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; + + + /* cache pci_devs of northbridges. */ + pci_for_each_dev(dev) { + if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 && + (PCI_SLOT(dev->devfn) >=24) && (PCI_SLOT(dev->devfn) <=31)) { + + hammers[i++] = dev; + nr_garts = i; + if (i==MAX_HAMMER_GARTS) + return 0; + } + } + return 0; } @@ -420,11 +340,11 @@ if (cap_ptr == 0) return -ENODEV; - agp_bridge.dev = dev; - agp_bridge.capndx = cap_ptr; + agp_bridge->dev = dev; + agp_bridge->capndx = cap_ptr; /* Fill in the mode register */ - pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode); + pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode); amd_8151_setup(dev); amd_k8_agp_driver.dev = dev; agp_register_driver(&amd_k8_agp_driver); @@ -458,9 +378,9 @@ ret_val = pci_module_init(&agp_amdk8_pci_driver); if (ret_val) - agp_bridge.type = NOT_SUPPORTED; + agp_bridge->type = NOT_SUPPORTED; - agp_bridge.type = AMD_8151; + agp_bridge->type = AMD_8151; return ret_val; } diff -Nru a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c --- a/drivers/char/agp/backend.c Fri Feb 14 00:27:29 2003 +++ b/drivers/char/agp/backend.c Fri Feb 14 00:27:29 2003 @@ -44,26 +44,27 @@ #define AGPGART_VERSION_MAJOR 0 #define AGPGART_VERSION_MINOR 100 -struct agp_bridge_data agp_bridge = { .type = NOT_SUPPORTED }; +struct agp_bridge_data agp_bridge_dummy = { .type = NOT_SUPPORTED }; +struct agp_bridge_data *agp_bridge = &agp_bridge_dummy; int agp_backend_acquire(void) { - if (agp_bridge.type == NOT_SUPPORTED) + if (agp_bridge->type == NOT_SUPPORTED) return -EINVAL; - if (atomic_read(&agp_bridge.agp_in_use) != 0) + if (atomic_read(&agp_bridge->agp_in_use) != 0) return -EBUSY; - atomic_inc(&agp_bridge.agp_in_use); + atomic_inc(&agp_bridge->agp_in_use); return 0; } void agp_backend_release(void) { - if (agp_bridge.type == NOT_SUPPORTED) + if (agp_bridge->type == NOT_SUPPORTED) return; - atomic_dec(&agp_bridge.agp_in_use); + atomic_dec(&agp_bridge->agp_in_use); } struct agp_max_table { @@ -114,38 +115,38 @@ { int size_value, rc, got_gatt=0, got_keylist=0; - agp_bridge.max_memory_agp = agp_find_max(); - agp_bridge.version = &agp_current_version; + agp_bridge->max_memory_agp = agp_find_max(); + agp_bridge->version = &agp_current_version; - if (agp_bridge.needs_scratch_page == TRUE) { + if (agp_bridge->needs_scratch_page == TRUE) { void *addr; - addr = agp_bridge.agp_alloc_page(); + addr = agp_bridge->agp_alloc_page(); if (addr == NULL) { printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); return -ENOMEM; } - agp_bridge.scratch_page_real = virt_to_phys(addr); - agp_bridge.scratch_page = - agp_bridge.mask_memory(agp_bridge.scratch_page_real, 0); + agp_bridge->scratch_page_real = virt_to_phys(addr); + agp_bridge->scratch_page = + agp_bridge->mask_memory(agp_bridge->scratch_page_real, 0); } - size_value = agp_bridge.fetch_size(); + size_value = agp_bridge->fetch_size(); if (size_value == 0) { printk(KERN_ERR PFX "unable to determine aperture size.\n"); rc = -EINVAL; goto err_out; } - if (agp_bridge.create_gatt_table()) { + if (agp_bridge->create_gatt_table()) { printk(KERN_ERR PFX "unable to get memory for graphics translation table.\n"); rc = -ENOMEM; goto err_out; } got_gatt = 1; - agp_bridge.key_list = vmalloc(PAGE_SIZE * 4); - if (agp_bridge.key_list == NULL) { + agp_bridge->key_list = vmalloc(PAGE_SIZE * 4); + if (agp_bridge->key_list == NULL) { printk(KERN_ERR PFX "error allocating memory for key lists.\n"); rc = -ENOMEM; goto err_out; @@ -153,27 +154,27 @@ got_keylist = 1; /* FIXME vmalloc'd memory not guaranteed contiguous */ - memset(agp_bridge.key_list, 0, PAGE_SIZE * 4); + memset(agp_bridge->key_list, 0, PAGE_SIZE * 4); - if (agp_bridge.configure()) { + if (agp_bridge->configure()) { printk(KERN_ERR PFX "error configuring host chipset.\n"); rc = -EINVAL; goto err_out; } printk(KERN_INFO PFX "AGP aperture is %dM @ 0x%lx\n", - size_value, agp_bridge.gart_bus_addr); + size_value, agp_bridge->gart_bus_addr); return 0; err_out: - if (agp_bridge.needs_scratch_page == TRUE) { - agp_bridge.agp_destroy_page(phys_to_virt(agp_bridge.scratch_page_real)); + if (agp_bridge->needs_scratch_page == TRUE) { + agp_bridge->agp_destroy_page(phys_to_virt(agp_bridge->scratch_page_real)); } if (got_gatt) - agp_bridge.free_gatt_table(); + agp_bridge->free_gatt_table(); if (got_keylist) - vfree(agp_bridge.key_list); + vfree(agp_bridge->key_list); return rc; } @@ -181,13 +182,16 @@ /* cannot be __exit b/c as it could be called from __init code */ static void agp_backend_cleanup(void) { - agp_bridge.cleanup(); - agp_bridge.free_gatt_table(); - vfree(agp_bridge.key_list); - - if (agp_bridge.needs_scratch_page == TRUE) { - agp_bridge.agp_destroy_page(phys_to_virt(agp_bridge.scratch_page_real)); - } + if (agp_bridge->cleanup != NULL) + agp_bridge->cleanup(); + if (agp_bridge->free_gatt_table != NULL) + agp_bridge->free_gatt_table(); + if (agp_bridge->key_list) + vfree(agp_bridge->key_list); + + if ((agp_bridge->agp_destroy_page!=NULL) && + (agp_bridge->needs_scratch_page == TRUE)) + agp_bridge->agp_destroy_page(phys_to_virt(agp_bridge->scratch_page_real)); } static int agp_power(struct pm_dev *dev, pm_request_t rq, void *data) @@ -195,9 +199,9 @@ switch(rq) { case PM_SUSPEND: - return agp_bridge.suspend(); + return agp_bridge->suspend(); case PM_RESUME: - agp_bridge.resume(); + agp_bridge->resume(); return 0; } return 0; @@ -248,21 +252,25 @@ /* FIXME: What to do with this? */ inter_module_register("drm_agp", THIS_MODULE, &drm_agp); - pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge.dev), agp_power); + pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge->dev), agp_power); agp_count++; return 0; frontend_err: agp_backend_cleanup(); err_out: - agp_bridge.type = NOT_SUPPORTED; + agp_bridge->type = NOT_SUPPORTED; module_put(drv->owner); + drv->dev = NULL; return ret_val; } int agp_unregister_driver(struct agp_driver *drv) { - agp_bridge.type = NOT_SUPPORTED; + if (drv->dev==NULL) + return -ENODEV; + + agp_bridge->type = NOT_SUPPORTED; pm_unregister_all(agp_power); agp_frontend_cleanup(); agp_backend_cleanup(); @@ -282,8 +290,8 @@ already_initialised = 1; - memset(&agp_bridge, 0, sizeof(struct agp_bridge_data)); - agp_bridge.type = NOT_SUPPORTED; + memset(agp_bridge, 0, sizeof(struct agp_bridge_data)); + agp_bridge->type = NOT_SUPPORTED; printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Dave Jones\n", AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR); diff -Nru a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c --- a/drivers/char/agp/frontend.c Fri Feb 14 00:27:27 2003 +++ b/drivers/char/agp/frontend.c Fri Feb 14 00:27:27 2003 @@ -97,7 +97,9 @@ int size, pgprot_t page_prot) { agp_segment_priv *seg; - int num_segments, pg_start, pg_count, i; + int num_segments, i; + off_t pg_start; + size_t pg_count; pg_start = offset / 4096; pg_count = size / 4096; @@ -174,7 +176,7 @@ agp_segment_priv **ret_seg; agp_segment_priv *seg; agp_segment *user_seg; - int i; + size_t i; seg = kmalloc((sizeof(agp_segment_priv) * region->seg_count), GFP_KERNEL); if (seg == NULL) { @@ -578,8 +580,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) { - int size; - int current_size; + unsigned int size, current_size; unsigned long offset; agp_client *client; agp_file_private *priv = (agp_file_private *) file->private_data; @@ -611,8 +612,11 @@ if (!agp_find_seg_in_client(client, offset, size, vma->vm_page_prot)) goto out_inval; - if (remap_page_range(vma, vma->vm_start, (kerninfo.aper_base + offset), - size, vma->vm_page_prot)) { + if (kerninfo.vm_ops) { + vma->vm_ops = kerninfo.vm_ops; + } else if (remap_page_range(vma, vma->vm_start, + (kerninfo.aper_base + offset), + size, vma->vm_page_prot)) { goto out_again; } AGP_UNLOCK(); @@ -623,8 +627,11 @@ if (size != current_size) goto out_inval; - if (remap_page_range(vma, vma->vm_start, kerninfo.aper_base, - size, vma->vm_page_prot)) { + if (kerninfo.vm_ops) { + vma->vm_ops = kerninfo.vm_ops; + } else if (remap_page_range(vma, vma->vm_start, + kerninfo.aper_base, + size, vma->vm_page_prot)) { goto out_again; } AGP_UNLOCK(); diff -Nru a/drivers/char/agp/generic-3.0.c b/drivers/char/agp/generic-3.0.c --- a/drivers/char/agp/generic-3.0.c Fri Feb 14 00:27:27 2003 +++ b/drivers/char/agp/generic-3.0.c Fri Feb 14 00:27:27 2003 @@ -77,7 +77,7 @@ struct agp_3_0_dev *dev; }; - struct pci_dev *td = agp_bridge.dev, *dev; + struct pci_dev *td = agp_bridge->dev, *dev; struct list_head *head = &dev_list->list, *pos; struct agp_3_0_dev *cur; struct isoch_data *master, target; @@ -117,8 +117,8 @@ if((ret = agp_3_0_dev_list_sort(dev_list, ndevs)) != 0) goto free_and_exit; - pci_read_config_dword(td, agp_bridge.capndx + 0x0c, &tnistat); - pci_read_config_dword(td, agp_bridge.capndx + 0x04, &tstatus); + pci_read_config_dword(td, agp_bridge->capndx + 0x0c, &tnistat); + pci_read_config_dword(td, agp_bridge->capndx + 0x04, &tstatus); /* Extract power-on defaults from the target */ target.maxbw = (tnistat >> 16) & 0xff; @@ -170,13 +170,13 @@ * in the target's NISTAT register, so we need to do this now * to get an accurate value for ISOCH_N later. */ - pci_read_config_word(td, agp_bridge.capndx + 0x20, &tnicmd); + pci_read_config_word(td, agp_bridge->capndx + 0x20, &tnicmd); tnicmd &= ~(0x3 << 6); tnicmd |= target.y << 6; - pci_write_config_word(td, agp_bridge.capndx + 0x20, tnicmd); + pci_write_config_word(td, agp_bridge->capndx + 0x20, tnicmd); /* Reread the target's ISOCH_N */ - pci_read_config_dword(td, agp_bridge.capndx + 0x0c, &tnistat); + pci_read_config_dword(td, agp_bridge->capndx + 0x0c, &tnistat); target.n = (tnistat >> 8) & 0xff; /* Calculate the minimum ISOCH_N needed by each master */ @@ -296,7 +296,7 @@ u32 trq, mrq, rem; unsigned int cdev = 0; - pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 0x04, &tstatus); + pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + 0x04, &tstatus); trq = (tstatus >> 24) & 0xff; mrq = trq / ndevs; @@ -321,7 +321,7 @@ */ static int agp_3_0_node_enable(u32 mode, u32 minor) { - struct pci_dev *td = agp_bridge.dev, *dev; + struct pci_dev *td = agp_bridge->dev, *dev; u8 bus_num, mcapndx; u32 isoch, arqsz, cal_cycle, tmp, rate; u32 tstatus, tcmd, mcmd, mstatus, ncapid; @@ -364,7 +364,7 @@ } /* Extract some power-on defaults from the target */ - pci_read_config_dword(td, agp_bridge.capndx + 0x04, &tstatus); + pci_read_config_dword(td, agp_bridge->capndx + 0x04, &tstatus); isoch = (tstatus >> 17) & 0x1; arqsz = (tstatus >> 13) & 0x7; cal_cycle = (tstatus >> 10) & 0x7; @@ -470,7 +470,7 @@ * Also set the AGP_ENABLE bit, effectively 'turning on' the * target (this has to be done _before_ turning on the masters). */ - pci_read_config_dword(td, agp_bridge.capndx + 0x08, &tcmd); + pci_read_config_dword(td, agp_bridge->capndx + 0x08, &tcmd); tcmd &= ~(0x7 << 10); tcmd &= ~0x7; @@ -479,7 +479,7 @@ tcmd |= 0x1 << 8; tcmd |= rate; - pci_write_config_dword(td, agp_bridge.capndx + 0x08, tcmd); + pci_write_config_dword(td, agp_bridge->capndx + 0x08, tcmd); /* * Set the target's advertised arqsz value, the minimum supported @@ -525,11 +525,11 @@ * (AGP 3.0 devices are required to operate as AGP 2.0 devices * when not using 3.0 electricals. */ -int agp_generic_agp_3_0_enable(u32 mode) +void agp_generic_agp_3_0_enable(u32 mode) { u32 ncapid, major, minor, agp_3_0; - pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx, &ncapid); + pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx, &ncapid); major = (ncapid >> 20) & 0xf; minor = (ncapid >> 16) & 0xf; @@ -537,16 +537,13 @@ printk(KERN_INFO PFX "Found an AGP %d.%d compliant device.\n",major, minor); if(major >= 3) { - pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 0x4, &agp_3_0); + pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + 0x4, &agp_3_0); /* * Check to see if we are operating in 3.0 mode */ - if((agp_3_0 >> 3) & 0x1) { + if((agp_3_0 >> 3) & 0x1) agp_3_0_node_enable(mode, minor); - return TRUE; - } } - return FALSE; } EXPORT_SYMBOL(agp_generic_agp_3_0_enable); diff -Nru a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c --- a/drivers/char/agp/generic.c Fri Feb 14 00:27:27 2003 +++ b/drivers/char/agp/generic.c Fri Feb 14 00:27:27 2003 @@ -52,16 +52,16 @@ return; if (key < MAXKEY) - clear_bit(key, agp_bridge.key_list); + clear_bit(key, agp_bridge->key_list); } static int agp_get_key(void) { int bit; - bit = find_first_zero_bit(agp_bridge.key_list, MAXKEY); + bit = find_first_zero_bit(agp_bridge->key_list, MAXKEY); if (bit < MAXKEY) { - set_bit(bit, agp_bridge.key_list); + set_bit(bit, agp_bridge->key_list); return bit; } return -1; @@ -96,21 +96,21 @@ void agp_free_memory(agp_memory * curr) { - int i; + size_t i; - if ((agp_bridge.type == NOT_SUPPORTED) || (curr == NULL)) + if ((agp_bridge->type == NOT_SUPPORTED) || (curr == NULL)) return; if (curr->is_bound == TRUE) agp_unbind_memory(curr); if (curr->type != 0) { - agp_bridge.free_by_type(curr); + agp_bridge->free_by_type(curr); return; } if (curr->page_count != 0) { for (i = 0; i < curr->page_count; i++) { - agp_bridge.agp_destroy_page(phys_to_virt(curr->memory[i])); + agp_bridge->agp_destroy_page(phys_to_virt(curr->memory[i])); } } agp_free_key(curr->key); @@ -124,16 +124,16 @@ { int scratch_pages; agp_memory *new; - int i; + size_t i; - if (agp_bridge.type == NOT_SUPPORTED) + if (agp_bridge->type == NOT_SUPPORTED) return NULL; - if ((atomic_read(&agp_bridge.current_memory_agp) + page_count) > agp_bridge.max_memory_agp) + if ((atomic_read(&agp_bridge->current_memory_agp) + page_count) > agp_bridge->max_memory_agp) return NULL; if (type != 0) { - new = agp_bridge.alloc_by_type(page_count, type); + new = agp_bridge->alloc_by_type(page_count, type); return new; } @@ -145,7 +145,7 @@ return NULL; for (i = 0; i < page_count; i++) { - void *addr = agp_bridge.agp_alloc_page(); + void *addr = agp_bridge->agp_alloc_page(); if (addr == NULL) { agp_free_memory(new); @@ -167,9 +167,9 @@ int current_size; void *temp; - temp = agp_bridge.current_size; + temp = agp_bridge->current_size; - switch (agp_bridge.size_type) { + switch (agp_bridge->size_type) { case U8_APER_SIZE: current_size = A_SIZE_8(temp)->size; break; @@ -201,9 +201,9 @@ int num_entries; void *temp; - temp = agp_bridge.current_size; + temp = agp_bridge->current_size; - switch (agp_bridge.size_type) { + switch (agp_bridge->size_type) { case U8_APER_SIZE: num_entries = A_SIZE_8(temp)->num_entries; break; @@ -235,20 +235,21 @@ int agp_copy_info(agp_kern_info * info) { memset(info, 0, sizeof(agp_kern_info)); - if (agp_bridge.type == NOT_SUPPORTED) { - info->chipset = agp_bridge.type; + if (agp_bridge->type == NOT_SUPPORTED) { + info->chipset = agp_bridge->type; return -EIO; } - info->version.major = agp_bridge.version->major; - info->version.minor = agp_bridge.version->minor; - info->device = agp_bridge.dev; - info->chipset = agp_bridge.type; - info->mode = agp_bridge.mode; - info->aper_base = agp_bridge.gart_bus_addr; + info->version.major = agp_bridge->version->major; + info->version.minor = agp_bridge->version->minor; + info->device = agp_bridge->dev; + info->chipset = agp_bridge->type; + info->mode = agp_bridge->mode; + info->aper_base = agp_bridge->gart_bus_addr; info->aper_size = agp_return_size(); - info->max_memory = agp_bridge.max_memory_agp; - info->current_memory = atomic_read(&agp_bridge.current_memory_agp); - info->cant_use_aperture = agp_bridge.cant_use_aperture; + info->max_memory = agp_bridge->max_memory_agp; + info->current_memory = atomic_read(&agp_bridge->current_memory_agp); + info->cant_use_aperture = agp_bridge->cant_use_aperture; + info->vm_ops = agp_bridge->vm_ops; info->page_mask = ~0UL; return 0; } @@ -265,7 +266,7 @@ { int ret_val; - if ((agp_bridge.type == NOT_SUPPORTED) || + if ((agp_bridge->type == NOT_SUPPORTED) || (curr == NULL) || (curr->is_bound == TRUE)) { return -EINVAL; } @@ -273,7 +274,7 @@ CACHE_FLUSH(); curr->is_flushed = TRUE; } - ret_val = agp_bridge.insert_memory(curr, pg_start, curr->type); + ret_val = agp_bridge->insert_memory(curr, pg_start, curr->type); if (ret_val != 0) return ret_val; @@ -287,13 +288,13 @@ { int ret_val; - if ((agp_bridge.type == NOT_SUPPORTED) || (curr == NULL)) + if ((agp_bridge->type == NOT_SUPPORTED) || (curr == NULL)) return -EINVAL; if (curr->is_bound != TRUE) return -EINVAL; - ret_val = agp_bridge.remove_memory(curr, curr->pg_start, curr->type); + ret_val = agp_bridge->remove_memory(curr, curr->pg_start, curr->type); if (ret_val != 0) return ret_val; @@ -395,15 +396,15 @@ { u32 command; - pci_read_config_dword(agp_bridge.dev, - agp_bridge.capndx + PCI_AGP_STATUS, + pci_read_config_dword(agp_bridge->dev, + agp_bridge->capndx + PCI_AGP_STATUS, &command); command = agp_collect_device_status(mode, command); command |= 0x100; - pci_write_config_dword(agp_bridge.dev, - agp_bridge.capndx + PCI_AGP_COMMAND, + pci_write_config_dword(agp_bridge->dev, + agp_bridge->capndx + PCI_AGP_COMMAND, command); agp_device_command(command, 0); @@ -421,17 +422,17 @@ struct page *page; /* The generic routines can't handle 2 level gatt's */ - if (agp_bridge.size_type == LVL2_APER_SIZE) + if (agp_bridge->size_type == LVL2_APER_SIZE) return -EINVAL; table = NULL; - i = agp_bridge.aperture_size_idx; - temp = agp_bridge.current_size; + i = agp_bridge->aperture_size_idx; + temp = agp_bridge->current_size; size = page_order = num_entries = 0; - if (agp_bridge.size_type != FIXED_APER_SIZE) { + if (agp_bridge->size_type != FIXED_APER_SIZE) { do { - switch (agp_bridge.size_type) { + switch (agp_bridge->size_type) { case U8_APER_SIZE: size = A_SIZE_8(temp)->size; page_order = @@ -462,15 +463,15 @@ if (table == NULL) { i++; - switch (agp_bridge.size_type) { + switch (agp_bridge->size_type) { case U8_APER_SIZE: - agp_bridge.current_size = A_IDX8(); + agp_bridge->current_size = A_IDX8(); break; case U16_APER_SIZE: - agp_bridge.current_size = A_IDX16(); + agp_bridge->current_size = A_IDX16(); break; case U32_APER_SIZE: - agp_bridge.current_size = A_IDX32(); + agp_bridge->current_size = A_IDX32(); break; /* This case will never really * happen. @@ -478,15 +479,15 @@ case FIXED_APER_SIZE: case LVL2_APER_SIZE: default: - agp_bridge.current_size = - agp_bridge.current_size; + agp_bridge->current_size = + agp_bridge->current_size; break; } - temp = agp_bridge.current_size; + temp = agp_bridge->current_size; } else { - agp_bridge.aperture_size_idx = i; + agp_bridge->aperture_size_idx = i; } - } while ((table == NULL) && (i < agp_bridge.num_aperture_sizes)); + } while ((table == NULL) && (i < agp_bridge->num_aperture_sizes)); } else { size = ((struct aper_size_info_fixed *) temp)->size; page_order = ((struct aper_size_info_fixed *) temp)->page_order; @@ -502,14 +503,14 @@ for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) SetPageReserved(page); - agp_bridge.gatt_table_real = (u32 *) table; + agp_bridge->gatt_table_real = (u32 *) table; agp_gatt_table = (void *)table; CACHE_FLUSH(); - agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table), + agp_bridge->gatt_table = ioremap_nocache(virt_to_phys(table), (PAGE_SIZE * (1 << page_order))); CACHE_FLUSH(); - if (agp_bridge.gatt_table == NULL) { + if (agp_bridge->gatt_table == NULL) { for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) ClearPageReserved(page); @@ -517,11 +518,11 @@ return -ENOMEM; } - agp_bridge.gatt_bus_addr = virt_to_phys(agp_bridge.gatt_table_real); + agp_bridge->gatt_bus_addr = virt_to_phys(agp_bridge->gatt_table_real); /* AK: bogus, should encode addresses > 4GB */ for (i = 0; i < num_entries; i++) - agp_bridge.gatt_table[i] = (unsigned long) agp_bridge.scratch_page; + agp_bridge->gatt_table[i] = (unsigned long) agp_bridge->scratch_page; return 0; } @@ -543,9 +544,9 @@ void *temp; struct page *page; - temp = agp_bridge.current_size; + temp = agp_bridge->current_size; - switch (agp_bridge.size_type) { + switch (agp_bridge->size_type) { case U8_APER_SIZE: page_order = A_SIZE_8(temp)->page_order; break; @@ -572,25 +573,27 @@ * from the table. */ - iounmap(agp_bridge.gatt_table); - table = (char *) agp_bridge.gatt_table_real; + iounmap(agp_bridge->gatt_table); + table = (char *) agp_bridge->gatt_table_real; table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1); for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) ClearPageReserved(page); - free_pages((unsigned long) agp_bridge.gatt_table_real, page_order); + free_pages((unsigned long) agp_bridge->gatt_table_real, page_order); return 0; } int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type) { - int i, j, num_entries; + int num_entries; + size_t i; + off_t j; void *temp; - temp = agp_bridge.current_size; + temp = agp_bridge->current_size; - switch (agp_bridge.size_type) { + switch (agp_bridge->size_type) { case U8_APER_SIZE: num_entries = A_SIZE_8(temp)->num_entries; break; @@ -627,7 +630,7 @@ j = pg_start; while (j < (pg_start + mem->page_count)) { - if (!PGE_EMPTY(agp_bridge.gatt_table[j])) { + if (!PGE_EMPTY(agp_bridge->gatt_table[j])) { return -EBUSY; } j++; @@ -639,16 +642,16 @@ } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) - agp_bridge.gatt_table[j] = - agp_bridge.mask_memory(mem->memory[i], mem->type); + agp_bridge->gatt_table[j] = + agp_bridge->mask_memory(mem->memory[i], mem->type); - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return 0; } int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type) { - int i; + size_t i; if (type != 0 || mem->type != 0) { /* The generic routines know nothing of memory types */ @@ -657,11 +660,11 @@ /* AK: bogus, should encode addresses > 4GB */ for (i = pg_start; i < (mem->page_count + pg_start); i++) { - agp_bridge.gatt_table[i] = - (unsigned long) agp_bridge.scratch_page; + agp_bridge->gatt_table[i] = + (unsigned long) agp_bridge->scratch_page; } - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return 0; } @@ -700,7 +703,7 @@ get_page(page); SetPageLocked(page); - atomic_inc(&agp_bridge.current_memory_agp); + atomic_inc(&agp_bridge->current_memory_agp); return page_address(page); } @@ -716,16 +719,16 @@ put_page(page); unlock_page(page); free_page((unsigned long)addr); - atomic_dec(&agp_bridge.current_memory_agp); + atomic_dec(&agp_bridge->current_memory_agp); } /* End Basic Page Allocation Routines */ void agp_enable(u32 mode) { - if (agp_bridge.type == NOT_SUPPORTED) + if (agp_bridge->type == NOT_SUPPORTED) return; - agp_bridge.agp_enable(mode); + agp_bridge->agp_enable(mode); } EXPORT_SYMBOL(agp_free_memory); @@ -750,6 +753,9 @@ EXPORT_SYMBOL(agp_generic_alloc_by_type); EXPORT_SYMBOL(agp_generic_free_by_type); EXPORT_SYMBOL(global_cache_flush); + +EXPORT_SYMBOL(agp_device_command); +EXPORT_SYMBOL(agp_collect_device_status); EXPORT_SYMBOL_GPL(agp_num_entries); diff -Nru a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c --- a/drivers/char/agp/hp-agp.c Fri Feb 14 00:27:29 2003 +++ b/drivers/char/agp/hp-agp.c Fri Feb 14 00:27:29 2003 @@ -176,7 +176,7 @@ size = hp_private.gart_size / MB(1); hp_zx1_sizes[0].size = size; - agp_bridge.current_size = (void *) &hp_zx1_sizes[0]; + agp_bridge->current_size = (void *) &hp_zx1_sizes[0]; return size; } @@ -184,10 +184,10 @@ { struct _hp_private *hp = &hp_private; - agp_bridge.gart_bus_addr = hp->gart_base; - agp_bridge.capndx = pci_find_capability(agp_bridge.dev, PCI_CAP_ID_AGP); - pci_read_config_dword(agp_bridge.dev, - agp_bridge.capndx + PCI_AGP_STATUS, &agp_bridge.mode); + agp_bridge->gart_bus_addr = hp->gart_base; + agp_bridge->capndx = pci_find_capability(agp_bridge->dev, PCI_CAP_ID_AGP); + pci_read_config_dword(agp_bridge->dev, + agp_bridge->capndx + PCI_AGP_STATUS, &agp_bridge->mode); if (hp->io_pdir_owner) { OUTREG64(hp->registers, HP_ZX1_PDIR_BASE, @@ -241,7 +241,7 @@ } for (i = 0; i < hp->gatt_entries; i++) { - hp->gatt[i] = (unsigned long) agp_bridge.scratch_page; + hp->gatt[i] = (unsigned long) agp_bridge->scratch_page; } return 0; @@ -296,11 +296,11 @@ for (k = 0; k < hp->io_pages_per_kpage; k++, j++, paddr += hp->io_page_size) { - hp->gatt[j] = agp_bridge.mask_memory(paddr, type); + hp->gatt[j] = agp_bridge->mask_memory(paddr, type); } } - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return 0; } @@ -316,10 +316,10 @@ io_pg_start = hp->io_pages_per_kpage * pg_start; io_pg_count = hp->io_pages_per_kpage * mem->page_count; for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) { - hp->gatt[i] = agp_bridge.scratch_page; + hp->gatt[i] = agp_bridge->scratch_page; } - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return 0; } @@ -330,39 +330,39 @@ static int __init hp_zx1_setup (struct pci_dev *pdev __attribute__((unused))) { - agp_bridge.masks = hp_zx1_masks; - agp_bridge.dev_private_data = NULL; - agp_bridge.size_type = FIXED_APER_SIZE; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = hp_zx1_configure; - agp_bridge.fetch_size = hp_zx1_fetch_size; - agp_bridge.cleanup = hp_zx1_cleanup; - agp_bridge.tlb_flush = hp_zx1_tlbflush; - agp_bridge.mask_memory = hp_zx1_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = hp_zx1_create_gatt_table; - agp_bridge.free_gatt_table = hp_zx1_free_gatt_table; - agp_bridge.insert_memory = hp_zx1_insert_memory; - agp_bridge.remove_memory = hp_zx1_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.cant_use_aperture = 1; + agp_bridge->masks = hp_zx1_masks; + agp_bridge->dev_private_data = NULL; + agp_bridge->size_type = FIXED_APER_SIZE; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = hp_zx1_configure; + agp_bridge->fetch_size = hp_zx1_fetch_size; + agp_bridge->cleanup = hp_zx1_cleanup; + agp_bridge->tlb_flush = hp_zx1_tlbflush; + agp_bridge->mask_memory = hp_zx1_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = hp_zx1_create_gatt_table; + agp_bridge->free_gatt_table = hp_zx1_free_gatt_table; + agp_bridge->insert_memory = hp_zx1_insert_memory; + agp_bridge->remove_memory = hp_zx1_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->cant_use_aperture = 1; return hp_zx1_ioc_init(); } static int __init agp_find_supported_device(struct pci_dev *dev) { - agp_bridge.dev = dev; + agp_bridge->dev = dev; /* ZX1 LBAs can be either PCI or AGP bridges */ if (pci_find_capability(dev, PCI_CAP_ID_AGP)) { printk(KERN_INFO PFX "Detected HP ZX1 AGP chipset at %s\n", dev->slot_name); - agp_bridge.type = HP_ZX1; - agp_bridge.dev = dev; + agp_bridge->type = HP_ZX1; + agp_bridge->dev = dev; return hp_zx1_setup(dev); } return -ENODEV; @@ -408,7 +408,7 @@ ret_val = pci_module_init(&agp_hp_pci_driver); if (ret_val) - agp_bridge.type = NOT_SUPPORTED; + agp_bridge->type = NOT_SUPPORTED; return ret_val; } diff -Nru a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c --- a/drivers/char/agp/i460-agp.c Fri Feb 14 00:27:28 2003 +++ b/drivers/char/agp/i460-agp.c Fri Feb 14 00:27:28 2003 @@ -96,7 +96,7 @@ struct aper_size_info_8 *values; /* Determine the GART page size */ - pci_read_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL, &temp); + pci_read_config_byte(agp_bridge->dev, INTEL_I460_GXBCTL, &temp); i460.io_page_shift = (temp & I460_4M_PS) ? 22 : 12; pr_debug("i460_fetch_size: io_page_shift=%d\n", i460.io_page_shift); @@ -107,9 +107,9 @@ return 0; } - values = A_SIZE_8(agp_bridge.aperture_sizes); + values = A_SIZE_8(agp_bridge->aperture_sizes); - pci_read_config_byte(agp_bridge.dev, INTEL_I460_AGPSIZ, &temp); + pci_read_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ, &temp); /* Exit now if the IO drivers for the GART SRAMS are turned off */ if (temp & I460_SRAM_IO_DISABLE) { @@ -130,7 +130,7 @@ else i460.dynamic_apbase = INTEL_I460_APBASE; - for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { /* * Dynamically calculate the proper num_entries and page_order values for * the define aperture sizes. Take care not to shift off the end of @@ -140,11 +140,11 @@ values[i].page_order = log2((sizeof(u32)*values[i].num_entries) >> PAGE_SHIFT); } - for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { /* Neglect control bits when matching up size_value */ if ((temp & I460_AGPSIZ_MASK) == values[i].size_value) { - agp_bridge.previous_size = agp_bridge.current_size = (void *) (values + i); - agp_bridge.aperture_size_idx = i; + agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i); + agp_bridge->aperture_size_idx = i; return values[i].size; } } @@ -166,8 +166,8 @@ { u8 temp; - pci_read_config_byte(agp_bridge.dev, INTEL_I460_AGPSIZ, &temp); - pci_write_config_byte(agp_bridge.dev, INTEL_I460_AGPSIZ, + pci_read_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ, &temp); + pci_write_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ, ((temp & ~I460_AGPSIZ_MASK) | size_value)); } @@ -175,7 +175,7 @@ { struct aper_size_info_8 *previous_size; - previous_size = A_SIZE_8(agp_bridge.previous_size); + previous_size = A_SIZE_8(agp_bridge->previous_size); i460_write_agpsiz(previous_size->size_value); if (I460_IO_PAGE_SHIFT > PAGE_SHIFT) @@ -194,7 +194,7 @@ temp.large = 0; - current_size = A_SIZE_8(agp_bridge.current_size); + current_size = A_SIZE_8(agp_bridge->current_size); i460_write_agpsiz(current_size->size_value); /* @@ -202,14 +202,14 @@ * This has to be done since the AGP aperture can be above 4GB on * 460 based systems. */ - pci_read_config_dword(agp_bridge.dev, i460.dynamic_apbase, &(temp.small[0])); - pci_read_config_dword(agp_bridge.dev, i460.dynamic_apbase + 4, &(temp.small[1])); + pci_read_config_dword(agp_bridge->dev, i460.dynamic_apbase, &(temp.small[0])); + pci_read_config_dword(agp_bridge->dev, i460.dynamic_apbase + 4, &(temp.small[1])); /* Clear BAR control bits */ - agp_bridge.gart_bus_addr = temp.large & ~((1UL << 3) - 1); + agp_bridge->gart_bus_addr = temp.large & ~((1UL << 3) - 1); - pci_read_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL, &scratch); - pci_write_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL, + pci_read_config_byte(agp_bridge->dev, INTEL_I460_GXBCTL, &scratch); + pci_write_config_byte(agp_bridge->dev, INTEL_I460_GXBCTL, (scratch & 0x02) | I460_GXBCTL_OOG | I460_GXBCTL_BWC); /* @@ -234,16 +234,16 @@ /* * Load up the fixed address of the GART SRAMS which hold our GATT table. */ - temp = agp_bridge.current_size; + temp = agp_bridge->current_size; page_order = A_SIZE_8(temp)->page_order; num_entries = A_SIZE_8(temp)->num_entries; i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order); /* These are no good, the should be removed from the agp_bridge strucure... */ - agp_bridge.gatt_table_real = NULL; - agp_bridge.gatt_table = NULL; - agp_bridge.gatt_bus_addr = 0; + agp_bridge->gatt_table_real = NULL; + agp_bridge->gatt_table = NULL; + agp_bridge->gatt_bus_addr = 0; for (i = 0; i < num_entries; ++i) WR_GATT(i, 0); @@ -256,7 +256,7 @@ int num_entries, i; void *temp; - temp = agp_bridge.current_size; + temp = agp_bridge->current_size; num_entries = A_SIZE_8(temp)->num_entries; @@ -284,7 +284,7 @@ io_pg_start = I460_IOPAGES_PER_KPAGE * pg_start; - temp = agp_bridge.current_size; + temp = agp_bridge->current_size; num_entries = A_SIZE_8(temp)->num_entries; if ((io_pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count) > num_entries) { @@ -306,7 +306,7 @@ for (i = 0, j = io_pg_start; i < mem->page_count; i++) { paddr = mem->memory[i]; for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size) - WR_GATT(j, agp_bridge.mask_memory(paddr, mem->type)); + WR_GATT(j, agp_bridge->mask_memory(paddr, mem->type)); } WR_FLUSH_GATT(j - 1); return 0; @@ -364,7 +364,7 @@ lp->paddr = virt_to_phys(lpage); lp->refcount = 0; - atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge.current_memory_agp); + atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); return 0; } @@ -374,7 +374,7 @@ lp->alloced_map = NULL; free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); - atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge.current_memory_agp); + atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); } static int i460_insert_memory_large_io_page (agp_memory * mem, off_t pg_start, int type) @@ -383,7 +383,7 @@ struct lp_desc *start, *end, *lp; void *temp; - temp = agp_bridge.current_size; + temp = agp_bridge->current_size; num_entries = A_SIZE_8(temp)->num_entries; /* Figure out what pg_start means in terms of our large GART pages */ @@ -417,7 +417,7 @@ if (i460_alloc_large_page(lp) < 0) return -ENOMEM; pg = lp - i460.lp_desc; - WR_GATT(pg, agp_bridge.mask_memory(lp->paddr, 0)); + WR_GATT(pg, agp_bridge->mask_memory(lp->paddr, 0)); WR_FLUSH_GATT(pg); } @@ -439,7 +439,7 @@ struct lp_desc *start, *end, *lp; void *temp; - temp = agp_bridge.current_size; + temp = agp_bridge->current_size; num_entries = A_SIZE_8(temp)->num_entries; /* Figure out what pg_start means in terms of our large GART pages */ @@ -519,43 +519,43 @@ static unsigned long i460_mask_memory (unsigned long addr, int type) { /* Make sure the returned address is a valid GATT entry */ - return (agp_bridge.masks[0].mask + return (agp_bridge->masks[0].mask | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12)); } static int __init intel_i460_setup (struct pci_dev *pdev __attribute__((unused))) { - agp_bridge.masks = i460_masks; - agp_bridge.aperture_sizes = (void *) i460_sizes; - agp_bridge.size_type = U8_APER_SIZE; - agp_bridge.num_aperture_sizes = 3; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = i460_configure; - agp_bridge.fetch_size = i460_fetch_size; - agp_bridge.cleanup = i460_cleanup; - agp_bridge.tlb_flush = i460_tlb_flush; - agp_bridge.mask_memory = i460_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = i460_create_gatt_table; - agp_bridge.free_gatt_table = i460_free_gatt_table; + agp_bridge->masks = i460_masks; + agp_bridge->aperture_sizes = (void *) i460_sizes; + agp_bridge->size_type = U8_APER_SIZE; + agp_bridge->num_aperture_sizes = 3; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = i460_configure; + agp_bridge->fetch_size = i460_fetch_size; + agp_bridge->cleanup = i460_cleanup; + agp_bridge->tlb_flush = i460_tlb_flush; + agp_bridge->mask_memory = i460_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = i460_create_gatt_table; + agp_bridge->free_gatt_table = i460_free_gatt_table; #if I460_LARGE_IO_PAGES - agp_bridge.insert_memory = i460_insert_memory; - agp_bridge.remove_memory = i460_remove_memory; - agp_bridge.agp_alloc_page = i460_alloc_page; - agp_bridge.agp_destroy_page = i460_destroy_page; + agp_bridge->insert_memory = i460_insert_memory; + agp_bridge->remove_memory = i460_remove_memory; + agp_bridge->agp_alloc_page = i460_alloc_page; + agp_bridge->agp_destroy_page = i460_destroy_page; #else - agp_bridge.insert_memory = i460_insert_memory_small_io_page; - agp_bridge.remove_memory = i460_remove_memory_small_io_page; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; + agp_bridge->insert_memory = i460_insert_memory_small_io_page; + agp_bridge->remove_memory = i460_remove_memory_small_io_page; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; #endif - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 1; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 1; return 0; } @@ -571,8 +571,8 @@ if (cap_ptr == 0) return -ENODEV; - agp_bridge.dev = dev; - agp_bridge.capndx = cap_ptr; + agp_bridge->dev = dev; + agp_bridge->capndx = cap_ptr; intel_i460_setup(dev); i460_agp_driver.dev = dev; agp_register_driver(&i460_agp_driver); @@ -605,7 +605,7 @@ ret_val = pci_module_init(&agp_intel_i460_pci_driver); if (ret_val) - agp_bridge.type = NOT_SUPPORTED; + agp_bridge->type = NOT_SUPPORTED; return ret_val; } diff -Nru a/drivers/char/agp/i7x05-agp.c b/drivers/char/agp/i7x05-agp.c --- a/drivers/char/agp/i7x05-agp.c Fri Feb 14 00:27:27 2003 +++ b/drivers/char/agp/i7x05-agp.c Fri Feb 14 00:27:27 2003 @@ -13,16 +13,16 @@ /* * For AGP 3.0 APSIZE is now 16 bits */ - pci_read_config_word (agp_bridge.dev, INTEL_I7505_APSIZE, &tmp); + pci_read_config_word (agp_bridge->dev, INTEL_I7505_APSIZE, &tmp); tmp = (tmp & 0xfff); - values = A_SIZE_16(agp_bridge.aperture_sizes); + values = A_SIZE_16(agp_bridge->aperture_sizes); - for (i=0; i < agp_bridge.num_aperture_sizes; i++) { + for (i=0; i < agp_bridge->num_aperture_sizes; i++) { if (tmp == values[i].size_value) { - agp_bridge.previous_size = agp_bridge.current_size = + agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + i); - agp_bridge.aperture_size_idx = i; + agp_bridge->aperture_size_idx = i; return values[i].size; } } @@ -33,18 +33,18 @@ static void intel_7505_tlbflush(agp_memory *mem) { u32 temp; - pci_read_config_dword(agp_bridge.dev, INTEL_I7505_AGPCTRL, &temp); - pci_write_config_dword(agp_bridge.dev, INTEL_I7505_AGPCTRL, temp & ~(1 << 7)); - pci_read_config_dword(agp_bridge.dev, INTEL_I7505_AGPCTRL, &temp); - pci_write_config_dword(agp_bridge.dev, INTEL_I7505_AGPCTRL, temp | (1 << 7)); + pci_read_config_dword(agp_bridge->dev, INTEL_I7505_AGPCTRL, &temp); + pci_write_config_dword(agp_bridge->dev, INTEL_I7505_AGPCTRL, temp & ~(1 << 7)); + pci_read_config_dword(agp_bridge->dev, INTEL_I7505_AGPCTRL, &temp); + pci_write_config_dword(agp_bridge->dev, INTEL_I7505_AGPCTRL, temp | (1 << 7)); } static void intel_7505_cleanup(void) { aper_size_info_16 *previous_size; - previous_size = A_SIZE_16(agp_bridge.previous_size); - pci_write_config_byte(agp_bridge.dev, INTEL_I7505_APSIZE, + previous_size = A_SIZE_16(agp_bridge->previous_size); + pci_write_config_byte(agp_bridge->dev, INTEL_I7505_APSIZE, previous_size->size_value); } @@ -54,25 +54,25 @@ u32 temp; aper_size_info_16 *current_size; - current_size = A_SIZE_16(agp_bridge.current_size); + current_size = A_SIZE_16(agp_bridge->current_size); /* aperture size */ - pci_write_config_word(agp_bridge.dev, INTEL_I7505_APSIZE, + pci_write_config_word(agp_bridge->dev, INTEL_I7505_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_I7505_NAPBASELO, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(agp_bridge->dev, INTEL_I7505_NAPBASELO, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase */ - pci_write_config_dword(agp_bridge.dev, INTEL_I7505_ATTBASE, - agp_bridge.gatt_bus_addr); + pci_write_config_dword(agp_bridge->dev, INTEL_I7505_ATTBASE, + agp_bridge->gatt_bus_addr); /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_I7505_AGPCTRL, 0x0000); + pci_write_config_dword(agp_bridge->dev, INTEL_I7505_AGPCTRL, 0x0000); /* clear error registers */ - pci_write_config_byte(agp_bridge.dev, INTEL_I7505_ERRSTS, 0xff); + pci_write_config_byte(agp_bridge->dev, INTEL_I7505_ERRSTS, 0xff); return 0; } @@ -95,30 +95,30 @@ static int __init intel_7505_setup (struct pci_dev *pdev) { - agp_bridge.masks = intel_generic_masks; - agp_bridge.aperture_sizes = (void *) intel_7505_sizes; - agp_bridge.size_type = U16_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = intel_7505_configure; - agp_bridge.fetch_size = intel_7505_fetch_size; - agp_bridge.cleanup = intel_7505_cleanup; - agp_bridge.tlb_flush = intel_7505_tlbflush; - agp_bridge.mask_memory = intel_mask_memory; - agp_bridge.agp_enable = i7505_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = intel_generic_masks; + agp_bridge->aperture_sizes = (void *) intel_7505_sizes; + agp_bridge->size_type = U16_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = intel_7505_configure; + agp_bridge->fetch_size = intel_7505_fetch_size; + agp_bridge->cleanup = intel_7505_cleanup; + agp_bridge->tlb_flush = intel_7505_tlbflush; + agp_bridge->mask_memory = intel_mask_memory; + agp_bridge->agp_enable = i7505_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return 0; } @@ -149,7 +149,7 @@ if (pdev->device == devs[j].device_id) { printk (KERN_INFO PFX "Detected Intel %s chipset\n", devs[j].chipset_name); - agp_bridge.type = devs[j].chipset; + agp_bridge->type = devs[j].chipset; if (devs[j].chipset_setup != NULL) return devs[j].chipset_setup(pdev); @@ -177,10 +177,10 @@ return -ENODEV; if (agp_lookup_host_bridge(dev) != -ENODEV) { - agp_bridge.dev = dev; - agp_bridge.capndx = cap_ptr; + agp_bridge->dev = dev; + agp_bridge->capndx = cap_ptr; /* Fill in the mode register */ - pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode) + pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode) i7x05_agp_driver.dev = dev; agp_register_driver(&i7x05_agp_driver); return 0; @@ -215,7 +215,7 @@ ret_val = pci_module_init(&agp_i7x05_pci_driver); if (ret_val) - agp_bridge.type = NOT_SUPPORTED; + agp_bridge->type = NOT_SUPPORTED; return ret_val; } diff -Nru a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c --- a/drivers/char/agp/intel-agp.c Fri Feb 14 00:27:28 2003 +++ b/drivers/char/agp/intel-agp.c Fri Feb 14 00:27:28 2003 @@ -39,22 +39,22 @@ u32 smram_miscc; struct aper_size_info_fixed *values; - pci_read_config_dword(agp_bridge.dev, I810_SMRAM_MISCC, &smram_miscc); - values = A_SIZE_FIX(agp_bridge.aperture_sizes); + pci_read_config_dword(agp_bridge->dev, I810_SMRAM_MISCC, &smram_miscc); + values = A_SIZE_FIX(agp_bridge->aperture_sizes); if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) { printk(KERN_WARNING PFX "i810 is disabled\n"); return 0; } if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) { - agp_bridge.previous_size = - agp_bridge.current_size = (void *) (values + 1); - agp_bridge.aperture_size_idx = 1; + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + 1); + agp_bridge->aperture_size_idx = 1; return values[1].size; } else { - agp_bridge.previous_size = - agp_bridge.current_size = (void *) (values); - agp_bridge.aperture_size_idx = 0; + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values); + agp_bridge->aperture_size_idx = 0; return values[0].size; } @@ -67,7 +67,7 @@ u32 temp; int i; - current_size = A_SIZE_FIX(agp_bridge.current_size); + current_size = A_SIZE_FIX(agp_bridge->current_size); pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp); temp &= 0xfff80000; @@ -81,16 +81,16 @@ intel_i810_private.num_dcache_entries = 1024; } pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL, - agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED); + agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED); CACHE_FLUSH(); - if (agp_bridge.needs_scratch_page == TRUE) { + if (agp_bridge->needs_scratch_page == TRUE) { for (i = 0; i < current_size->num_entries; i++) { OUTREG32(intel_i810_private.registers, I810_PTE_BASE + (i * 4), - agp_bridge.scratch_page); + agp_bridge->scratch_page); } } return 0; @@ -118,14 +118,14 @@ int i, j, num_entries; void *temp; - temp = agp_bridge.current_size; + temp = agp_bridge->current_size; num_entries = A_SIZE_FIX(temp)->num_entries; if ((pg_start + mem->page_count) > num_entries) { return -EINVAL; } for (j = pg_start; j < (pg_start + mem->page_count); j++) { - if (!PGE_EMPTY(agp_bridge.gatt_table[j])) { + if (!PGE_EMPTY(agp_bridge->gatt_table[j])) { return -EBUSY; } } @@ -141,7 +141,7 @@ I810_PTE_VALID); } CACHE_FLUSH(); - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return 0; } if((type == AGP_PHYS_MEMORY) && (mem->type == AGP_PHYS_MEMORY)) @@ -154,11 +154,11 @@ for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { OUTREG32(intel_i810_private.registers, I810_PTE_BASE + (j * 4), - agp_bridge.mask_memory(mem->memory[i], mem->type)); + agp_bridge->mask_memory(mem->memory[i], mem->type)); } CACHE_FLUSH(); - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return 0; } @@ -170,11 +170,11 @@ for (i = pg_start; i < (mem->page_count + pg_start); i++) { OUTREG32(intel_i810_private.registers, I810_PTE_BASE + (i * 4), - agp_bridge.scratch_page); + agp_bridge->scratch_page); } CACHE_FLUSH(); - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return 0; } @@ -211,7 +211,7 @@ if (new == NULL) return NULL; - addr = agp_bridge.agp_alloc_page(); + addr = agp_bridge->agp_alloc_page(); if (addr == NULL) { /* Free this structure */ @@ -232,7 +232,7 @@ { agp_free_key(curr->key); if(curr->type == AGP_PHYS_MEMORY) { - agp_bridge.agp_destroy_page(phys_to_virt(curr->memory[0])); + agp_bridge->agp_destroy_page(phys_to_virt(curr->memory[0])); vfree(curr->memory); } kfree(curr); @@ -241,37 +241,37 @@ static unsigned long intel_i810_mask_memory(unsigned long addr, int type) { /* Type checking must be done elsewhere */ - return addr | agp_bridge.masks[type].mask; + return addr | agp_bridge->masks[type].mask; } static int __init intel_i810_setup(struct pci_dev *i810_dev) { intel_i810_private.i810_dev = i810_dev; - agp_bridge.masks = intel_i810_masks; - agp_bridge.aperture_sizes = (void *) intel_i810_sizes; - agp_bridge.size_type = FIXED_APER_SIZE; - agp_bridge.num_aperture_sizes = 2; - agp_bridge.dev_private_data = (void *) &intel_i810_private; - agp_bridge.needs_scratch_page = TRUE; - agp_bridge.configure = intel_i810_configure; - agp_bridge.fetch_size = intel_i810_fetch_size; - agp_bridge.cleanup = intel_i810_cleanup; - agp_bridge.tlb_flush = intel_i810_tlbflush; - agp_bridge.mask_memory = intel_i810_mask_memory; - agp_bridge.agp_enable = intel_i810_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = intel_i810_insert_entries; - agp_bridge.remove_memory = intel_i810_remove_entries; - agp_bridge.alloc_by_type = intel_i810_alloc_by_type; - agp_bridge.free_by_type = intel_i810_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = intel_i810_masks; + agp_bridge->aperture_sizes = (void *) intel_i810_sizes; + agp_bridge->size_type = FIXED_APER_SIZE; + agp_bridge->num_aperture_sizes = 2; + agp_bridge->dev_private_data = (void *) &intel_i810_private; + agp_bridge->needs_scratch_page = TRUE; + agp_bridge->configure = intel_i810_configure; + agp_bridge->fetch_size = intel_i810_fetch_size; + agp_bridge->cleanup = intel_i810_cleanup; + agp_bridge->tlb_flush = intel_i810_tlbflush; + agp_bridge->mask_memory = intel_i810_mask_memory; + agp_bridge->agp_enable = intel_i810_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = intel_i810_insert_entries; + agp_bridge->remove_memory = intel_i810_remove_entries; + agp_bridge->alloc_by_type = intel_i810_alloc_by_type; + agp_bridge->free_by_type = intel_i810_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return 0; } @@ -296,7 +296,7 @@ u8 rdct; static const int ddt[4] = { 0, 16, 32, 64 }; - pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl); + pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); switch (gmch_ctrl & I830_GMCH_GMS_MASK) { case I830_GMCH_GMS_STOLEN_512: @@ -337,10 +337,10 @@ int num_entries; u32 temp; - size = agp_bridge.current_size; + size = agp_bridge->current_size; page_order = size->page_order; num_entries = size->num_entries; - agp_bridge.gatt_table_real = 0; + agp_bridge->gatt_table_real = 0; pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp); temp &= 0xfff80000; @@ -354,9 +354,9 @@ /* we have to call this as early as possible after the MMIO base address is known */ intel_i830_init_gtt_entries(); - agp_bridge.gatt_table = NULL; + agp_bridge->gatt_table = NULL; - agp_bridge.gatt_bus_addr = temp; + agp_bridge->gatt_bus_addr = temp; return(0); } @@ -374,16 +374,16 @@ u16 gmch_ctrl; struct aper_size_info_fixed *values; - pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl); - values = A_SIZE_FIX(agp_bridge.aperture_sizes); + pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); + values = A_SIZE_FIX(agp_bridge->aperture_sizes); if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { - agp_bridge.previous_size = agp_bridge.current_size = (void *) values; - agp_bridge.aperture_size_idx = 0; + agp_bridge->previous_size = agp_bridge->current_size = (void *) values; + agp_bridge->aperture_size_idx = 0; return(values[0].size); } else { - agp_bridge.previous_size = agp_bridge.current_size = (void *) values; - agp_bridge.aperture_size_idx = 1; + agp_bridge->previous_size = agp_bridge->current_size = (void *) values; + agp_bridge->aperture_size_idx = 1; return(values[1].size); } @@ -397,21 +397,21 @@ u16 gmch_ctrl; int i; - current_size = A_SIZE_FIX(agp_bridge.current_size); + current_size = A_SIZE_FIX(agp_bridge->current_size); pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); - pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl); + pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); gmch_ctrl |= I830_GMCH_ENABLED; - pci_write_config_word(agp_bridge.dev,I830_GMCH_CTRL,gmch_ctrl); + pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl); - OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED); + OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED); CACHE_FLUSH(); - if (agp_bridge.needs_scratch_page == TRUE) + if (agp_bridge->needs_scratch_page == TRUE) for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) - OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page); + OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page); return (0); } @@ -426,7 +426,7 @@ int i,j,num_entries; void *temp; - temp = agp_bridge.current_size; + temp = agp_bridge->current_size; num_entries = A_SIZE_FIX(temp)->num_entries; if (pg_start < intel_i830_private.gtt_entries) { @@ -452,11 +452,11 @@ for (i = 0, j = pg_start; i < mem->page_count; i++, j++) OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4), - agp_bridge.mask_memory(mem->memory[i], mem->type)); + agp_bridge->mask_memory(mem->memory[i], mem->type)); CACHE_FLUSH(); - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return(0); } @@ -473,11 +473,11 @@ } for (i = pg_start; i < (mem->page_count + pg_start); i++) - OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page); + OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page); CACHE_FLUSH(); - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return (0); } @@ -504,7 +504,7 @@ if (nw == NULL) return(NULL); - addr = agp_bridge.agp_alloc_page(); + addr = agp_bridge->agp_alloc_page(); if (addr == NULL) { /* free this structure */ agp_free_memory(nw); @@ -526,35 +526,35 @@ { intel_i830_private.i830_dev = i830_dev; - agp_bridge.masks = intel_i810_masks; - agp_bridge.aperture_sizes = (void *) intel_i830_sizes; - agp_bridge.size_type = FIXED_APER_SIZE; - agp_bridge.num_aperture_sizes = 2; - - agp_bridge.dev_private_data = (void *) &intel_i830_private; - agp_bridge.needs_scratch_page = TRUE; - - agp_bridge.configure = intel_i830_configure; - agp_bridge.fetch_size = intel_i830_fetch_size; - agp_bridge.cleanup = intel_i830_cleanup; - agp_bridge.tlb_flush = intel_i810_tlbflush; - agp_bridge.mask_memory = intel_i810_mask_memory; - agp_bridge.agp_enable = intel_i810_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - - agp_bridge.create_gatt_table = intel_i830_create_gatt_table; - agp_bridge.free_gatt_table = intel_i830_free_gatt_table; - - agp_bridge.insert_memory = intel_i830_insert_entries; - agp_bridge.remove_memory = intel_i830_remove_entries; - agp_bridge.alloc_by_type = intel_i830_alloc_by_type; - agp_bridge.free_by_type = intel_i810_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = intel_i810_masks; + agp_bridge->aperture_sizes = (void *) intel_i830_sizes; + agp_bridge->size_type = FIXED_APER_SIZE; + agp_bridge->num_aperture_sizes = 2; + + agp_bridge->dev_private_data = (void *) &intel_i830_private; + agp_bridge->needs_scratch_page = TRUE; + + agp_bridge->configure = intel_i830_configure; + agp_bridge->fetch_size = intel_i830_fetch_size; + agp_bridge->cleanup = intel_i830_cleanup; + agp_bridge->tlb_flush = intel_i810_tlbflush; + agp_bridge->mask_memory = intel_i810_mask_memory; + agp_bridge->agp_enable = intel_i810_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + + agp_bridge->create_gatt_table = intel_i830_create_gatt_table; + agp_bridge->free_gatt_table = intel_i830_free_gatt_table; + + agp_bridge->insert_memory = intel_i830_insert_entries; + agp_bridge->remove_memory = intel_i830_remove_entries; + agp_bridge->alloc_by_type = intel_i830_alloc_by_type; + agp_bridge->free_by_type = intel_i810_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return(0); } @@ -564,13 +564,13 @@ u16 temp; struct aper_size_info_16 *values; - pci_read_config_word(agp_bridge.dev, INTEL_APSIZE, &temp); - values = A_SIZE_16(agp_bridge.aperture_sizes); + pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp); + values = A_SIZE_16(agp_bridge->aperture_sizes); - for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { if (temp == values[i].size_value) { - agp_bridge.previous_size = agp_bridge.current_size = (void *) (values + i); - agp_bridge.aperture_size_idx = i; + agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i); + agp_bridge->aperture_size_idx = i; return values[i].size; } } @@ -584,20 +584,20 @@ u8 temp; struct aper_size_info_8 *values; - pci_read_config_byte(agp_bridge.dev, INTEL_APSIZE, &temp); + pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp); /* Intel 815 chipsets have a _weird_ APSIZE register with only * one non-reserved bit, so mask the others out ... */ - if (agp_bridge.type == INTEL_I815) + if (agp_bridge->type == INTEL_I815) temp &= (1 << 3); - values = A_SIZE_8(agp_bridge.aperture_sizes); + values = A_SIZE_8(agp_bridge->aperture_sizes); - for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { if (temp == values[i].size_value) { - agp_bridge.previous_size = - agp_bridge.current_size = (void *) (values + i); - agp_bridge.aperture_size_idx = i; + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + i); + agp_bridge->aperture_size_idx = i; return values[i].size; } } @@ -607,18 +607,18 @@ static void intel_tlbflush(agp_memory * mem) { - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2200); - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280); + pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2200); + pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280); } static void intel_8xx_tlbflush(agp_memory * mem) { u32 temp; - pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp); - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp & ~(1 << 7)); - pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp); - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp | (1 << 7)); + pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp); + pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp & ~(1 << 7)); + pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp); + pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp | (1 << 7)); } @@ -627,10 +627,10 @@ u16 temp; struct aper_size_info_16 *previous_size; - previous_size = A_SIZE_16(agp_bridge.previous_size); - pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp); - pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9)); - pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, previous_size->size_value); + previous_size = A_SIZE_16(agp_bridge->previous_size); + pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp); + pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9)); + pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value); } @@ -639,10 +639,10 @@ u16 temp; struct aper_size_info_8 *previous_size; - previous_size = A_SIZE_8(agp_bridge.previous_size); - pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp); - pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9)); - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, previous_size->size_value); + previous_size = A_SIZE_8(agp_bridge->previous_size); + pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp); + pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9)); + pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value); } @@ -652,27 +652,27 @@ u16 temp2; struct aper_size_info_16 *current_size; - current_size = A_SIZE_16(agp_bridge.current_size); + current_size = A_SIZE_16(agp_bridge->current_size); /* aperture size */ - pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); + pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); + pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280); + pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280); /* paccfg/nbxcfg */ - pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2); - pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, + pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2); + pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, (temp2 & ~(1 << 10)) | (1 << 9)); /* clear any possible error conditions */ - pci_write_config_byte(agp_bridge.dev, INTEL_ERRSTS + 1, 7); + pci_write_config_byte(agp_bridge->dev, INTEL_ERRSTS + 1, 7); return 0; } @@ -682,32 +682,32 @@ u8 temp2; struct aper_size_info_8 *current_size; - current_size = A_SIZE_8(agp_bridge.current_size); + current_size = A_SIZE_8(agp_bridge->current_size); /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ /* the Intel 815 chipset spec. says that bits 29-31 in the * ATTBASE register are reserved -> try not to write them */ - if (agp_bridge.gatt_bus_addr & INTEL_815_ATTBASE_MASK) + if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) panic("gatt bus addr too high"); - pci_read_config_dword(agp_bridge.dev, INTEL_ATTBASE, &addr); + pci_read_config_dword(agp_bridge->dev, INTEL_ATTBASE, &addr); addr &= INTEL_815_ATTBASE_MASK; - addr |= agp_bridge.gatt_bus_addr; - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, addr); + addr |= agp_bridge->gatt_bus_addr; + pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, addr); /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); /* apcont */ - pci_read_config_byte(agp_bridge.dev, INTEL_815_APCONT, &temp2); - pci_write_config_byte(agp_bridge.dev, INTEL_815_APCONT, temp2 | (1 << 1)); + pci_read_config_byte(agp_bridge->dev, INTEL_815_APCONT, &temp2); + pci_write_config_byte(agp_bridge->dev, INTEL_815_APCONT, temp2 | (1 << 1)); /* clear any possible error conditions */ /* Oddness : this chipset seems to have no ERRSTS register ! */ @@ -724,11 +724,11 @@ u8 temp; struct aper_size_info_8 *previous_size; - previous_size = A_SIZE_8(agp_bridge.previous_size); - pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp); - pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR, + previous_size = A_SIZE_8(agp_bridge->previous_size); + pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp); + pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR, temp & ~(1 << 1)); - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value); } @@ -739,28 +739,28 @@ u8 temp2; struct aper_size_info_8 *current_size; - current_size = A_SIZE_8(agp_bridge.current_size); + current_size = A_SIZE_8(agp_bridge->current_size); /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); + pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); + pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); /* global enable aperture access */ /* This flag is not accessed through MCHCFG register as in */ /* i850 chipset. */ - pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp2); - pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR, temp2 | (1 << 1)); + pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp2); + pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR, temp2 | (1 << 1)); /* clear any possible AGP-related error conditions */ - pci_write_config_word(agp_bridge.dev, INTEL_I820_ERRSTS, 0x001c); + pci_write_config_word(agp_bridge->dev, INTEL_I820_ERRSTS, 0x001c); return 0; } @@ -770,26 +770,26 @@ u16 temp2; struct aper_size_info_8 *current_size; - current_size = A_SIZE_8(agp_bridge.current_size); + current_size = A_SIZE_8(agp_bridge->current_size); /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); + pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); + pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); /* mcgcfg */ - pci_read_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, &temp2); - pci_write_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, temp2 | (1 << 9)); + pci_read_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, &temp2); + pci_write_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, temp2 | (1 << 9)); /* clear any possible error conditions */ - pci_write_config_word(agp_bridge.dev, INTEL_I840_ERRSTS, 0xc000); + pci_write_config_word(agp_bridge->dev, INTEL_I840_ERRSTS, 0xc000); return 0; } @@ -799,26 +799,26 @@ u8 temp2; struct aper_size_info_8 *current_size; - current_size = A_SIZE_8(agp_bridge.current_size); + current_size = A_SIZE_8(agp_bridge->current_size); /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); + pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); + pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); /* agpm */ - pci_read_config_byte(agp_bridge.dev, INTEL_I845_AGPM, &temp2); - pci_write_config_byte(agp_bridge.dev, INTEL_I845_AGPM, temp2 | (1 << 1)); + pci_read_config_byte(agp_bridge->dev, INTEL_I845_AGPM, &temp2); + pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1)); /* clear any possible error conditions */ - pci_write_config_word(agp_bridge.dev, INTEL_I845_ERRSTS, 0x001c); + pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c); return 0; } @@ -833,26 +833,26 @@ u16 temp2; struct aper_size_info_8 *current_size; - current_size = A_SIZE_8(agp_bridge.current_size); + current_size = A_SIZE_8(agp_bridge->current_size); /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); + pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); + pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); /* mcgcfg */ - pci_read_config_word(agp_bridge.dev, INTEL_I850_MCHCFG, &temp2); - pci_write_config_word(agp_bridge.dev, INTEL_I850_MCHCFG, temp2 | (1 << 9)); + pci_read_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, &temp2); + pci_write_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, temp2 | (1 << 9)); /* clear any possible AGP-related error conditions */ - pci_write_config_word(agp_bridge.dev, INTEL_I850_ERRSTS, 0x001c); + pci_write_config_word(agp_bridge->dev, INTEL_I850_ERRSTS, 0x001c); return 0; } @@ -862,26 +862,26 @@ u16 temp2; struct aper_size_info_8 *current_size; - current_size = A_SIZE_8(agp_bridge.current_size); + current_size = A_SIZE_8(agp_bridge->current_size); /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); + pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); + pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); /* mcgcfg */ - pci_read_config_word(agp_bridge.dev, INTEL_I860_MCHCFG, &temp2); - pci_write_config_word(agp_bridge.dev, INTEL_I860_MCHCFG, temp2 | (1 << 9)); + pci_read_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, &temp2); + pci_write_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, temp2 | (1 << 9)); /* clear any possible AGP-related error conditions */ - pci_write_config_word(agp_bridge.dev, INTEL_I860_ERRSTS, 0xf700); + pci_write_config_word(agp_bridge->dev, INTEL_I860_ERRSTS, 0xf700); return 0; } @@ -891,33 +891,33 @@ u16 temp2; struct aper_size_info_8 *current_size; - current_size = A_SIZE_8(agp_bridge.current_size); + current_size = A_SIZE_8(agp_bridge->current_size); /* aperture size */ - pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); + pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ - pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); + pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); /* agpctrl */ - pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); /* gmch */ - pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2); - pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp2 | (1 << 9)); + pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2); + pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp2 | (1 << 9)); /* clear any possible AGP-related error conditions */ - pci_write_config_word(agp_bridge.dev, INTEL_I830_ERRSTS, 0x1c); + pci_write_config_word(agp_bridge->dev, INTEL_I830_ERRSTS, 0x1c); return 0; } static unsigned long intel_mask_memory(unsigned long addr, int type) { /* Memory type is ignored */ - return addr | agp_bridge.masks[0].mask; + return addr | agp_bridge->masks[0].mask; } static void intel_resume(void) @@ -969,234 +969,234 @@ static int __init intel_generic_setup (struct pci_dev *pdev) { - agp_bridge.masks = intel_generic_masks; - agp_bridge.aperture_sizes = (void *) intel_generic_sizes; - agp_bridge.size_type = U16_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = intel_configure; - agp_bridge.fetch_size = intel_fetch_size; - agp_bridge.cleanup = intel_cleanup; - agp_bridge.tlb_flush = intel_tlbflush; - agp_bridge.mask_memory = intel_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = intel_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = intel_generic_masks; + agp_bridge->aperture_sizes = (void *) intel_generic_sizes; + agp_bridge->size_type = U16_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = intel_configure; + agp_bridge->fetch_size = intel_fetch_size; + agp_bridge->cleanup = intel_cleanup; + agp_bridge->tlb_flush = intel_tlbflush; + agp_bridge->mask_memory = intel_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = intel_resume; + agp_bridge->cant_use_aperture = 0; return 0; } static int __init intel_815_setup (struct pci_dev *pdev) { - agp_bridge.masks = intel_generic_masks; - agp_bridge.aperture_sizes = (void *) intel_815_sizes; - agp_bridge.size_type = U8_APER_SIZE; - agp_bridge.num_aperture_sizes = 2; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = intel_815_configure; - agp_bridge.fetch_size = intel_8xx_fetch_size; - agp_bridge.cleanup = intel_8xx_cleanup; - agp_bridge.tlb_flush = intel_8xx_tlbflush; - agp_bridge.mask_memory = intel_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = intel_generic_masks; + agp_bridge->aperture_sizes = (void *) intel_815_sizes; + agp_bridge->size_type = U8_APER_SIZE; + agp_bridge->num_aperture_sizes = 2; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = intel_815_configure; + agp_bridge->fetch_size = intel_8xx_fetch_size; + agp_bridge->cleanup = intel_8xx_cleanup; + agp_bridge->tlb_flush = intel_8xx_tlbflush; + agp_bridge->mask_memory = intel_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return 0; } static int __init intel_820_setup (struct pci_dev *pdev) { - agp_bridge.masks = intel_generic_masks; - agp_bridge.aperture_sizes = (void *) intel_8xx_sizes; - agp_bridge.size_type = U8_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = intel_820_configure; - agp_bridge.fetch_size = intel_8xx_fetch_size; - agp_bridge.cleanup = intel_820_cleanup; - agp_bridge.tlb_flush = intel_820_tlbflush; - agp_bridge.mask_memory = intel_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = intel_generic_masks; + agp_bridge->aperture_sizes = (void *) intel_8xx_sizes; + agp_bridge->size_type = U8_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = intel_820_configure; + agp_bridge->fetch_size = intel_8xx_fetch_size; + agp_bridge->cleanup = intel_820_cleanup; + agp_bridge->tlb_flush = intel_820_tlbflush; + agp_bridge->mask_memory = intel_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return 0; } static int __init intel_830mp_setup (struct pci_dev *pdev) { - agp_bridge.masks = intel_generic_masks; - agp_bridge.aperture_sizes = (void *) intel_830mp_sizes; - agp_bridge.size_type = U8_APER_SIZE; - agp_bridge.num_aperture_sizes = 4; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = intel_830mp_configure; - agp_bridge.fetch_size = intel_8xx_fetch_size; - agp_bridge.cleanup = intel_8xx_cleanup; - agp_bridge.tlb_flush = intel_8xx_tlbflush; - agp_bridge.mask_memory = intel_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = intel_generic_masks; + agp_bridge->aperture_sizes = (void *) intel_830mp_sizes; + agp_bridge->size_type = U8_APER_SIZE; + agp_bridge->num_aperture_sizes = 4; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = intel_830mp_configure; + agp_bridge->fetch_size = intel_8xx_fetch_size; + agp_bridge->cleanup = intel_8xx_cleanup; + agp_bridge->tlb_flush = intel_8xx_tlbflush; + agp_bridge->mask_memory = intel_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return 0; } static int __init intel_840_setup (struct pci_dev *pdev) { - agp_bridge.masks = intel_generic_masks; - agp_bridge.aperture_sizes = (void *) intel_8xx_sizes; - agp_bridge.size_type = U8_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = intel_840_configure; - agp_bridge.fetch_size = intel_8xx_fetch_size; - agp_bridge.cleanup = intel_8xx_cleanup; - agp_bridge.tlb_flush = intel_8xx_tlbflush; - agp_bridge.mask_memory = intel_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = intel_generic_masks; + agp_bridge->aperture_sizes = (void *) intel_8xx_sizes; + agp_bridge->size_type = U8_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = intel_840_configure; + agp_bridge->fetch_size = intel_8xx_fetch_size; + agp_bridge->cleanup = intel_8xx_cleanup; + agp_bridge->tlb_flush = intel_8xx_tlbflush; + agp_bridge->mask_memory = intel_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return 0; } static int __init intel_845_setup (struct pci_dev *pdev) { - agp_bridge.masks = intel_generic_masks; - agp_bridge.aperture_sizes = (void *) intel_8xx_sizes; - agp_bridge.size_type = U8_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = intel_845_configure; - agp_bridge.fetch_size = intel_8xx_fetch_size; - agp_bridge.cleanup = intel_8xx_cleanup; - agp_bridge.tlb_flush = intel_8xx_tlbflush; - agp_bridge.mask_memory = intel_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = intel_845_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = intel_generic_masks; + agp_bridge->aperture_sizes = (void *) intel_8xx_sizes; + agp_bridge->size_type = U8_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = intel_845_configure; + agp_bridge->fetch_size = intel_8xx_fetch_size; + agp_bridge->cleanup = intel_8xx_cleanup; + agp_bridge->tlb_flush = intel_8xx_tlbflush; + agp_bridge->mask_memory = intel_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = intel_845_resume; + agp_bridge->cant_use_aperture = 0; return 0; } static int __init intel_850_setup (struct pci_dev *pdev) { - agp_bridge.masks = intel_generic_masks; - agp_bridge.aperture_sizes = (void *) intel_8xx_sizes; - agp_bridge.size_type = U8_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = intel_850_configure; - agp_bridge.fetch_size = intel_8xx_fetch_size; - agp_bridge.cleanup = intel_8xx_cleanup; - agp_bridge.tlb_flush = intel_8xx_tlbflush; - agp_bridge.mask_memory = intel_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = intel_generic_masks; + agp_bridge->aperture_sizes = (void *) intel_8xx_sizes; + agp_bridge->size_type = U8_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = intel_850_configure; + agp_bridge->fetch_size = intel_8xx_fetch_size; + agp_bridge->cleanup = intel_8xx_cleanup; + agp_bridge->tlb_flush = intel_8xx_tlbflush; + agp_bridge->mask_memory = intel_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return 0; } static int __init intel_860_setup (struct pci_dev *pdev) { - agp_bridge.masks = intel_generic_masks; - agp_bridge.aperture_sizes = (void *) intel_8xx_sizes; - agp_bridge.size_type = U8_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = intel_860_configure; - agp_bridge.fetch_size = intel_8xx_fetch_size; - agp_bridge.cleanup = intel_8xx_cleanup; - agp_bridge.tlb_flush = intel_8xx_tlbflush; - agp_bridge.mask_memory = intel_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = intel_generic_masks; + agp_bridge->aperture_sizes = (void *) intel_8xx_sizes; + agp_bridge->size_type = U8_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = intel_860_configure; + agp_bridge->fetch_size = intel_8xx_fetch_size; + agp_bridge->cleanup = intel_8xx_cleanup; + agp_bridge->tlb_flush = intel_8xx_tlbflush; + agp_bridge->mask_memory = intel_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return 0; } @@ -1287,7 +1287,7 @@ if (pdev->device == devs[j].device_id) { printk (KERN_INFO PFX "Detected Intel %s chipset\n", devs[j].chipset_name); - agp_bridge.type = devs[j].chipset; + agp_bridge->type = devs[j].chipset; if (devs[j].chipset_setup != NULL) return devs[j].chipset_setup(pdev); @@ -1302,7 +1302,7 @@ if (agp_try_unsupported) { printk(KERN_WARNING PFX "Trying generic Intel routines" " for device id: %04x\n", pdev->device); - agp_bridge.type = INTEL_GENERIC; + agp_bridge->type = INTEL_GENERIC; return intel_generic_setup(pdev); } @@ -1319,7 +1319,7 @@ struct pci_dev *i810_dev; u8 cap_ptr = 0; - agp_bridge.dev = dev; + agp_bridge->dev = dev; /* This shit needs moving into tables/init-routines. */ switch (dev->device) { @@ -1331,7 +1331,7 @@ return -ENODEV; } printk(KERN_INFO PFX "Detected an Intel i810 Chipset.\n"); - agp_bridge.type = INTEL_I810; + agp_bridge->type = INTEL_I810; return intel_i810_setup (i810_dev); case PCI_DEVICE_ID_INTEL_82810_MC3: @@ -1342,7 +1342,7 @@ return -ENODEV; } printk(KERN_INFO PFX "Detected an Intel i810 DC100 Chipset.\n"); - agp_bridge.type = INTEL_I810; + agp_bridge->type = INTEL_I810; return intel_i810_setup(i810_dev); case PCI_DEVICE_ID_INTEL_82810E_MC: @@ -1353,7 +1353,7 @@ return -ENODEV; } printk(KERN_INFO PFX "Detected an Intel i810 E Chipset.\n"); - agp_bridge.type = INTEL_I810; + agp_bridge->type = INTEL_I810; return intel_i810_setup(i810_dev); case PCI_DEVICE_ID_INTEL_82815_MC: @@ -1371,7 +1371,7 @@ break; } printk(KERN_INFO PFX "agpgart: Detected an Intel i815 Chipset.\n"); - agp_bridge.type = INTEL_I810; + agp_bridge->type = INTEL_I810; return intel_i810_setup(i810_dev); case PCI_DEVICE_ID_INTEL_82845G_HB: @@ -1387,11 +1387,11 @@ * We probably have a I845MP chipset with an external graphics * card. It will be initialized later */ - agp_bridge.type = INTEL_I845_G; + agp_bridge->type = INTEL_I845_G; break; } printk(KERN_INFO PFX "Detected an Intel 845G Chipset.\n"); - agp_bridge.type = INTEL_I810; + agp_bridge->type = INTEL_I810; return intel_i830_setup(i810_dev); case PCI_DEVICE_ID_INTEL_82830_HB: @@ -1402,11 +1402,11 @@ if (i810_dev == NULL) { /* Intel 830MP with external graphic card */ /* It will be initialized later */ - agp_bridge.type = INTEL_I830_M; + agp_bridge->type = INTEL_I830_M; break; } printk(KERN_INFO PFX "Detected an Intel 830M Chipset.\n"); - agp_bridge.type = INTEL_I810; + agp_bridge->type = INTEL_I810; return intel_i830_setup(i810_dev); default: @@ -1416,10 +1416,10 @@ cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); if (cap_ptr == 0) return -ENODEV; - agp_bridge.capndx = cap_ptr; + agp_bridge->capndx = cap_ptr; /* Fill in the mode register */ - pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode); + pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode); /* probe for known chipsets */ return agp_lookup_host_bridge(dev); @@ -1472,7 +1472,7 @@ ret_val = pci_module_init(&agp_intel_pci_driver); if (ret_val) - agp_bridge.type = NOT_SUPPORTED; + agp_bridge->type = NOT_SUPPORTED; return ret_val; } diff -Nru a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c --- a/drivers/char/agp/sis-agp.c Fri Feb 14 00:27:26 2003 +++ b/drivers/char/agp/sis-agp.c Fri Feb 14 00:27:26 2003 @@ -16,16 +16,16 @@ int i; struct aper_size_info_8 *values; - pci_read_config_byte(agp_bridge.dev, SIS_APSIZE, &temp_size); - values = A_SIZE_8(agp_bridge.aperture_sizes); - for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + pci_read_config_byte(agp_bridge->dev, SIS_APSIZE, &temp_size); + values = A_SIZE_8(agp_bridge->aperture_sizes); + for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { if ((temp_size == values[i].size_value) || ((temp_size & ~(0x03)) == (values[i].size_value & ~(0x03)))) { - agp_bridge.previous_size = - agp_bridge.current_size = (void *) (values + i); + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + i); - agp_bridge.aperture_size_idx = i; + agp_bridge->aperture_size_idx = i; return values[i].size; } } @@ -35,7 +35,7 @@ static void sis_tlbflush(agp_memory * mem) { - pci_write_config_byte(agp_bridge.dev, SIS_TLBFLUSH, 0x02); + pci_write_config_byte(agp_bridge->dev, SIS_TLBFLUSH, 0x02); } static int sis_configure(void) @@ -43,13 +43,13 @@ u32 temp; struct aper_size_info_8 *current_size; - current_size = A_SIZE_8(agp_bridge.current_size); - pci_write_config_byte(agp_bridge.dev, SIS_TLBCNTRL, 0x05); - pci_read_config_dword(agp_bridge.dev, SIS_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); - pci_write_config_dword(agp_bridge.dev, SIS_ATTBASE, - agp_bridge.gatt_bus_addr); - pci_write_config_byte(agp_bridge.dev, SIS_APSIZE, + current_size = A_SIZE_8(agp_bridge->current_size); + pci_write_config_byte(agp_bridge->dev, SIS_TLBCNTRL, 0x05); + pci_read_config_dword(agp_bridge->dev, SIS_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_write_config_dword(agp_bridge->dev, SIS_ATTBASE, + agp_bridge->gatt_bus_addr); + pci_write_config_byte(agp_bridge->dev, SIS_APSIZE, current_size->size_value); return 0; } @@ -58,8 +58,8 @@ { struct aper_size_info_8 *previous_size; - previous_size = A_SIZE_8(agp_bridge.previous_size); - pci_write_config_byte(agp_bridge.dev, SIS_APSIZE, + previous_size = A_SIZE_8(agp_bridge->previous_size); + pci_write_config_byte(agp_bridge->dev, SIS_APSIZE, (previous_size->size_value & ~(0x03))); } @@ -67,7 +67,7 @@ { /* Memory type is ignored */ - return addr | agp_bridge.masks[0].mask; + return addr | agp_bridge->masks[0].mask; } static struct aper_size_info_8 sis_generic_sizes[7] = @@ -88,30 +88,30 @@ static int __init sis_generic_setup (struct pci_dev *pdev) { - agp_bridge.masks = sis_generic_masks; - agp_bridge.aperture_sizes = (void *) sis_generic_sizes; - agp_bridge.size_type = U8_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = sis_configure; - agp_bridge.fetch_size = sis_fetch_size; - agp_bridge.cleanup = sis_cleanup; - agp_bridge.tlb_flush = sis_tlbflush; - agp_bridge.mask_memory = sis_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = sis_generic_masks; + agp_bridge->aperture_sizes = (void *) sis_generic_sizes; + agp_bridge->size_type = U8_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = sis_configure; + agp_bridge->fetch_size = sis_fetch_size; + agp_bridge->cleanup = sis_cleanup; + agp_bridge->tlb_flush = sis_tlbflush; + agp_bridge->mask_memory = sis_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return 0; } @@ -198,7 +198,7 @@ if (pdev->device == devs[j].device_id) { printk (KERN_INFO PFX "Detected SiS %s chipset\n", devs[j].chipset_name); - agp_bridge.type = devs[j].chipset; + agp_bridge->type = devs[j].chipset; if (devs[j].chipset_setup != NULL) return devs[j].chipset_setup(pdev); @@ -212,7 +212,7 @@ if (agp_try_unsupported) { printk(KERN_WARNING PFX "Trying generic SiS routines" " for device id: %04x\n", pdev->device); - agp_bridge.type = SIS_GENERIC; + agp_bridge->type = SIS_GENERIC; return sis_generic_setup(pdev); } @@ -235,10 +235,10 @@ /* probe for known chipsets */ if (agp_lookup_host_bridge(dev) != -ENODEV) { - agp_bridge.dev = dev; - agp_bridge.capndx = cap_ptr; + agp_bridge->dev = dev; + agp_bridge->capndx = cap_ptr; /* Fill in the mode register */ - pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode); + pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode); sis_agp_driver.dev = dev; agp_register_driver(&sis_agp_driver); return 0; @@ -272,7 +272,7 @@ ret_val = pci_module_init(&agp_sis_pci_driver); if (ret_val) - agp_bridge.type = NOT_SUPPORTED; + agp_bridge->type = NOT_SUPPORTED; return ret_val; } diff -Nru a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c --- a/drivers/char/agp/sworks-agp.c Fri Feb 14 00:27:27 2003 +++ b/drivers/char/agp/sworks-agp.c Fri Feb 14 00:27:27 2003 @@ -47,7 +47,7 @@ CACHE_FLUSH(); for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) { - page_map->remapped[i] = agp_bridge.scratch_page; + page_map->remapped[i] = agp_bridge->scratch_page; } return 0; @@ -120,7 +120,7 @@ #ifndef GET_PAGE_DIR_IDX #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \ - GET_PAGE_DIR_OFF(agp_bridge.gart_bus_addr)) + GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr)) #endif #ifndef GET_GATT_OFF @@ -135,7 +135,7 @@ u32 temp; int i; - value = A_SIZE_LVL2(agp_bridge.current_size); + value = A_SIZE_LVL2(agp_bridge->current_size); retval = serverworks_create_page_map(&page_dir); if (retval != 0) { return retval; @@ -147,7 +147,7 @@ } /* Create a fake scratch directory */ for(i = 0; i < 1024; i++) { - serverworks_private.scratch_dir.remapped[i] = (unsigned long) agp_bridge.scratch_page; + serverworks_private.scratch_dir.remapped[i] = (unsigned long) agp_bridge->scratch_page; page_dir.remapped[i] = virt_to_phys(serverworks_private.scratch_dir.real); page_dir.remapped[i] |= 0x00000001; @@ -160,17 +160,17 @@ return retval; } - agp_bridge.gatt_table_real = (u32 *)page_dir.real; - agp_bridge.gatt_table = (u32 *)page_dir.remapped; - agp_bridge.gatt_bus_addr = virt_to_phys(page_dir.real); + agp_bridge->gatt_table_real = (u32 *)page_dir.real; + agp_bridge->gatt_table = (u32 *)page_dir.remapped; + agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); /* Get the address for the gart region. * This is a bus address even on the alpha, b/c its * used to program the agp master not the cpu */ - pci_read_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,&temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* Calculate the agp offset */ @@ -187,8 +187,8 @@ { struct serverworks_page_map page_dir; - page_dir.real = (unsigned long *)agp_bridge.gatt_table_real; - page_dir.remapped = (unsigned long *)agp_bridge.gatt_table; + page_dir.real = (unsigned long *)agp_bridge->gatt_table_real; + page_dir.remapped = (unsigned long *)agp_bridge->gatt_table; serverworks_free_gatt_pages(); serverworks_free_page_map(&page_dir); @@ -203,20 +203,20 @@ u32 temp2; struct aper_size_info_lvl2 *values; - values = A_SIZE_LVL2(agp_bridge.aperture_sizes); - pci_read_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,&temp); - pci_write_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs, + values = A_SIZE_LVL2(agp_bridge->aperture_sizes); + pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp); + pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs, SVWRKS_SIZE_MASK); - pci_read_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,&temp2); - pci_write_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,temp); + pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp2); + pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,temp); temp2 &= SVWRKS_SIZE_MASK; - for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { if (temp2 == values[i].size_value) { - agp_bridge.previous_size = - agp_bridge.current_size = (void *) (values + i); + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + i); - agp_bridge.aperture_size_idx = i; + agp_bridge->aperture_size_idx = i; return values[i].size; } } @@ -231,17 +231,17 @@ u8 enable_reg; u16 cap_reg; - current_size = A_SIZE_LVL2(agp_bridge.current_size); + current_size = A_SIZE_LVL2(agp_bridge->current_size); /* Get the memory mapped registers */ - pci_read_config_dword(agp_bridge.dev, serverworks_private.mm_addr_ofs, &temp); + pci_read_config_dword(agp_bridge->dev, serverworks_private.mm_addr_ofs, &temp); temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); serverworks_private.registers = (volatile u8 *) ioremap(temp, 4096); OUTREG8(serverworks_private.registers, SVWRKS_GART_CACHE, 0x0a); OUTREG32(serverworks_private.registers, SVWRKS_GATTBASE, - agp_bridge.gatt_bus_addr); + agp_bridge->gatt_bus_addr); cap_reg = INREG16(serverworks_private.registers, SVWRKS_COMMAND); cap_reg &= ~0x0007; @@ -253,21 +253,21 @@ enable_reg |= 0x1; /* Agp Enable bit */ pci_write_config_byte(serverworks_private.svrwrks_dev, SVWRKS_AGP_ENABLE, enable_reg); - agp_bridge.tlb_flush(NULL); + agp_bridge->tlb_flush(NULL); - agp_bridge.capndx = pci_find_capability(serverworks_private.svrwrks_dev, PCI_CAP_ID_AGP); + agp_bridge->capndx = pci_find_capability(serverworks_private.svrwrks_dev, PCI_CAP_ID_AGP); /* Fill in the mode register */ pci_read_config_dword(serverworks_private.svrwrks_dev, - agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode); + agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode); - pci_read_config_byte(agp_bridge.dev, SVWRKS_CACHING, &enable_reg); + pci_read_config_byte(agp_bridge->dev, SVWRKS_CACHING, &enable_reg); enable_reg &= ~0x3; - pci_write_config_byte(agp_bridge.dev, SVWRKS_CACHING, enable_reg); + pci_write_config_byte(agp_bridge->dev, SVWRKS_CACHING, enable_reg); - pci_read_config_byte(agp_bridge.dev, SVWRKS_FEATURE, &enable_reg); + pci_read_config_byte(agp_bridge->dev, SVWRKS_FEATURE, &enable_reg); enable_reg |= (1<<6); - pci_write_config_byte(agp_bridge.dev,SVWRKS_FEATURE, enable_reg); + pci_write_config_byte(agp_bridge->dev,SVWRKS_FEATURE, enable_reg); return 0; } @@ -313,7 +313,7 @@ { /* Only type 0 is supported by the serverworks chipsets */ - return addr | agp_bridge.masks[0].mask; + return addr | agp_bridge->masks[0].mask; } static int serverworks_insert_memory(agp_memory * mem, @@ -323,7 +323,7 @@ unsigned long *cur_gatt; unsigned long addr; - num_entries = A_SIZE_LVL2(agp_bridge.current_size)->num_entries; + num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries; if (type != 0 || mem->type != 0) { return -EINVAL; @@ -334,7 +334,7 @@ j = pg_start; while (j < (pg_start + mem->page_count)) { - addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr; + addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; cur_gatt = SVRWRKS_GET_GATT(addr); if (!PGE_EMPTY(cur_gatt[GET_GATT_OFF(addr)])) { return -EBUSY; @@ -348,12 +348,12 @@ } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { - addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr; + addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; cur_gatt = SVRWRKS_GET_GATT(addr); cur_gatt[GET_GATT_OFF(addr)] = - agp_bridge.mask_memory(mem->memory[i], mem->type); + agp_bridge->mask_memory(mem->memory[i], mem->type); } - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return 0; } @@ -369,16 +369,16 @@ } CACHE_FLUSH(); - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); for (i = pg_start; i < (mem->page_count + pg_start); i++) { - addr = (i * PAGE_SIZE) + agp_bridge.gart_bus_addr; + addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; cur_gatt = SVRWRKS_GET_GATT(addr); cur_gatt[GET_GATT_OFF(addr)] = - (unsigned long) agp_bridge.scratch_page; + (unsigned long) agp_bridge->scratch_page; } - agp_bridge.tlb_flush(mem); + agp_bridge->tlb_flush(mem); return 0; } @@ -403,7 +403,7 @@ u32 command; pci_read_config_dword(serverworks_private.svrwrks_dev, - agp_bridge.capndx + PCI_AGP_STATUS, + agp_bridge->capndx + PCI_AGP_STATUS, &command); command = agp_collect_device_status(mode, command); @@ -414,7 +414,7 @@ command |= 0x100; pci_write_config_dword(serverworks_private.svrwrks_dev, - agp_bridge.capndx + PCI_AGP_COMMAND, + agp_bridge->capndx + PCI_AGP_COMMAND, command); agp_device_command(command, 0); @@ -427,39 +427,39 @@ serverworks_private.svrwrks_dev = pdev; - agp_bridge.masks = serverworks_masks; - agp_bridge.aperture_sizes = (void *) serverworks_sizes; - agp_bridge.size_type = LVL2_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = (void *) &serverworks_private; - agp_bridge.needs_scratch_page = TRUE; - agp_bridge.configure = serverworks_configure; - agp_bridge.fetch_size = serverworks_fetch_size; - agp_bridge.cleanup = serverworks_cleanup; - agp_bridge.tlb_flush = serverworks_tlbflush; - agp_bridge.mask_memory = serverworks_mask_memory; - agp_bridge.agp_enable = serverworks_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = serverworks_create_gatt_table; - agp_bridge.free_gatt_table = serverworks_free_gatt_table; - agp_bridge.insert_memory = serverworks_insert_memory; - agp_bridge.remove_memory = serverworks_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; + agp_bridge->masks = serverworks_masks; + agp_bridge->aperture_sizes = (void *) serverworks_sizes; + agp_bridge->size_type = LVL2_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = (void *) &serverworks_private; + agp_bridge->needs_scratch_page = TRUE; + agp_bridge->configure = serverworks_configure; + agp_bridge->fetch_size = serverworks_fetch_size; + agp_bridge->cleanup = serverworks_cleanup; + agp_bridge->tlb_flush = serverworks_tlbflush; + agp_bridge->mask_memory = serverworks_mask_memory; + agp_bridge->agp_enable = serverworks_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = serverworks_create_gatt_table; + agp_bridge->free_gatt_table = serverworks_free_gatt_table; + agp_bridge->insert_memory = serverworks_insert_memory; + agp_bridge->remove_memory = serverworks_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; - pci_read_config_dword(agp_bridge.dev, + pci_read_config_dword(agp_bridge->dev, SVWRKS_APSIZE, &temp); serverworks_private.gart_addr_ofs = 0x10; if(temp & PCI_BASE_ADDRESS_MEM_TYPE_64) { - pci_read_config_dword(agp_bridge.dev, + pci_read_config_dword(agp_bridge->dev, SVWRKS_APSIZE + 4, &temp2); if(temp2 != 0) { @@ -472,11 +472,11 @@ serverworks_private.mm_addr_ofs = 0x14; } - pci_read_config_dword(agp_bridge.dev, + pci_read_config_dword(agp_bridge->dev, serverworks_private.mm_addr_ofs, &temp); if(temp & PCI_BASE_ADDRESS_MEM_TYPE_64) { - pci_read_config_dword(agp_bridge.dev, + pci_read_config_dword(agp_bridge->dev, serverworks_private.mm_addr_ofs + 4, &temp2); if(temp2 != 0) { @@ -503,21 +503,21 @@ return -ENODEV; } - agp_bridge.dev = dev; + agp_bridge->dev = dev; switch (dev->device) { case PCI_DEVICE_ID_SERVERWORKS_HE: - agp_bridge.type = SVWRKS_HE; + agp_bridge->type = SVWRKS_HE; return serverworks_setup(bridge_dev); case PCI_DEVICE_ID_SERVERWORKS_LE: case 0x0007: - agp_bridge.type = SVWRKS_LE; + agp_bridge->type = SVWRKS_LE; return serverworks_setup(bridge_dev); default: if(agp_try_unsupported) { - agp_bridge.type = SVWRKS_GENERIC; + agp_bridge->type = SVWRKS_GENERIC; return serverworks_setup(bridge_dev); } break; @@ -565,7 +565,7 @@ ret_val = pci_module_init(&agp_serverworks_pci_driver); if (ret_val) - agp_bridge.type = NOT_SUPPORTED; + agp_bridge->type = NOT_SUPPORTED; return ret_val; } diff -Nru a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c --- a/drivers/char/agp/via-agp.c Fri Feb 14 00:27:29 2003 +++ b/drivers/char/agp/via-agp.c Fri Feb 14 00:27:29 2003 @@ -11,73 +11,78 @@ static int agp_try_unsupported __initdata = 0; + static int via_fetch_size(void) { int i; u8 temp; struct aper_size_info_8 *values; - values = A_SIZE_8(agp_bridge.aperture_sizes); - pci_read_config_byte(agp_bridge.dev, VIA_APSIZE, &temp); - for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + values = A_SIZE_8(agp_bridge->aperture_sizes); + pci_read_config_byte(agp_bridge->dev, VIA_APSIZE, &temp); + for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { if (temp == values[i].size_value) { - agp_bridge.previous_size = - agp_bridge.current_size = (void *) (values + i); - agp_bridge.aperture_size_idx = i; + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + i); + agp_bridge->aperture_size_idx = i; return values[i].size; } } - return 0; } + static int via_configure(void) { u32 temp; struct aper_size_info_8 *current_size; - current_size = A_SIZE_8(agp_bridge.current_size); + current_size = A_SIZE_8(agp_bridge->current_size); /* aperture size */ - pci_write_config_byte(agp_bridge.dev, VIA_APSIZE, + pci_write_config_byte(agp_bridge->dev, VIA_APSIZE, current_size->size_value); /* address to map too */ - pci_read_config_dword(agp_bridge.dev, VIA_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(agp_bridge->dev, VIA_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* GART control register */ - pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000000f); + pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000000f); /* attbase - aperture GATT base */ - pci_write_config_dword(agp_bridge.dev, VIA_ATTBASE, - (agp_bridge.gatt_bus_addr & 0xfffff000) | 3); + pci_write_config_dword(agp_bridge->dev, VIA_ATTBASE, + (agp_bridge->gatt_bus_addr & 0xfffff000) | 3); return 0; } + static void via_cleanup(void) { struct aper_size_info_8 *previous_size; - previous_size = A_SIZE_8(agp_bridge.previous_size); - pci_write_config_byte(agp_bridge.dev, VIA_APSIZE, + previous_size = A_SIZE_8(agp_bridge->previous_size); + pci_write_config_byte(agp_bridge->dev, VIA_APSIZE, previous_size->size_value); /* Do not disable by writing 0 to VIA_ATTBASE, it screws things up * during reinitialization. */ } + static void via_tlbflush(agp_memory * mem) { - pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000008f); - pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000000f); + pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000008f); + pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000000f); } + static unsigned long via_mask_memory(unsigned long addr, int type) { /* Memory type is ignored */ - return addr | agp_bridge.masks[0].mask; + return addr | agp_bridge->masks[0].mask; } + static struct aper_size_info_8 via_generic_sizes[7] = { {256, 65536, 6, 0}, @@ -89,123 +94,327 @@ {4, 1024, 0, 252} }; + static struct gatt_mask via_generic_masks[] = { {.mask = 0x00000000, .type = 0} }; + +#ifdef CONFIG_AGP3 +static int via_fetch_size_agp3(void) +{ + int i; + u16 temp; + struct aper_size_info_16 *values; + + values = A_SIZE_16(agp_bridge->aperture_sizes); + pci_read_config_word(agp_bridge->dev, VIA_AGP3_APSIZE, &temp); + temp &= 0xfff; + + for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { + if (temp == values[i].size_value) { + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + i); + agp_bridge->aperture_size_idx = i; + return values[i].size; + } + } + return 0; +} + + +static int via_configure_agp3(void) +{ + u32 temp; + struct aper_size_info_16 *current_size; + + current_size = A_SIZE_16(agp_bridge->current_size); + + /* address to map too */ + pci_read_config_dword(agp_bridge->dev, VIA_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* attbase - aperture GATT base */ + pci_write_config_dword(agp_bridge->dev, VIA_AGP3_ATTBASE, + agp_bridge->gatt_bus_addr & 0xfffff000); + return 0; +} + + +static void via_cleanup_agp3(void) +{ + struct aper_size_info_16 *previous_size; + + previous_size = A_SIZE_16(agp_bridge->previous_size); + pci_write_config_byte(agp_bridge->dev, VIA_APSIZE, previous_size->size_value); +} + + +static void via_tlbflush_agp3(agp_memory * mem) +{ + u32 temp; + + pci_read_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, &temp); + pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp & ~(1<<7)); + pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp); +} + + +static struct aper_size_info_16 via_generic_agp3_sizes[11] = +{ + { 4, 1024, 0, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3|1<<2|1<<1|1<<0 }, + { 8, 2048, 1, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3|1<<2|1<<1}, + { 16, 4096, 2, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3|1<<2}, + { 32, 8192, 3, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3}, + { 64, 16384, 4, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4}, + { 128, 32768, 5, 1<<11|1<<10|1<<9|1<<8|1<<5}, + { 256, 65536, 6, 1<<11|1<<10|1<<9|1<<8}, + { 512, 131072, 7, 1<<11|1<<10|1<<9}, + { 1024, 262144, 8, 1<<11|1<<10}, + { 2048, 524288, 9, 1<<11} /* 2GB <- Max supported */ +}; + + +static int __init via_generic_agp3_setup (struct pci_dev *pdev) +{ + agp_bridge->dev = pdev; + agp_bridge->type = VIA_GENERIC; + agp_bridge->masks = via_generic_masks; + agp_bridge->aperture_sizes = (void *) via_generic_agp3_sizes; + agp_bridge->size_type = U16_APER_SIZE; + agp_bridge->num_aperture_sizes = 10; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->agp_enable = agp_generic_agp_3_0_enable; + agp_bridge->configure = via_configure_agp3; + agp_bridge->fetch_size = via_fetch_size_agp3; + agp_bridge->cleanup = via_cleanup_agp3; + agp_bridge->tlb_flush = via_tlbflush_agp3; + agp_bridge->mask_memory = via_mask_memory; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; + return 0; +} +#else +static int __init via_generic_agp3_setup (struct pci_dev *pdev) +{ + printk (KERN_INFO PFX "Bridge in AGP3 mode, but CONFIG_AGP3=n\n"); + return -ENODEV; +} +#endif /* CONFIG_AGP3 */ + + static int __init via_generic_setup (struct pci_dev *pdev) { - agp_bridge.masks = via_generic_masks; - agp_bridge.aperture_sizes = (void *) via_generic_sizes; - agp_bridge.size_type = U8_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = via_configure; - agp_bridge.fetch_size = via_fetch_size; - agp_bridge.cleanup = via_cleanup; - agp_bridge.tlb_flush = via_tlbflush; - agp_bridge.mask_memory = via_mask_memory; - agp_bridge.agp_enable = agp_generic_agp_enable; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; +#ifdef CONFIG_AGP3 + /* Garg, there are KT400s with KT266 IDs. */ + if (pdev->device == PCI_DEVICE_ID_VIA_8367_0) { + + /* Is there a KT400 subsystem ? */ + if (pdev->subsystem_device==PCI_DEVICE_ID_VIA_8377_0) { + u8 reg; + + printk (KERN_INFO PFX "Found KT400 in disguise as a KT266.\n"); + + /* Check AGP compatability mode. */ + pci_read_config_byte(pdev, VIA_AGPSEL, ®); + if ((reg & (1<<1))==0) + return via_generic_agp3_setup(pdev); + + /* Its in 2.0 mode, drop through. */ + } + } +#endif + + agp_bridge->masks = via_generic_masks; + agp_bridge->aperture_sizes = (void *) via_generic_sizes; + agp_bridge->size_type = U8_APER_SIZE; + agp_bridge->num_aperture_sizes = 7; + agp_bridge->dev_private_data = NULL; + agp_bridge->needs_scratch_page = FALSE; + agp_bridge->configure = via_configure; + agp_bridge->fetch_size = via_fetch_size; + agp_bridge->cleanup = via_cleanup; + agp_bridge->tlb_flush = via_tlbflush; + agp_bridge->mask_memory = via_mask_memory; + agp_bridge->agp_enable = agp_generic_agp_enable; + agp_bridge->cache_flush = global_cache_flush; + agp_bridge->create_gatt_table = agp_generic_create_gatt_table; + agp_bridge->free_gatt_table = agp_generic_free_gatt_table; + agp_bridge->insert_memory = agp_generic_insert_memory; + agp_bridge->remove_memory = agp_generic_remove_memory; + agp_bridge->alloc_by_type = agp_generic_alloc_by_type; + agp_bridge->free_by_type = agp_generic_free_by_type; + agp_bridge->agp_alloc_page = agp_generic_alloc_page; + agp_bridge->agp_destroy_page = agp_generic_destroy_page; + agp_bridge->suspend = agp_generic_suspend; + agp_bridge->resume = agp_generic_resume; + agp_bridge->cant_use_aperture = 0; return 0; } -/* - * The KT400 does magick to put the AGP bridge compliant with the same - * standards version as the graphics card. If we haven't fallen into - * 2.0 compatability mode, we abort, as this gets picked up by - * via-agp3.o - */ +/* The KT400 does magick to put the AGP bridge compliant with the same + * standards version as the graphics card. */ static int __init via_kt400_setup(struct pci_dev *pdev) { u8 reg; pci_read_config_byte(pdev, VIA_AGPSEL, ®); /* Check AGP 2.0 compatability mode. */ - if ((reg & (1<<1))==1) { - via_generic_setup(pdev); - return 0; - } - return -ENODEV; + if ((reg & (1<<1))==0) + return via_generic_agp3_setup(pdev); + return via_generic_setup(pdev); } + static struct agp_device_ids via_agp_device_ids[] __initdata = { { .device_id = PCI_DEVICE_ID_VIA_82C597_0, - .chipset = VIA_VP3, .chipset_name = "VP3", }, + { .device_id = PCI_DEVICE_ID_VIA_82C598_0, - .chipset = VIA_MVP3, .chipset_name = "MVP3", }, + { .device_id = PCI_DEVICE_ID_VIA_8501_0, - .chipset = VIA_MVP4, .chipset_name = "MVP4", }, + + /* VT8601 */ + { + .device_id = PCI_DEVICE_ID_VIA_8601_0, + .chipset_name = "PLE133 ProMedia", + }, + + /* VT82C693A / VT28C694T */ { .device_id = PCI_DEVICE_ID_VIA_82C691, - .chipset = VIA_APOLLO_PRO, - .chipset_name = "Apollo Pro", + .chipset_name = "Apollo Pro 133", }, + { .device_id = PCI_DEVICE_ID_VIA_8371_0, - .chipset = VIA_APOLLO_KX133, .chipset_name = "Apollo Pro KX133", }, + + /* VT8633 */ { .device_id = PCI_DEVICE_ID_VIA_8633_0, - .chipset = VIA_APOLLO_PRO_266, .chipset_name = "Apollo Pro 266", }, + + /* VT8361 */ +/* { + .device_id = PCI_DEVICE_ID_VIA_8361, // 0x3112 + .chipset_name = "Apollo KLE133", + }, */ + + /* VT8365 / VT8362 */ { .device_id = PCI_DEVICE_ID_VIA_8363_0, - .chipset = VIA_APOLLO_KT133, - .chipset_name = "Apollo Pro KT133", + .chipset_name = "Apollo Pro KT133/KM133/TwisterK", }, + + /* VT8753A */ +/* { + .device_id = PCI_DEVICE_ID_VIA_8753_0, // 0x3128 + .chipset_name = "P4X266", + }, */ + + /* VT8366 */ { .device_id = PCI_DEVICE_ID_VIA_8367_0, - .chipset = VIA_APOLLO_KT133, - .chipset_name = "Apollo Pro KT266", + .chipset_name = "Apollo Pro KT266/KT333", }, + + /* VT8633 (for CuMine/ Celeron) */ { .device_id = PCI_DEVICE_ID_VIA_8653_0, - .chipset = VIA_APOLLO_PRO, .chipset_name = "Apollo Pro 266T", }, + + /* KM266 / PM266 */ +/* { + .device_id = PCI_DEVICE_ID_VIA_KM266, // 0x3116 + .chipset_name = "KM266/PM266", + }, */ + + /* CLE266 */ +/* { + .device_id = PCI_DEVICE_ID_VIA_CLE266, // 0x3123 + .chipset_name = "CLE266", + }, */ + { .device_id = PCI_DEVICE_ID_VIA_8377_0, - .chipset = VIA_APOLLO_KT400, .chipset_name = "Apollo Pro KT400", .chipset_setup = via_kt400_setup, }, + + /* VT8604 / VT8605 / VT8603 / TwisterT + * (Apollo Pro133A chipset with S3 Savage4) */ { - /* VIA ProSavage PM133 (Apollo Pro133A chipset with S3 Savage4) */ .device_id = PCI_DEVICE_ID_VIA_82C694X_0, - .chipset = VIA_VT8605, - .chipset_name = "Apollo ProSavage PM133" + .chipset_name = "Apollo ProSavage PM133/PL133/PN133/Twister" }, + + /* VT8752*/ +/* { + .device_id = PCI_DEVICE_ID_VIA_8752, // 0x3148 + .chipset_name = "ProSavage DDR P4M266", + }, */ + + /* KN266/PN266 */ +/* { + .device_id = PCI_DEVICE_ID_KN266, // 0x3156 + .chipset_name = "KN266/PN266", + }, */ + + /* VT8754 */ { .device_id = PCI_DEVICE_ID_VIA_8754, - .chipset = VIA_P4X, .chipset_name = "Apollo P4X333/P4X400" }, + + /* P4N333 */ +/* { + .device_id = PCI_DEVICE_ID_VIA_P4N333, // 0x3178 + .chipset_name = "P4N333", + }, */ + + /* P4X600 */ +/* { + .device_id = PCI_DEVICE_ID_VIA_P4X600, // 0x0198 + .chipset_name = "P4X600", + }, */ + + /* KM400 */ +/* { + .device_id = PCI_DEVICE_ID_VIA_KM400, // 0x3205 + .chipset_name = "KM400", + }, */ + + /* P4M400 */ +/* { + .device_id = PCI_DEVICE_ID_VIA_P4M400, // 0x3209 + .chipset_name = "PM400", + }, */ + { }, /* dummy final entry, always present */ }; @@ -221,7 +430,7 @@ while (devs[j].chipset_name != NULL) { if (pdev->device == devs[j].device_id) { printk (KERN_INFO PFX "Detected VIA %s chipset\n", devs[j].chipset_name); - agp_bridge.type = devs[j].chipset; + agp_bridge->type = VIA_GENERIC; if (devs[j].chipset_setup != NULL) return devs[j].chipset_setup(pdev); @@ -235,7 +444,7 @@ if (agp_try_unsupported) { printk(KERN_WARNING PFX "Trying generic VIA routines" " for device id: %04x\n", pdev->device); - agp_bridge.type = VIA_GENERIC; + agp_bridge->type = VIA_GENERIC; return via_generic_setup(pdev); } @@ -244,10 +453,12 @@ return -ENODEV; } + static struct agp_driver via_agp_driver = { .owner = THIS_MODULE, }; + static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent) { u8 cap_ptr = 0; @@ -258,10 +469,10 @@ /* probe for known chipsets */ if (agp_lookup_host_bridge (dev) != -ENODEV) { - agp_bridge.dev = dev; - agp_bridge.capndx = cap_ptr; + agp_bridge->dev = dev; + agp_bridge->capndx = cap_ptr; /* Fill in the mode register */ - pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode); + pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode); via_agp_driver.dev = dev; agp_register_driver(&via_agp_driver); return 0; @@ -269,6 +480,7 @@ return -ENODEV; } + static struct pci_device_id agp_via_pci_table[] __initdata = { { .class = (PCI_CLASS_BRIDGE_HOST << 8), @@ -283,31 +495,36 @@ MODULE_DEVICE_TABLE(pci, agp_via_pci_table); + static struct __initdata pci_driver agp_via_pci_driver = { .name = "agpgart-via", .id_table = agp_via_pci_table, .probe = agp_via_probe, }; + static int __init agp_via_init(void) { int ret_val; ret_val = pci_module_init(&agp_via_pci_driver); if (ret_val) - agp_bridge.type = NOT_SUPPORTED; + agp_bridge->type = NOT_SUPPORTED; return ret_val; } + static void __exit agp_via_cleanup(void) { agp_unregister_driver(&via_agp_driver); pci_unregister_driver(&agp_via_pci_driver); } + module_init(agp_via_init); module_exit(agp_via_cleanup); MODULE_PARM(agp_try_unsupported, "1i"); MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Dave Jones "); diff -Nru a/drivers/char/agp/via-kt400.c b/drivers/char/agp/via-kt400.c --- a/drivers/char/agp/via-kt400.c Fri Feb 14 00:27:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,202 +0,0 @@ -/* - * VIA KT400 AGPGART routines. - * - * The KT400 does magick to put the AGP bridge compliant with the same - * standards version as the graphics card. If we haven't fallen into - * 2.0 compatability mode, we run this code. Otherwise, we run the - * code in via-agp.c - */ - -#include -#include -#include -#include -#include -#include "agp.h" - -static int via_fetch_size(void) -{ - int i; - u8 temp; - struct aper_size_info_16 *values; - - values = A_SIZE_16(agp_bridge.aperture_sizes); - pci_read_config_byte(agp_bridge.dev, VIA_AGP3_APSIZE, &temp); - for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { - if (temp == values[i].size_value) { - agp_bridge.previous_size = - agp_bridge.current_size = (void *) (values + i); - agp_bridge.aperture_size_idx = i; - return values[i].size; - } - } - return 0; -} - -static int via_configure(void) -{ - u32 temp; - struct aper_size_info_16 *current_size; - - current_size = A_SIZE_16(agp_bridge.current_size); - - /* address to map too */ - pci_read_config_dword(agp_bridge.dev, VIA_APBASE, &temp); - agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); - - /* attbase - aperture GATT base */ - pci_write_config_dword(agp_bridge.dev, VIA_AGP3_ATTBASE, - agp_bridge.gatt_bus_addr & 0xfffff000); - return 0; -} - -static void via_cleanup(void) -{ - struct aper_size_info_16 *previous_size; - - previous_size = A_SIZE_16(agp_bridge.previous_size); - pci_write_config_byte(agp_bridge.dev, VIA_APSIZE, previous_size->size_value); -} - -static void via_tlbflush(agp_memory * mem) -{ - u32 temp; - - pci_read_config_dword(agp_bridge.dev, VIA_AGP3_GARTCTRL, &temp); - pci_write_config_dword(agp_bridge.dev, VIA_AGP3_GARTCTRL, temp & ~(1<<7)); - pci_write_config_dword(agp_bridge.dev, VIA_AGP3_GARTCTRL, temp); -} - -static unsigned long via_mask_memory(unsigned long addr, int type) -{ - /* Memory type is ignored */ - - return addr | agp_bridge.masks[0].mask; -} - -static struct aper_size_info_16 via_generic_sizes[11] = -{ - { 4, 1024, 0, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3|1<<2|1<<1|1<<0 }, - { 8, 2048, 1, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3|1<<2|1<<1}, - { 16, 4096, 2, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3|1<<2}, - { 32, 8192, 3, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3}, - { 64, 16384, 4, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4}, - { 128, 32768, 5, 1<<11|1<<10|1<<9|1<<8|1<<5}, - { 256, 65536, 6, 1<<11|1<<10|1<<9|1<<8}, - { 512, 131072, 7, 1<<11|1<<10|1<<9}, - { 1024, 262144, 8, 1<<11|1<<10}, - { 2048, 524288, 9, 1<<11} /* 2GB <- Max supported */ -}; - -static struct gatt_mask via_generic_masks[] = -{ - {.mask = 0x00000000, .type = 0} -}; - - -static void __init via_kt400_enable(u32 mode) -{ - if ((agp_generic_agp_3_0_enable(mode))==FALSE) - printk (KERN_INFO PFX "agp_generic_agp_3_0_enable() failed\n"); -} - -static struct agp_driver via_kt400_agp_driver = { - .owner = THIS_MODULE, -}; - -static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent) -{ - u8 reg; - u8 cap_ptr = 0; - - cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); - if (cap_ptr == 0) - return -ENODEV; - - pci_read_config_byte(dev, VIA_AGPSEL, ®); - /* Check if we are in AGP 2.0 compatability mode, if so it - * will be picked up by via-agp.o */ - if ((reg & (1<<1))==1) - return -ENODEV; - - printk (KERN_INFO PFX "Detected VIA KT400 AGP3 chipset\n"); - - agp_bridge.dev = dev; - agp_bridge.type = VIA_APOLLO_KT400_3; - agp_bridge.capndx = cap_ptr; - agp_bridge.masks = via_generic_masks; - agp_bridge.aperture_sizes = (void *) via_generic_sizes; - agp_bridge.size_type = U8_APER_SIZE; - agp_bridge.num_aperture_sizes = 7; - agp_bridge.dev_private_data = NULL; - agp_bridge.needs_scratch_page = FALSE; - agp_bridge.agp_enable = via_kt400_enable; - agp_bridge.configure = via_configure; - agp_bridge.fetch_size = via_fetch_size; - agp_bridge.cleanup = via_cleanup; - agp_bridge.tlb_flush = via_tlbflush; - agp_bridge.mask_memory = via_mask_memory; - agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = agp_generic_create_gatt_table; - agp_bridge.free_gatt_table = agp_generic_free_gatt_table; - agp_bridge.insert_memory = agp_generic_insert_memory; - agp_bridge.remove_memory = agp_generic_remove_memory; - agp_bridge.alloc_by_type = agp_generic_alloc_by_type; - agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = agp_generic_alloc_page; - agp_bridge.agp_destroy_page = agp_generic_destroy_page; - agp_bridge.suspend = agp_generic_suspend; - agp_bridge.resume = agp_generic_resume; - agp_bridge.cant_use_aperture = 0; - - /* Fill in the mode register */ - pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode); - - via_kt400_agp_driver.dev = dev; - agp_register_driver(&via_kt400_agp_driver); - return 0; -} - -static struct pci_device_id agp_via_pci_table[] __initdata = { - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_VIA, - .device = PCI_DEVICE_ID_VIA_8377_0, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { } -}; - -MODULE_DEVICE_TABLE(pci, agp_via_pci_table); - -static struct __initdata pci_driver agp_via_pci_driver = { - .name = "agpgart-via", - .id_table = agp_via_pci_table, - .probe = agp_via_probe, -}; - -static int __init agp_via_init(void) -{ - int ret_val; - - ret_val = pci_module_init(&agp_via_pci_driver); - if (ret_val) - agp_bridge.type = NOT_SUPPORTED; - - return ret_val; -} - -static void __exit agp_via_cleanup(void) -{ - agp_unregister_driver(&via_kt400_agp_driver); - pci_unregister_driver(&agp_via_pci_driver); -} - -module_init(agp_via_init); -module_exit(agp_via_cleanup); - -MODULE_AUTHOR("Dave Jones "); -MODULE_LICENSE("GPL and additional rights"); - diff -Nru a/drivers/char/ec3104_keyb.c b/drivers/char/ec3104_keyb.c --- a/drivers/char/ec3104_keyb.c Fri Feb 14 00:27:28 2003 +++ b/drivers/char/ec3104_keyb.c Fri Feb 14 00:27:28 2003 @@ -376,8 +376,6 @@ struct e5_struct *k = &ec3104_keyb; u8 msr, lsr; - kbd_pt_regs = regs; - msr = ctrl_inb(EC3104_SER4_MSR); if ((msr & MSR_CTS) && !(k->last_msr & MSR_CTS)) { diff -Nru a/drivers/char/ftape/lowlevel/ftape-read.c b/drivers/char/ftape/lowlevel/ftape-read.c --- a/drivers/char/ftape/lowlevel/ftape-read.c Fri Feb 14 00:27:26 2003 +++ b/drivers/char/ftape/lowlevel/ftape-read.c Fri Feb 14 00:27:26 2003 @@ -589,6 +589,8 @@ (max_floppy_track != 254 || max_floppy_sector != 128)) #endif ) { + char segperheadz = ftape_segments_per_head ? ' ' : '?'; + char segpercylz = ftape_segments_per_cylinder ? ' ' : '?'; TRACE(ft_t_err,"Tape parameters inconsistency, please report"); TRACE(ft_t_err, "reported = %d/%d/%d/%d/%d/%d", ft_format_code, @@ -597,14 +599,20 @@ max_floppy_side, max_floppy_track, max_floppy_sector); - TRACE(ft_t_err, "required = %d/%d/%d/%d/%d/%d", + TRACE(ft_t_err, "required = %d/%d/%d/%d%c/%d%c/%d", ft_format_code, ft_segments_per_track, ft_tracks_per_tape, + ftape_segments_per_head ? ((ft_segments_per_track * ft_tracks_per_tape -1) / - ftape_segments_per_head ), + ftape_segments_per_head ) : + (ft_segments_per_track * ft_tracks_per_tape -1), + segperheadz, + ftape_segments_per_cylinder ? (ftape_segments_per_head / - ftape_segments_per_cylinder - 1 ), + ftape_segments_per_cylinder - 1 ) : + ftape_segments_per_head - 1, + segpercylz, (ftape_segments_per_cylinder * FT_SECTORS_PER_SEGMENT)); TRACE_EXIT -EIO; } diff -Nru a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c --- a/drivers/char/hvc_console.c Fri Feb 14 00:27:29 2003 +++ b/drivers/char/hvc_console.c Fri Feb 14 00:27:29 2003 @@ -233,9 +233,7 @@ { int i; - daemonize(); - strcpy(current->comm, "khvcd"); - sigfillset(¤t->blocked); + daemonize("khvcd"); for (;;) { if (!cpus_in_xmon) { diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c --- a/drivers/char/keyboard.c Fri Feb 14 00:27:28 2003 +++ b/drivers/char/keyboard.c Fri Feb 14 00:27:28 2003 @@ -48,24 +48,22 @@ * Exported functions/variables */ -#ifndef KBD_DEFMODE #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META)) -#endif -#ifndef KBD_DEFLEDS /* * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on. - * This seems a good reason to start with NumLock off. + * This seems a good reason to start with NumLock off. On PC9800 however there + * is no NumLock key and everyone expects the keypad to be used for numbers. */ + +#ifdef CONFIG_X86_PC9800 +#define KBD_DEFLEDS (1 << VC_NUMLOCK) +#else #define KBD_DEFLEDS 0 #endif -#ifndef KBD_DEFLOCK #define KBD_DEFLOCK 0 -#endif -struct pt_regs *kbd_pt_regs; -EXPORT_SYMBOL(kbd_pt_regs); void compute_shiftstate(void); /* @@ -79,7 +77,7 @@ k_slock, k_dead2, k_ignore, k_ignore typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value, - char up_flag); + char up_flag, struct pt_regs *regs); static k_handler_fn K_HANDLERS; static k_handler_fn *k_handler[16] = { K_HANDLERS }; @@ -90,7 +88,7 @@ fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\ fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num -typedef void (fn_handler_fn)(struct vc_data *vc); +typedef void (fn_handler_fn)(struct vc_data *vc, struct pt_regs *regs); static fn_handler_fn FN_HANDLERS; static fn_handler_fn *fn_handler[] = { FN_HANDLERS }; @@ -422,7 +420,7 @@ /* * Special function handlers */ -static void fn_enter(struct vc_data *vc) +static void fn_enter(struct vc_data *vc, struct pt_regs *regs) { if (diacr) { put_queue(vc, diacr); @@ -433,27 +431,27 @@ put_queue(vc, 10); } -static void fn_caps_toggle(struct vc_data *vc) +static void fn_caps_toggle(struct vc_data *vc, struct pt_regs *regs) { if (rep) return; chg_vc_kbd_led(kbd, VC_CAPSLOCK); } -static void fn_caps_on(struct vc_data *vc) +static void fn_caps_on(struct vc_data *vc, struct pt_regs *regs) { if (rep) return; set_vc_kbd_led(kbd, VC_CAPSLOCK); } -static void fn_show_ptregs(struct vc_data *vc) +static void fn_show_ptregs(struct vc_data *vc, struct pt_regs *regs) { - if (kbd_pt_regs) - show_regs(kbd_pt_regs); + if (regs) + show_regs(regs); } -static void fn_hold(struct vc_data *vc) +static void fn_hold(struct vc_data *vc, struct pt_regs *regs) { struct tty_struct *tty = vc->vc_tty; @@ -471,12 +469,12 @@ stop_tty(tty); } -static void fn_num(struct vc_data *vc) +static void fn_num(struct vc_data *vc, struct pt_regs *regs) { if (vc_kbd_mode(kbd,VC_APPLIC)) applkey(vc, 'P', 1); else - fn_bare_num(vc); + fn_bare_num(vc, regs); } /* @@ -485,19 +483,19 @@ * Bind this to NumLock if you prefer that the NumLock key always * changes the NumLock flag. */ -static void fn_bare_num(struct vc_data *vc) +static void fn_bare_num(struct vc_data *vc, struct pt_regs *regs) { if (!rep) chg_vc_kbd_led(kbd, VC_NUMLOCK); } -static void fn_lastcons(struct vc_data *vc) +static void fn_lastcons(struct vc_data *vc, struct pt_regs *regs) { /* switch to the last used console, ChN */ set_console(last_console); } -static void fn_dec_console(struct vc_data *vc) +static void fn_dec_console(struct vc_data *vc, struct pt_regs *regs) { int i; @@ -510,7 +508,7 @@ set_console(i); } -static void fn_inc_console(struct vc_data *vc) +static void fn_inc_console(struct vc_data *vc, struct pt_regs *regs) { int i; @@ -523,7 +521,7 @@ set_console(i); } -static void fn_send_intr(struct vc_data *vc) +static void fn_send_intr(struct vc_data *vc, struct pt_regs *regs) { struct tty_struct *tty = vc->vc_tty; @@ -533,44 +531,44 @@ con_schedule_flip(tty); } -static void fn_scroll_forw(struct vc_data *vc) +static void fn_scroll_forw(struct vc_data *vc, struct pt_regs *regs) { scrollfront(0); } -static void fn_scroll_back(struct vc_data *vc) +static void fn_scroll_back(struct vc_data *vc, struct pt_regs *regs) { scrollback(0); } -static void fn_show_mem(struct vc_data *vc) +static void fn_show_mem(struct vc_data *vc, struct pt_regs *regs) { show_mem(); } -static void fn_show_state(struct vc_data *vc) +static void fn_show_state(struct vc_data *vc, struct pt_regs *regs) { show_state(); } -static void fn_boot_it(struct vc_data *vc) +static void fn_boot_it(struct vc_data *vc, struct pt_regs *regs) { ctrl_alt_del(); } -static void fn_compose(struct vc_data *vc) +static void fn_compose(struct vc_data *vc, struct pt_regs *regs) { dead_key_next = 1; } -static void fn_spawn_con(struct vc_data *vc) +static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs) { if (spawnpid) if(kill_proc(spawnpid, spawnsig, 1)) spawnpid = 0; } -static void fn_SAK(struct vc_data *vc) +static void fn_SAK(struct vc_data *vc, struct pt_regs *regs) { struct tty_struct *tty = vc->vc_tty; @@ -583,7 +581,7 @@ reset_vc(fg_console); } -static void fn_null(struct vc_data *vc) +static void fn_null(struct vc_data *vc, struct pt_regs *regs) { compute_shiftstate(); } @@ -591,11 +589,11 @@ /* * Special key handlers */ -static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag) +static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { } -static void k_spec(struct vc_data *vc, unsigned char value, char up_flag) +static void k_spec(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { if (up_flag) return; @@ -605,15 +603,15 @@ kbd->kbdmode == VC_MEDIUMRAW) && value != K_SAK) return; /* SAK is allowed even in raw mode */ - fn_handler[value](vc); + fn_handler[value](vc, regs); } -static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag) +static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { printk(KERN_ERR "keyboard.c: k_lowercase was called - impossible\n"); } -static void k_self(struct vc_data *vc, unsigned char value, char up_flag) +static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { if (up_flag) return; /* no action, if this is a key release */ @@ -634,7 +632,7 @@ * dead keys modifying the same character. Very useful * for Vietnamese. */ -static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) +static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { if (up_flag) return; @@ -644,21 +642,21 @@ /* * Obsolete - for backwards compatibility only */ -static void k_dead(struct vc_data *vc, unsigned char value, char up_flag) +static void k_dead(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { static unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' }; value = ret_diacr[value]; - k_dead2(vc, value, up_flag); + k_dead2(vc, value, up_flag, regs); } -static void k_cons(struct vc_data *vc, unsigned char value, char up_flag) +static void k_cons(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { if (up_flag) return; set_console(value); } -static void k_fn(struct vc_data *vc, unsigned char value, char up_flag) +static void k_fn(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { if (up_flag) return; @@ -669,7 +667,7 @@ printk(KERN_ERR "k_fn called with value=%d\n", value); } -static void k_cur(struct vc_data *vc, unsigned char value, char up_flag) +static void k_cur(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { static const char *cur_chars = "BDCA"; @@ -678,7 +676,7 @@ applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE)); } -static void k_pad(struct vc_data *vc, unsigned char value, char up_flag) +static void k_pad(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { static const char *pad_chars = "0123456789+-*/\015,.?()#"; static const char *app_map = "pqrstuvwxylSRQMnnmPQS"; @@ -696,34 +694,34 @@ switch (value) { case KVAL(K_PCOMMA): case KVAL(K_PDOT): - k_fn(vc, KVAL(K_REMOVE), 0); + k_fn(vc, KVAL(K_REMOVE), 0, regs); return; case KVAL(K_P0): - k_fn(vc, KVAL(K_INSERT), 0); + k_fn(vc, KVAL(K_INSERT), 0, regs); return; case KVAL(K_P1): - k_fn(vc, KVAL(K_SELECT), 0); + k_fn(vc, KVAL(K_SELECT), 0, regs); return; case KVAL(K_P2): - k_cur(vc, KVAL(K_DOWN), 0); + k_cur(vc, KVAL(K_DOWN), 0, regs); return; case KVAL(K_P3): - k_fn(vc, KVAL(K_PGDN), 0); + k_fn(vc, KVAL(K_PGDN), 0, regs); return; case KVAL(K_P4): - k_cur(vc, KVAL(K_LEFT), 0); + k_cur(vc, KVAL(K_LEFT), 0, regs); return; case KVAL(K_P6): - k_cur(vc, KVAL(K_RIGHT), 0); + k_cur(vc, KVAL(K_RIGHT), 0, regs); return; case KVAL(K_P7): - k_fn(vc, KVAL(K_FIND), 0); + k_fn(vc, KVAL(K_FIND), 0, regs); return; case KVAL(K_P8): - k_cur(vc, KVAL(K_UP), 0); + k_cur(vc, KVAL(K_UP), 0, regs); return; case KVAL(K_P9): - k_fn(vc, KVAL(K_PGUP), 0); + k_fn(vc, KVAL(K_PGUP), 0, regs); return; case KVAL(K_P5): applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC)); @@ -735,7 +733,7 @@ put_queue(vc, 10); } -static void k_shift(struct vc_data *vc, unsigned char value, char up_flag) +static void k_shift(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { int old_state = shift_state; @@ -776,7 +774,7 @@ } } -static void k_meta(struct vc_data *vc, unsigned char value, char up_flag) +static void k_meta(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { if (up_flag) return; @@ -788,7 +786,7 @@ put_queue(vc, value | 0x80); } -static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag) +static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { int base; @@ -810,16 +808,16 @@ npadch = npadch * base + value; } -static void k_lock(struct vc_data *vc, unsigned char value, char up_flag) +static void k_lock(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { if (up_flag || rep) return; chg_vc_kbd_lock(kbd, value); } -static void k_slock(struct vc_data *vc, unsigned char value, char up_flag) +static void k_slock(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { - k_shift(vc, value, up_flag); + k_shift(vc, value, up_flag, regs); if (up_flag || rep) return; chg_vc_kbd_slock(kbd, value); @@ -894,9 +892,9 @@ * Aside from timing (which isn't really that important for * keyboard interrupts as they happen often), using the software * interrupt routines for this thing allows us to easily mask - * this when we don't want any of the above to happen. Not yet - * used, but this allows for easy and efficient race-condition - * prevention later on. + * this when we don't want any of the above to happen. + * This allows for easy and efficient race-condition prevention + * for kbd_refresh_leds => input_event(dev, EV_LED, ...) => ... */ static void kbd_bh(unsigned long dummy) @@ -910,6 +908,7 @@ input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04)); + input_sync(handle->dev); } } @@ -918,6 +917,23 @@ DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); +/* + * This allows a newly plugged keyboard to pick the LED state. + */ +void kbd_refresh_leds(struct input_handle *handle) +{ + unsigned char leds = ledstate; + + tasklet_disable(&keyboard_tasklet); + if (leds != 0xff) { + input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); + input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); + input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04)); + input_sync(handle->dev); + } + tasklet_enable(&keyboard_tasklet); +} + #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) static unsigned short x86_keycodes[256] = @@ -996,7 +1012,7 @@ } #endif -void kbd_keycode(unsigned int keycode, int down) +void kbd_keycode(unsigned int keycode, int down, struct pt_regs *regs) { struct vc_data *vc = vc_cons[fg_console].d; unsigned short keysym, *key_map; @@ -1027,7 +1043,8 @@ if ((raw_mode = (kbd->kbdmode == VC_RAW))) if (emulate_raw(vc, keycode, !down << 7)) - printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode); + if (keycode < BTN_MISC) + printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode); #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ if (keycode == KEY_SYSRQ && !rep) { @@ -1035,7 +1052,7 @@ return; } if (sysrq_down && down && !rep) { - handle_sysrq(kbd_sysrq_xlate[keycode], kbd_pt_regs, tty); + handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty); return; } #endif @@ -1112,7 +1129,7 @@ } } - (*k_handler[type])(vc, keysym & 0xff, !down); + (*k_handler[type])(vc, keysym & 0xff, !down, regs); if (type != KT_SLOCK) kbd->slockstate = 0; @@ -1123,7 +1140,7 @@ { if (event_type != EV_KEY) return; - kbd_keycode(keycode, down); + kbd_keycode(keycode, down, handle->dev->regs); tasklet_schedule(&keyboard_tasklet); do_poke_blanked_console = 1; schedule_console_callback(); @@ -1159,6 +1176,7 @@ handle->name = kbd_name; input_open_device(handle); + kbd_refresh_leds(handle); return handle; } diff -Nru a/drivers/char/misc.c b/drivers/char/misc.c --- a/drivers/char/misc.c Fri Feb 14 00:27:30 2003 +++ b/drivers/char/misc.c Fri Feb 14 00:27:30 2003 @@ -50,8 +50,6 @@ #include #include -#include "busmouse.h" - /* * Head entry for the doubly linked miscdevice list */ @@ -64,7 +62,6 @@ #define DYNAMIC_MINORS 64 /* like dynamic majors */ static unsigned char misc_minors[DYNAMIC_MINORS / 8]; -extern int psaux_init(void); #ifdef CONFIG_SGI_NEWPORT_GFX extern void gfx_register(void); #endif diff -Nru a/drivers/char/moxa.c b/drivers/char/moxa.c --- a/drivers/char/moxa.c Fri Feb 14 00:27:30 2003 +++ b/drivers/char/moxa.c Fri Feb 14 00:27:30 2003 @@ -2832,7 +2832,7 @@ st = jiffies; et = st + tick; - while (jiffies < et); + while (time_before(jiffies, et)); } static void moxafunc(unsigned long ofsAddr, int cmd, ushort arg) diff -Nru a/drivers/char/mxser.c b/drivers/char/mxser.c --- a/drivers/char/mxser.c Fri Feb 14 00:27:29 2003 +++ b/drivers/char/mxser.c Fri Feb 14 00:27:29 2003 @@ -857,7 +857,7 @@ while (!(inb(info->base + UART_LSR) & UART_LSR_TEMT)) { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(5); - if (jiffies > timeout) + if (time_after(jiffies, timeout)) break; } } diff -Nru a/drivers/char/n_tty.c b/drivers/char/n_tty.c --- a/drivers/char/n_tty.c Fri Feb 14 00:27:26 2003 +++ b/drivers/char/n_tty.c Fri Feb 14 00:27:26 2003 @@ -23,6 +23,11 @@ * 2000/01/20 Fixed SMP locking on put_tty_queue using bits of * the patch by Andrew J. Kroll * who actually finally proved there really was a race. + * + * 2002/03/18 Implemented n_tty_wakeup to send SIGIO POLL_OUTs to + * waiting writing processes-Sapan Bhatia . + * Also fixed a bug in BLOCKING mode where write_chan returns + * EAGAIN */ #include @@ -707,6 +712,22 @@ return 0; } +/* + * Required for the ptys, serial driver etc. since processes + * that attach themselves to the master and rely on ASYNC + * IO must be woken up + */ + +static void n_tty_write_wakeup(struct tty_struct *tty) +{ + if (tty->fasync) + { + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + kill_fasync(&tty->fasync, SIGIO, POLL_OUT); + } + return; +} + static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { @@ -1156,6 +1177,8 @@ while (nr > 0) { ssize_t num = opost_block(tty, b, nr); if (num < 0) { + if (num == -EAGAIN) + break; retval = num; goto break_out; } @@ -1235,6 +1258,6 @@ normal_poll, /* poll */ n_tty_receive_buf, /* receive_buf */ n_tty_receive_room, /* receive_room */ - 0 /* write_wakeup */ + n_tty_write_wakeup /* write_wakeup */ }; diff -Nru a/drivers/char/nvram.c b/drivers/char/nvram.c --- a/drivers/char/nvram.c Fri Feb 14 00:27:28 2003 +++ b/drivers/char/nvram.c Fri Feb 14 00:27:28 2003 @@ -231,8 +231,7 @@ * The are the file operation function for user access to /dev/nvram */ -static long long -nvram_llseek(struct file *file, loff_t offset, int origin) +static loff_t nvram_llseek(struct file *file,loff_t offset, int origin ) { lock_kernel(); switch (origin) { diff -Nru a/drivers/char/nwflash.c b/drivers/char/nwflash.c --- a/drivers/char/nwflash.c Fri Feb 14 00:27:30 2003 +++ b/drivers/char/nwflash.c Fri Feb 14 00:27:30 2003 @@ -47,7 +47,7 @@ static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg); static ssize_t flash_read(struct file *file, char *buf, size_t count, loff_t * ppos); static ssize_t flash_write(struct file *file, const char *buf, size_t count, loff_t * ppos); -static long long flash_llseek(struct file *file, long long offset, int orig); +static loff_t flash_llseek(struct file *file, loff_t offset, int orig); #define KFLASH_SIZE 1024*1024 //1 Meg #define KFLASH_SIZE4 4*1024*1024 //4 Meg @@ -301,9 +301,9 @@ * also note that seeking relative to the "end of file" isn't supported: * it has no meaning, so it returns -EINVAL. */ -static long long flash_llseek(struct file *file, long long offset, int orig) +static loff_t flash_llseek(struct file *file, loff_t offset, int orig) { - long long ret; + loff_t ret; lock_kernel(); if (flashdebug) diff -Nru a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c --- a/drivers/char/rio/rioroute.c Fri Feb 14 00:27:28 2003 +++ b/drivers/char/rio/rioroute.c Fri Feb 14 00:27:28 2003 @@ -763,7 +763,7 @@ #endif UnitId--; /* this trick relies on the Unit Id being UNSIGNED! */ - if ( UnitId > MAX_RUP ) /* dontcha just lurv unsigned maths! */ + if ( UnitId >= MAX_RUP ) /* dontcha just lurv unsigned maths! */ return(0); if ( HostP->Mapping[UnitId].Flags & BEEN_HERE ) diff -Nru a/drivers/char/riscom8.c b/drivers/char/riscom8.c --- a/drivers/char/riscom8.c Fri Feb 14 00:27:28 2003 +++ b/drivers/char/riscom8.c Fri Feb 14 00:27:28 2003 @@ -1090,7 +1090,7 @@ unsigned long flags; board = RC_BOARD(minor(tty->device)); - if (board > RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT)) + if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT)) return -ENODEV; bp = &rc_board[board]; diff -Nru a/drivers/char/specialix.c b/drivers/char/specialix.c --- a/drivers/char/specialix.c Fri Feb 14 00:27:30 2003 +++ b/drivers/char/specialix.c Fri Feb 14 00:27:30 2003 @@ -1456,7 +1456,7 @@ board = SX_BOARD(minor(tty->device)); - if (board > SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) + if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) return -ENODEV; bp = &sx_board[board]; @@ -2363,7 +2363,7 @@ struct pci_dev *pdev = NULL; i=0; - while (i <= SX_NBOARD) { + while (i < SX_NBOARD) { if (sx_board[i].flags & SX_BOARD_PRESENT) { i++; continue; diff -Nru a/drivers/char/sx.c b/drivers/char/sx.c --- a/drivers/char/sx.c Fri Feb 14 00:27:28 2003 +++ b/drivers/char/sx.c Fri Feb 14 00:27:28 2003 @@ -1689,7 +1689,7 @@ switch (cmd) { case SXIO_SET_BOARD: sx_dprintk (SX_DEBUG_FIRMWARE, "set board to %ld\n", arg); - if (arg > SX_NBOARDS) return -EIO; + if (arg >= SX_NBOARDS) return -EIO; sx_dprintk (SX_DEBUG_FIRMWARE, "not out of range\n"); if (!(boards[arg].flags & SX_BOARD_PRESENT)) return -EIO; sx_dprintk (SX_DEBUG_FIRMWARE, ".. and present!\n"); diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c --- a/drivers/char/tty_io.c Fri Feb 14 00:27:28 2003 +++ b/drivers/char/tty_io.c Fri Feb 14 00:27:28 2003 @@ -578,7 +578,7 @@ */ void disassociate_ctty(int on_exit) { - struct tty_struct *tty = current->tty; + struct tty_struct *tty; struct task_struct *p; struct list_head *l; struct pid *pid; @@ -586,6 +586,7 @@ lock_kernel(); + tty = current->tty; if (tty) { tty_pgrp = tty->pgrp; if (on_exit && tty->driver.type != TTY_DRIVER_TYPE_PTY) diff -Nru a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig --- a/drivers/char/watchdog/Kconfig Fri Feb 14 00:27:29 2003 +++ b/drivers/char/watchdog/Kconfig Fri Feb 14 00:27:29 2003 @@ -354,4 +354,14 @@ Documentation/modules.txt. The module will be called wafer5823wdt.o +config CPU5_WDT + tristate "SMA CPU5 Watchdog" + depends on WATCHDOG + ---help--- + TBD. + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module is called cpu5wdt.o. If you want to compile it as a + module, say M here and read . + endmenu diff -Nru a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile --- a/drivers/char/watchdog/Makefile Fri Feb 14 00:27:29 2003 +++ b/drivers/char/watchdog/Makefile Fri Feb 14 00:27:29 2003 @@ -29,3 +29,4 @@ obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o +obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o diff -Nru a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c --- a/drivers/char/watchdog/acquirewdt.c Fri Feb 14 00:27:29 2003 +++ b/drivers/char/watchdog/acquirewdt.c Fri Feb 14 00:27:29 2003 @@ -220,7 +220,7 @@ static int __init acq_init(void) { - printk("WDT driver for Acquire single board computer initialising.\n"); + printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n"); spin_lock_init(&acq_lock); if (misc_register(&acq_miscdev)) diff -Nru a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c --- a/drivers/char/watchdog/alim7101_wdt.c Fri Feb 14 00:27:29 2003 +++ b/drivers/char/watchdog/alim7101_wdt.c Fri Feb 14 00:27:29 2003 @@ -100,7 +100,7 @@ pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); } else { - printk(OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n"); + printk(KERN_INFO OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n"); } /* Re-set the timer interval */ timer.expires = jiffies + WDT_INTERVAL; @@ -136,7 +136,7 @@ add_timer(&timer); - printk(OUR_NAME ": Watchdog timer is now enabled.\n"); + printk(KERN_INFO OUR_NAME ": Watchdog timer is now enabled.\n"); } static void wdt_turnoff(void) @@ -144,7 +144,7 @@ /* Stop the timer */ del_timer_sync(&timer); wdt_change(WDT_DISABLE); - printk(OUR_NAME ": Watchdog timer is now disabled...\n"); + printk(KERN_INFO OUR_NAME ": Watchdog timer is now disabled...\n"); } /* @@ -203,7 +203,7 @@ if(wdt_expect_close) wdt_turnoff(); else - printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n"); + printk(KERN_INFO OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n"); clear_bit(0, &wdt_is_open); return 0; @@ -262,7 +262,7 @@ * reboot with no heartbeat */ wdt_change(WDT_ENABLE); - printk(OUR_NAME ": Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); + printk(KERN_INFO OUR_NAME ": Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); } return NOTIFY_DONE; } diff -Nru a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/char/watchdog/cpu5wdt.c Fri Feb 14 00:27:30 2003 @@ -0,0 +1,312 @@ +/* + * sma cpu5 watchdog driver + * + * Copyright (C) 2003 Heiko Ronsdorf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* adjustable parameters */ + +static int verbose = 0; +static int port = 0x91; +static volatile int ticks = 10000; + +#define PFX "cpu5wdt: " + +#define CPU5WDT_EXTENT 0x0A + +#define CPU5WDT_STATUS_REG 0x00 +#define CPU5WDT_TIME_A_REG 0x02 +#define CPU5WDT_TIME_B_REG 0x03 +#define CPU5WDT_MODE_REG 0x04 +#define CPU5WDT_TRIGGER_REG 0x07 +#define CPU5WDT_ENABLE_REG 0x08 +#define CPU5WDT_RESET_REG 0x09 + +#define CPU5WDT_INTERVAL (HZ/10+1) + +/* some device data */ + +static struct { + struct semaphore stop; + volatile int running; + struct timer_list timer; + volatile int queue; + int default_ticks; + int min_ticks; + unsigned long inuse; +} cpu5wdt_device; + +/* generic helper functions */ + +static void cpu5wdt_trigger(unsigned long unused) +{ + if ( verbose > 2 ) + printk(KERN_DEBUG PFX "trigger at %i ticks\n", ticks); + + if( cpu5wdt_device.running ) + ticks--; + + /* keep watchdog alive */ + outb(1, port + CPU5WDT_TRIGGER_REG); + + /* requeue?? */ + if( cpu5wdt_device.queue && ticks ) { + cpu5wdt_device.timer.expires = jiffies + CPU5WDT_INTERVAL; + add_timer(&cpu5wdt_device.timer); + } + else { + /* ticks doesn't matter anyway */ + up(&cpu5wdt_device.stop); + } + +} + +static void cpu5wdt_reset(void) +{ + if ( ticks < cpu5wdt_device.min_ticks ) + cpu5wdt_device.min_ticks = ticks; + + ticks = cpu5wdt_device.default_ticks; + + if ( verbose ) + printk(KERN_DEBUG PFX "reset (%i ticks)\n", (int) ticks); + +} + +static void cpu5wdt_start(void) +{ + if ( !cpu5wdt_device.queue ) { + cpu5wdt_device.queue = 1; + outb(0, port + CPU5WDT_TIME_A_REG); + outb(0, port + CPU5WDT_TIME_B_REG); + outb(1, port + CPU5WDT_MODE_REG); + outb(0, port + CPU5WDT_RESET_REG); + outb(0, port + CPU5WDT_ENABLE_REG); + cpu5wdt_device.timer.expires = jiffies + CPU5WDT_INTERVAL; + add_timer(&cpu5wdt_device.timer); + } + /* if process dies, counter is not decremented */ + cpu5wdt_device.running++; +} + +static int cpu5wdt_stop(void) +{ + if ( cpu5wdt_device.running ) + cpu5wdt_device.running = 0; + + ticks = cpu5wdt_device.default_ticks; + + if ( verbose ) + printk(KERN_CRIT PFX "stop not possible\n"); + + return -EIO; +} + +/* filesystem operations */ + +static int cpu5wdt_open(struct inode *inode, struct file *file) +{ + switch(minor(inode->i_rdev)) { + case WATCHDOG_MINOR: + if ( test_and_set_bit(0, &cpu5wdt_device.inuse) ) + return -EBUSY; + break; + default: + return -ENODEV; + } + return 0; + +} + +static int cpu5wdt_release(struct inode *inode, struct file *file) +{ + if(minor(inode->i_rdev)==WATCHDOG_MINOR) { + clear_bit(0, &cpu5wdt_device.inuse); + } + return 0; +} + +static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + unsigned int value; + static struct watchdog_info ident = + { + .options = WDIOF_CARDRESET, + .identity = "CPU5 WDT" + }; + + switch(cmd) { + case WDIOC_KEEPALIVE: + cpu5wdt_reset(); + break; + case WDIOC_GETSTATUS: + value = inb(port + CPU5WDT_STATUS_REG); + value = (value >> 2) & 1; + if ( copy_to_user((int *)arg, (int *)&value, sizeof(int)) ) + return -EFAULT; + break; + case WDIOC_GETSUPPORT: + if ( copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) ) + return -EFAULT; + break; + case WDIOC_SETOPTIONS: + if ( copy_from_user(&value, (int *)arg, sizeof(int)) ) + return -EFAULT; + switch(value) { + case WDIOS_ENABLECARD: + cpu5wdt_start(); + break; + case WDIOS_DISABLECARD: + return cpu5wdt_stop(); + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + return 0; +} + +static ssize_t cpu5wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +{ + if ( !count ) + return -EIO; + + cpu5wdt_reset(); + return count; + +} + +static struct file_operations cpu5wdt_fops = { + .owner = THIS_MODULE, + .ioctl = cpu5wdt_ioctl, + .open = cpu5wdt_open, + .write = cpu5wdt_write, + .release = cpu5wdt_release, +}; + +static struct miscdevice cpu5wdt_misc = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &cpu5wdt_fops +}; + +/* init/exit function */ + +static int __devinit cpu5wdt_init(void) +{ + unsigned int val; + int err; + + if ( verbose ) + printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose); + + if ( (err = misc_register(&cpu5wdt_misc)) < 0 ) { + printk(KERN_ERR PFX "misc_register failed\n"); + goto no_misc; + } + + if ( !request_region(port, CPU5WDT_EXTENT, PFX) ) { + printk(KERN_ERR PFX "request_region failed\n"); + err = -EBUSY; + goto no_port; + } + + /* watchdog reboot? */ + val = inb(port + CPU5WDT_STATUS_REG); + val = (val >> 2) & 1; + if ( !val ) + printk(KERN_INFO PFX "sorry, was my fault\n"); + + init_MUTEX_LOCKED(&cpu5wdt_device.stop); + cpu5wdt_device.queue = 0; + cpu5wdt_device.min_ticks = ticks; + + clear_bit(0, &cpu5wdt_device.inuse); + + init_timer(&cpu5wdt_device.timer); + cpu5wdt_device.timer.function = cpu5wdt_trigger; + cpu5wdt_device.timer.data = 0; + + cpu5wdt_device.default_ticks = ticks; + + printk(KERN_INFO PFX "init success\n"); + + return 0; + +no_port: + misc_deregister(&cpu5wdt_misc); +no_misc: + return err; +} + +static int __devinit cpu5wdt_init_module(void) +{ + return cpu5wdt_init(); +} + +static void __devexit cpu5wdt_exit(void) +{ + if ( cpu5wdt_device.queue ) { + cpu5wdt_device.queue = 0; + down(&cpu5wdt_device.stop); + } + + misc_deregister(&cpu5wdt_misc); + + release_region(port, CPU5WDT_EXTENT); + +} + +static void __devexit cpu5wdt_exit_module(void) +{ + cpu5wdt_exit(); +} + +/* module entry points */ + +module_init(cpu5wdt_init_module); +module_exit(cpu5wdt_exit_module); + +MODULE_AUTHOR("Heiko Ronsdorf "); +MODULE_DESCRIPTION("sma cpu5 watchdog driver"); +MODULE_SUPPORTED_DEVICE("sma cpu5 watchdog"); +MODULE_LICENSE("GPL"); + +MODULE_PARM(port, "i"); +MODULE_PARM_DESC(port, "base address of watchdog card, default is 0x91"); + +MODULE_PARM(verbose, "i"); +MODULE_PARM_DESC(verbose, "be verbose, default is 0 (no)"); + +MODULE_PARM(ticks, "i"); +MODULE_PARM_DESC(ticks, "count down ticks, default is 10000"); diff -Nru a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c --- a/drivers/char/watchdog/machzwd.c Fri Feb 14 00:27:27 2003 +++ b/drivers/char/watchdog/machzwd.c Fri Feb 14 00:27:27 2003 @@ -453,9 +453,9 @@ }; static struct miscdevice zf_miscdev = { - WATCHDOG_MINOR, - "watchdog", - &zf_fops + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &zf_fops }; @@ -464,9 +464,9 @@ * turn the timebomb registers off. */ static struct notifier_block zf_notifier = { - zf_notify_sys, - NULL, - 0 + .notifier_call = zf_notify_sys, + .next = NULL, + .priority = 0 }; static void __init zf_show_action(int act) diff -Nru a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c --- a/drivers/char/watchdog/pcwd.c Fri Feb 14 00:27:27 2003 +++ b/drivers/char/watchdog/pcwd.c Fri Feb 14 00:27:27 2003 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -197,28 +198,30 @@ if (revision == PCWD_REVISION_A) { if (card_status & WD_WDRST) - printk("pcwd: Previous reboot was caused by the card.\n"); + printk(KERN_INFO "pcwd: Previous reboot was caused by the card.\n"); if (card_status & WD_T110) { - printk("pcwd: Card senses a CPU Overheat. Panicking!\n"); - panic("pcwd: CPU Overheat.\n"); + printk(KERN_EMERG "pcwd: Card senses a CPU Overheat. Panicking!\n"); + printk(KERN_EMERG "pcwd: CPU Overheat.\n"); + machine_power_off(); } if ((!(card_status & WD_WDRST)) && (!(card_status & WD_T110))) - printk("pcwd: Cold boot sense.\n"); + printk(KERN_INFO "pcwd: Cold boot sense.\n"); } else { if (card_status & 0x01) - printk("pcwd: Previous reboot was caused by the card.\n"); + printk(KERN_INFO "pcwd: Previous reboot was caused by the card.\n"); if (card_status & 0x04) { - printk("pcwd: Card senses a CPU Overheat. Panicking!\n"); - panic("pcwd: CPU Overheat.\n"); + printk(KERN_EMERG "pcwd: Card senses a CPU Overheat. Panicking!\n"); + printk(KERN_EMERG "pcwd: CPU Overheat.\n"); + machine_power_off(); } if ((!(card_status & 0x01)) && (!(card_status & 0x04))) - printk("pcwd: Cold boot sense.\n"); + printk(KERN_INFO "pcwd: Cold boot sense.\n"); } } @@ -275,8 +278,10 @@ { rv |= WDIOF_OVERHEAT; - if (temp_panic) - panic("pcwd: Temperature overheat trip!\n"); + if (temp_panic) { + printk (KERN_INFO "pcwd: Temperature overheat trip!\n"); + machine_power_off(); + } } } else @@ -288,8 +293,10 @@ { rv |= WDIOF_OVERHEAT; - if (temp_panic) - panic("pcwd: Temperature overheat trip!\n"); + if (temp_panic) { + printk (KERN_INFO "pcwd: Temperature overheat trip!\n"); + machine_power_off(); + } } } @@ -350,7 +357,7 @@ spin_unlock(&io_lock); if ((cdat & 0x10) == 0) { - printk("pcwd: Could not disable card.\n"); + printk(KERN_INFO "pcwd: Could not disable card.\n"); return -EIO; } @@ -365,7 +372,7 @@ spin_unlock(&io_lock); if (cdat & 0x10) { - printk("pcwd: Could not enable card.\n"); + printk(KERN_INFO "pcwd: Could not enable card.\n"); return -EIO; } return 0; @@ -592,7 +599,7 @@ revision = PCWD_REVISION_A; - printk("pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER); + printk(KERN_INFO "pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER); /* Initial variables */ supports_temp = 0; @@ -611,7 +618,7 @@ } if (!found) { - printk("pcwd: No card detected, or port not available.\n"); + printk(KERN_INFO "pcwd: No card detected, or port not available.\n"); return(-EIO); } #endif @@ -624,9 +631,9 @@ revision = get_revision(); if (revision == PCWD_REVISION_A) - printk("pcwd: PC Watchdog (REV.A) detected at port 0x%03x\n", current_readport); + printk(KERN_INFO "pcwd: PC Watchdog (REV.A) detected at port 0x%03x\n", current_readport); else if (revision == PCWD_REVISION_C) - printk("pcwd: PC Watchdog (REV.C) detected at port 0x%03x (Firmware version: %s)\n", + printk(KERN_INFO "pcwd: PC Watchdog (REV.C) detected at port 0x%03x (Firmware version: %s)\n", current_readport, get_firmware()); else { /* Should NEVER happen, unless get_revision() fails. */ @@ -635,7 +642,7 @@ } if (supports_temp) - printk("pcwd: Temperature Option Detected.\n"); + printk(KERN_INFO "pcwd: Temperature Option Detected.\n"); debug_off(); diff -Nru a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c --- a/drivers/char/watchdog/sbc60xxwdt.c Fri Feb 14 00:27:29 2003 +++ b/drivers/char/watchdog/sbc60xxwdt.c Fri Feb 14 00:27:29 2003 @@ -267,9 +267,9 @@ }; static struct miscdevice wdt_miscdev = { - WATCHDOG_MINOR, - "watchdog", - &wdt_fops + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &wdt_fops }; /* @@ -291,9 +291,9 @@ static struct notifier_block wdt_notifier= { - wdt_notify_sys, - 0, - 0 + .notifier_call = wdt_notify_sys, + .next = NULL, + .priority = 0 }; static void __exit sbc60xxwdt_unload(void) diff -Nru a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c --- a/drivers/char/watchdog/sc1200wdt.c Fri Feb 14 00:27:27 2003 +++ b/drivers/char/watchdog/sc1200wdt.c Fri Feb 14 00:27:27 2003 @@ -23,6 +23,7 @@ * Add WDIOC_GETBOOTSTATUS and WDIOC_SETOPTIONS ioctls * Fix CONFIG_WATCHDOG_NOWAYOUT * 20020530 Joel Becker Add Matt Domsch's nowayout module option + * 20030116 Adam Belay Updated to the latest pnp code * */ @@ -35,7 +36,7 @@ #include #include #include -#include +#include #include #include @@ -75,9 +76,9 @@ static char expect_close; spinlock_t sc1200wdt_lock; /* io port access serialisation */ -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#if defined CONFIG_PNP static int isapnp = 1; -static struct pci_dev *wdt_dev; +static struct pnp_dev *wdt_dev; MODULE_PARM(isapnp, "i"); MODULE_PARM_DESC(isapnp, "When set to 0 driver ISA PnP support will be disabled"); @@ -296,18 +297,18 @@ static struct file_operations sc1200wdt_fops = { - owner: THIS_MODULE, - write: sc1200wdt_write, - ioctl: sc1200wdt_ioctl, - open: sc1200wdt_open, - release: sc1200wdt_release + .owner = THIS_MODULE, + .write = sc1200wdt_write, + .ioctl = sc1200wdt_ioctl, + .open = sc1200wdt_open, + .release = sc1200wdt_release }; static struct miscdevice sc1200wdt_miscdev = { - minor: WATCHDOG_MINOR, - name: "watchdog", - fops: &sc1200wdt_fops, + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &sc1200wdt_fops, }; @@ -328,40 +329,49 @@ } -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#if defined CONFIG_PNP -static int __init sc1200wdt_isapnp_probe(void) +struct pnp_device_id scl200wdt_pnp_devices[] = { + /* National Semiconductor PC87307/PC97307 watchdog component */ + {.id = "NSC0800", .driver_data = 0}, + {.id = ""} +}; + +static int scl200wdt_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) { - int ret; + /* this driver only supports one card at a time */ + if (wdt_dev || !isapnp) + return -EBUSY; - /* The WDT is logical device 8 on the main device */ - wdt_dev = isapnp_find_dev(NULL, ISAPNP_VENDOR('N','S','C'), ISAPNP_FUNCTION(0x08), NULL); - if (!wdt_dev) - return -ENODEV; - - if (wdt_dev->prepare(wdt_dev) < 0) { - printk(KERN_ERR PFX "ISA PnP found device that could not be autoconfigured\n"); - return -EAGAIN; - } + wdt_dev = dev; + io = pnp_port_start(wdt_dev, 0); + io_len = pnp_port_len(wdt_dev, 0); - if (!(pci_resource_flags(wdt_dev, 0) & IORESOURCE_IO)) { - printk(KERN_ERR PFX "ISA PnP could not find io ports\n"); - return -ENODEV; + if (!request_region(io, io_len, SC1200_MODULE_NAME)) { + printk(KERN_ERR PFX "Unable to register IO port %#x\n", io); + return -EBUSY; } - ret = wdt_dev->activate(wdt_dev); - if (ret && (ret != -EBUSY)) - return -ENOMEM; - - /* io port resource overriding support? */ - io = pci_resource_start(wdt_dev, 0); - io_len = pci_resource_len(wdt_dev, 0); - - printk(KERN_DEBUG PFX "ISA PnP found device at io port %#x/%d\n", io, io_len); + printk(KERN_INFO "scl200wdt: PnP device found at io port %#x/%d\n", io, io_len); return 0; } -#endif /* CONFIG_ISAPNP */ +static void scl200wdt_pnp_remove(struct pnp_dev * dev) +{ + if (wdt_dev){ + release_region(io, io_len); + wdt_dev = NULL; + } +} + +static struct pnp_driver scl200wdt_pnp_driver = { + .name = "scl200wdt", + .id_table = scl200wdt_pnp_devices, + .probe = scl200wdt_pnp_probe, + .remove = scl200wdt_pnp_remove, +}; + +#endif /* CONFIG_PNP */ static int __init sc1200wdt_init(void) @@ -373,9 +383,9 @@ spin_lock_init(&sc1200wdt_lock); sema_init(&open_sem, 1); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#if defined CONFIG_PNP if (isapnp) { - ret = sc1200wdt_isapnp_probe(); + ret = pnp_register_driver(&scl200wdt_pnp_driver); if (ret) goto out_clean; } @@ -387,12 +397,19 @@ goto out_clean; } +#if defined CONFIG_PNP + /* now that the user has specified an IO port and we haven't detected + * any devices, disable pnp support */ + isapnp = 0; + pnp_unregister_driver(&scl200wdt_pnp_driver); +#endif + if (!request_region(io, io_len, SC1200_MODULE_NAME)) { printk(KERN_ERR PFX "Unable to register IO port %#x\n", io); ret = -EBUSY; - goto out_pnp; + goto out_clean; } - + ret = sc1200wdt_probe(); if (ret) goto out_io; @@ -420,11 +437,6 @@ out_io: release_region(io, io_len); -out_pnp: -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE - if (isapnp && wdt_dev) - wdt_dev->deactivate(wdt_dev); -#endif goto out_clean; } @@ -434,11 +446,11 @@ misc_deregister(&sc1200wdt_miscdev); unregister_reboot_notifier(&sc1200wdt_notifier); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE - if(isapnp && wdt_dev) - wdt_dev->deactivate(wdt_dev); +#if defined CONFIG_PNP + if(isapnp) + pnp_unregister_driver(&scl200wdt_pnp_driver); + else #endif - release_region(io, io_len); } @@ -455,7 +467,7 @@ if (ints[0] > 1) timeout = ints[2]; -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#if defined CONFIG_PNP if (ints[0] > 2) isapnp = ints[3]; #endif @@ -474,5 +486,3 @@ MODULE_AUTHOR("Zwane Mwaikambo "); MODULE_DESCRIPTION("Driver for National Semiconductor PC87307/PC97307 watchdog component"); MODULE_LICENSE("GPL"); -EXPORT_NO_SYMBOLS; - diff -Nru a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c --- a/drivers/char/watchdog/sc520_wdt.c Fri Feb 14 00:27:28 2003 +++ b/drivers/char/watchdog/sc520_wdt.c Fri Feb 14 00:27:28 2003 @@ -281,18 +281,18 @@ } static struct file_operations wdt_fops = { - owner: THIS_MODULE, - llseek: fop_llseek, - write: fop_write, - open: fop_open, - release: fop_close, - ioctl: fop_ioctl + .owner = THIS_MODULE, + .llseek = fop_llseek, + .write = fop_write, + .open = fop_open, + .release = fop_close, + .ioctl = fop_ioctl }; static struct miscdevice wdt_miscdev = { - WATCHDOG_MINOR, - "watchdog", - &wdt_fops + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &wdt_fops }; /* @@ -314,9 +314,9 @@ static struct notifier_block wdt_notifier= { - wdt_notify_sys, - 0, - 0 + .notifier_call = wdt_notify_sys, + .next = NULL, + .priority = 0 }; static void __exit sc520_wdt_unload(void) diff -Nru a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c --- a/drivers/char/watchdog/w83877f_wdt.c Fri Feb 14 00:27:29 2003 +++ b/drivers/char/watchdog/w83877f_wdt.c Fri Feb 14 00:27:29 2003 @@ -275,9 +275,9 @@ }; static struct miscdevice wdt_miscdev = { - WATCHDOG_MINOR, - "watchdog", - &wdt_fops + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &wdt_fops }; /* @@ -299,9 +299,9 @@ static struct notifier_block wdt_notifier= { - wdt_notify_sys, - 0, - 0 + .notifier_call = wdt_notify_sys, + .next = NULL, + .priority = 0 }; static void __exit w83877f_wdt_unload(void) diff -Nru a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c --- a/drivers/char/watchdog/wafer5823wdt.c Fri Feb 14 00:27:30 2003 +++ b/drivers/char/watchdog/wafer5823wdt.c Fri Feb 14 00:27:30 2003 @@ -198,17 +198,17 @@ */ static struct file_operations wafwdt_fops = { - owner:THIS_MODULE, - write:wafwdt_write, - ioctl:wafwdt_ioctl, - open:wafwdt_open, - release:wafwdt_close, + .owner = THIS_MODULE, + .write = wafwdt_write, + .ioctl = wafwdt_ioctl, + .open = wafwdt_open, + .release = wafwdt_close, }; static struct miscdevice wafwdt_miscdev = { - WATCHDOG_MINOR, - "watchdog", - &wafwdt_fops + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &wafwdt_fops }; /* @@ -217,9 +217,9 @@ */ static struct notifier_block wafwdt_notifier = { - wafwdt_notify_sys, - NULL, - 0 + .notifier_call = wafwdt_notify_sys, + .next = NULL, + .priority = 0 }; static int __init wafwdt_init(void) diff -Nru a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c --- a/drivers/char/watchdog/wdt.c Fri Feb 14 00:27:28 2003 +++ b/drivers/char/watchdog/wdt.c Fri Feb 14 00:27:28 2003 @@ -465,17 +465,17 @@ static struct miscdevice wdt_miscdev= { - WATCHDOG_MINOR, - "watchdog", - &wdt_fops + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &wdt_fops }; #ifdef CONFIG_WDT_501 static struct miscdevice temp_miscdev= { - TEMP_MINOR, - "temperature", - &wdt_fops + .minor = TEMP_MINOR, + .name = "temperature", + .fops = &wdt_fops }; #endif @@ -486,9 +486,9 @@ static struct notifier_block wdt_notifier= { - wdt_notify_sys, - NULL, - 0 + .notifier_call = wdt_notify_sys, + .next = NULL, + .priority = 0 }; /** diff -Nru a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c --- a/drivers/char/watchdog/wdt977.c Fri Feb 14 00:27:29 2003 +++ b/drivers/char/watchdog/wdt977.c Fri Feb 14 00:27:29 2003 @@ -258,7 +258,7 @@ unsigned int cmd, unsigned long arg) { static struct watchdog_info ident = { - identity : "Winbond 83977" + .identity = "Winbond 83977" }; int temp; diff -Nru a/drivers/hotplug/cpci_hotplug_core.c b/drivers/hotplug/cpci_hotplug_core.c --- a/drivers/hotplug/cpci_hotplug_core.c Fri Feb 14 00:27:28 2003 +++ b/drivers/hotplug/cpci_hotplug_core.c Fri Feb 14 00:27:28 2003 @@ -622,8 +622,7 @@ struct list_head *tmp; lock_kernel(); - daemonize(); - strcpy(current->comm, "cpci_hp_eventd"); + daemonize("cpci_hp_eventd"); unlock_kernel(); dbg("%s - event thread started", __FUNCTION__); @@ -682,8 +681,7 @@ struct list_head *tmp; lock_kernel(); - daemonize(); - strcpy(current->comm, "cpci_hp_polld"); + daemonize("cpci_hp_polld"); unlock_kernel(); while(1) { diff -Nru a/drivers/hotplug/cpqphp_ctrl.c b/drivers/hotplug/cpqphp_ctrl.c --- a/drivers/hotplug/cpqphp_ctrl.c Fri Feb 14 00:27:27 2003 +++ b/drivers/hotplug/cpqphp_ctrl.c Fri Feb 14 00:27:27 2003 @@ -1709,10 +1709,7 @@ { struct controller *ctrl; lock_kernel(); - daemonize(); - - // New name - strcpy(current->comm, "phpd_event"); + daemonize("phpd_event"); unlock_kernel(); diff -Nru a/drivers/hotplug/ibmphp_hpc.c b/drivers/hotplug/ibmphp_hpc.c --- a/drivers/hotplug/ibmphp_hpc.c Fri Feb 14 00:27:27 2003 +++ b/drivers/hotplug/ibmphp_hpc.c Fri Feb 14 00:27:27 2003 @@ -1125,13 +1125,9 @@ static int hpc_poll_thread (void *data) { debug ("%s - Entry\n", __FUNCTION__); - lock_kernel (); - daemonize (); - // New name - strcpy (current->comm, "hpc_poll"); - - unlock_kernel (); + daemonize("hpc_poll"); + allow_signal(SIGKILL); poll_hpc (); diff -Nru a/drivers/i2c/i2c-adap-ite.c b/drivers/i2c/i2c-adap-ite.c --- a/drivers/i2c/i2c-adap-ite.c Fri Feb 14 00:27:27 2003 +++ b/drivers/i2c/i2c-adap-ite.c Fri Feb 14 00:27:27 2003 @@ -78,7 +78,7 @@ unsigned long j = jiffies + 10; DEB3(printk(" Write 0x%02x to 0x%x\n",(unsigned short)val, ctl&0xff)); - DEB3({while (jiffies < j) schedule();}) + DEB3({while (time_before(jiffies, j)) schedule();}) outw(val,ctl); } diff -Nru a/drivers/i2c/i2c-algo-ibm_ocp.c b/drivers/i2c/i2c-algo-ibm_ocp.c --- a/drivers/i2c/i2c-algo-ibm_ocp.c Fri Feb 14 00:27:29 2003 +++ b/drivers/i2c/i2c-algo-ibm_ocp.c Fri Feb 14 00:27:29 2003 @@ -84,7 +84,7 @@ /* respectively. This makes sure that the algorithm works. Some chips */ /* might not like this, as they have an internal timeout of some mils */ /* -#define SLO_IO jif=jiffies;while(jiffies<=jif+i2c_table[minor].veryslow)\ +#define SLO_IO jif=jiffies;while(time_before_eq(jiffies,jif+i2c_table[minor].veryslow))\ if (need_resched) schedule(); */ diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c --- a/drivers/i2c/i2c-core.c Fri Feb 14 00:27:27 2003 +++ b/drivers/i2c/i2c-core.c Fri Feb 14 00:27:27 2003 @@ -56,7 +56,7 @@ /* ----- global variables -------------------------------------------------- */ /**** lock for writing to global variables: the adapter & driver list */ -DECLARE_MUTEX(adap_lock); +static DECLARE_MUTEX(adap_lock); static DECLARE_MUTEX(driver_lock); /**** adapter list */ diff -Nru a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c --- a/drivers/ide/pci/amd74xx.c Fri Feb 14 00:27:30 2003 +++ b/drivers/ide/pci/amd74xx.c Fri Feb 14 00:27:30 2003 @@ -60,7 +60,7 @@ { PCI_DEVICE_ID_AMD_OPUS_7441, 0x00, 0x40, AMD_UDMA_100 }, /* AMD-768 Opus */ { PCI_DEVICE_ID_AMD_8111_IDE, 0x00, 0x40, AMD_UDMA_100 }, /* AMD-8111 */ { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x00, 0x50, AMD_UDMA_100 }, /* nVidia nForce */ - + { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x00, 0x50, AMD_UDMA_100 }, /* nVidia nForce 2 */ { 0 } }; @@ -446,6 +446,7 @@ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, { 0, }, }; diff -Nru a/drivers/ide/pci/amd74xx.h b/drivers/ide/pci/amd74xx.h --- a/drivers/ide/pci/amd74xx.h Fri Feb 14 00:27:26 2003 +++ b/drivers/ide/pci/amd74xx.h Fri Feb 14 00:27:26 2003 @@ -110,6 +110,20 @@ .bootable = ON_BOARD, .extra = 0, }, + { /* 6 */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, + .name = "NFORCE2", + .init_chipset = init_chipset_amd74xx, + .init_iops = NULL, + .init_hwif = init_hwif_amd74xx, + .init_dma = init_dma_amd74xx, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x50,0x01,0x01}, {0x50,0x02,0x02}}, + .bootable = ON_BOARD, + .extra = 0, + }, { .vendor = 0, .device = 0, diff -Nru a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c --- a/drivers/ieee1394/nodemgr.c Fri Feb 14 00:27:28 2003 +++ b/drivers/ieee1394/nodemgr.c Fri Feb 14 00:27:28 2003 @@ -1216,10 +1216,9 @@ struct host_info *hi = (struct host_info *)__hi; /* No userlevel access needed */ - daemonize(); + daemonize("knodemgrd"); + allow_signal(SIGTERM); - strcpy(current->comm, "knodemgrd"); - /* Sit and wait for a signal to probe the nodes on the bus. This * happens when we get a bus reset. */ while (!down_interruptible(&hi->reset_sem) && diff -Nru a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c --- a/drivers/input/gameport/ns558.c Fri Feb 14 00:27:29 2003 +++ b/drivers/input/gameport/ns558.c Fri Feb 14 00:27:29 2003 @@ -46,7 +46,7 @@ #define NS558_ISA 1 #define NS558_PNP 2 -static int ns558_isa_portlist[] = { 0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x207, 0x209, +static int ns558_isa_portlist[] = { 0x201, 0x200, 0x202, 0x203, 0x204, 0x205, 0x207, 0x209, 0x20b, 0x20c, 0x20e, 0x20f, 0x211, 0x219, 0x101, 0 }; struct ns558 { @@ -140,7 +140,7 @@ port->type = NS558_ISA; port->size = (1 << i); - port->gameport.io = io & (-1 << i); + port->gameport.io = io; port->gameport.phys = port->phys; port->gameport.name = port->name; port->gameport.id.bustype = BUS_ISA; @@ -148,7 +148,7 @@ sprintf(port->phys, "isa%04x/gameport0", io & (-1 << i)); sprintf(port->name, "NS558 ISA"); - request_region(port->gameport.io, (1 << i), "ns558-isa"); + request_region(io & (-1 << i), (1 << i), "ns558-isa"); gameport_register_port(&port->gameport); @@ -275,7 +275,7 @@ /* fall through */ #endif case NS558_ISA: - release_region(port->gameport.io, port->size); + release_region(port->gameport.io & ~(port->size - 1), port->size); break; default: diff -Nru a/drivers/input/joydev.c b/drivers/input/joydev.c --- a/drivers/input/joydev.c Fri Feb 14 00:27:28 2003 +++ b/drivers/input/joydev.c Fri Feb 14 00:27:28 2003 @@ -340,7 +340,7 @@ case JSIOCSBTNMAP: if (copy_from_user(joydev->keypam, (__u16 *) arg, sizeof(__u16) * (KEY_MAX - BTN_MISC))) return -EFAULT; - for (i = 0; i < joydev->nkey; i++); { + for (i = 0; i < joydev->nkey; i++) { if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL; joydev->keymap[joydev->keypam[i] - BTN_MISC] = i; } @@ -377,7 +377,8 @@ struct joydev *joydev; int i, j, t, minor; - if (test_bit(BTN_TOUCH, dev->keybit)) + /* Avoid tablets */ + if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit)) return NULL; for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); @@ -463,18 +464,18 @@ static struct input_device_id joydev_ids[] = { { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, + .evbit = { BIT(EV_ABS) }, .absbit = { BIT(ABS_X) }, }, { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, + .evbit = { BIT(EV_ABS) }, .absbit = { BIT(ABS_WHEEL) }, }, { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, + .evbit = { BIT(EV_ABS) }, .absbit = { BIT(ABS_THROTTLE) }, }, { }, /* Terminating entry */ diff -Nru a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c --- a/drivers/input/joystick/amijoy.c Fri Feb 14 00:27:29 2003 +++ b/drivers/input/joystick/amijoy.c Fri Feb 14 00:27:29 2003 @@ -64,6 +64,8 @@ case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break; } + input_regs(amijoy_dev + i, fp); + input_report_key(amijoy_dev + i, BTN_TRIGGER, button); input_report_abs(amijoy_dev + i, ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1)); diff -Nru a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c --- a/drivers/input/joystick/iforce/iforce-packets.c Fri Feb 14 00:27:28 2003 +++ b/drivers/input/joystick/iforce/iforce-packets.c Fri Feb 14 00:27:28 2003 @@ -151,7 +151,7 @@ return -1; } -void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) +void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs) { struct input_dev *dev = &iforce->dev; int i; @@ -181,6 +181,8 @@ case 0x01: /* joystick position data */ case 0x03: /* wheel position data */ + input_regs(dev, regs); + if (HI(cmd) == 1) { input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0])); input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2])); @@ -219,6 +221,7 @@ break; case 0x02: /* status report */ + input_regs(dev, regs); input_report_key(dev, BTN_DEAD, data[0] & 0x02); input_sync(dev); diff -Nru a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c --- a/drivers/input/joystick/iforce/iforce-serio.c Fri Feb 14 00:27:26 2003 +++ b/drivers/input/joystick/iforce/iforce-serio.c Fri Feb 14 00:27:26 2003 @@ -78,7 +78,7 @@ iforce_serial_xmit((struct iforce *)serio->private); } -static void iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags) +static void iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct iforce* iforce = serio->private; @@ -115,7 +115,7 @@ } if (iforce->idx == iforce->len) { - iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data); + iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data, regs); iforce->pkt = 0; iforce->id = 0; iforce->len = 0; diff -Nru a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c --- a/drivers/input/joystick/iforce/iforce-usb.c Fri Feb 14 00:27:29 2003 +++ b/drivers/input/joystick/iforce/iforce-usb.c Fri Feb 14 00:27:29 2003 @@ -74,7 +74,7 @@ spin_unlock_irqrestore(&iforce->xmit_lock, flags); } -static void iforce_usb_irq(struct urb *urb) +static void iforce_usb_irq(struct urb *urb, struct pt_regs *regs) { struct iforce *iforce = urb->context; int status; @@ -96,7 +96,7 @@ } iforce_process_packet(iforce, - (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1); + (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1, regs); exit: status = usb_submit_urb (urb, GFP_ATOMIC); @@ -105,7 +105,7 @@ __FUNCTION__, status); } -static void iforce_usb_out(struct urb *urb) +static void iforce_usb_out(struct urb *urb, struct pt_regs *regs) { struct iforce *iforce = urb->context; @@ -120,7 +120,7 @@ wake_up(&iforce->wait); } -static void iforce_usb_ctrl(struct urb *urb) +static void iforce_usb_ctrl(struct urb *urb, struct pt_regs *regs) { struct iforce *iforce = urb->context; if (urb->status) return; @@ -133,11 +133,14 @@ const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); + struct usb_host_interface *interface; struct usb_endpoint_descriptor *epirq, *epout; struct iforce *iforce; - epirq = intf->altsetting[0].endpoint + 0; - epout = intf->altsetting[0].endpoint + 1; + interface = &intf->altsetting[intf->act_altsetting]; + + epirq = &interface->endpoint[0].desc; + epout = &interface->endpoint[1].desc; if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL))) goto fail; diff -Nru a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h --- a/drivers/input/joystick/iforce/iforce.h Fri Feb 14 00:27:28 2003 +++ b/drivers/input/joystick/iforce/iforce.h Fri Feb 14 00:27:28 2003 @@ -176,7 +176,7 @@ /* iforce-packets.c */ int iforce_control_playback(struct iforce*, u16 id, unsigned int); -void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data); +void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs); int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data); void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) ; int iforce_get_id_packet(struct iforce *iforce, char *packet); diff -Nru a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c --- a/drivers/input/joystick/magellan.c Fri Feb 14 00:27:26 2003 +++ b/drivers/input/joystick/magellan.c Fri Feb 14 00:27:26 2003 @@ -81,7 +81,7 @@ return 0; } -static void magellan_process_packet(struct magellan* magellan) +static void magellan_process_packet(struct magellan* magellan, struct pt_regs *regs) { struct input_dev *dev = &magellan->dev; unsigned char *data = magellan->data; @@ -89,6 +89,8 @@ if (!magellan->idx) return; + input_regs(dev, regs); + switch (magellan->data[0]) { case 'd': /* Axis data */ @@ -111,12 +113,12 @@ input_sync(dev); } -static void magellan_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +static void magellan_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct magellan* magellan = serio->private; if (data == '\r') { - magellan_process_packet(magellan); + magellan_process_packet(magellan, regs); magellan->idx = 0; } else { if (magellan->idx < MAGELLAN_MAX_LENGTH) diff -Nru a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c --- a/drivers/input/joystick/spaceball.c Fri Feb 14 00:27:26 2003 +++ b/drivers/input/joystick/spaceball.c Fri Feb 14 00:27:26 2003 @@ -81,7 +81,7 @@ * SpaceBall. */ -static void spaceball_process_packet(struct spaceball* spaceball) +static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs *regs) { struct input_dev *dev = &spaceball->dev; unsigned char *data = spaceball->data; @@ -89,6 +89,8 @@ if (spaceball->idx < 2) return; + input_regs(dev, regs); + switch (spaceball->data[0]) { case 'D': /* Ball data */ @@ -147,13 +149,13 @@ * can occur in the axis values. */ -static void spaceball_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +static void spaceball_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct spaceball *spaceball = serio->private; switch (data) { case 0xd: - spaceball_process_packet(spaceball); + spaceball_process_packet(spaceball, regs); spaceball->idx = 0; spaceball->escape = 0; return; diff -Nru a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c --- a/drivers/input/joystick/spaceorb.c Fri Feb 14 00:27:28 2003 +++ b/drivers/input/joystick/spaceorb.c Fri Feb 14 00:27:28 2003 @@ -74,7 +74,7 @@ * SpaceOrb. */ -static void spaceorb_process_packet(struct spaceorb *spaceorb) +static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *regs) { struct input_dev *dev = &spaceorb->dev; unsigned char *data = spaceorb->data; @@ -86,6 +86,8 @@ for (i = 0; i < spaceorb->idx; i++) c ^= data[i]; if (c) return; + input_regs(dev, regs); + switch (data[0]) { case 'R': /* Reset packet */ @@ -128,12 +130,12 @@ input_sync(dev); } -static void spaceorb_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +static void spaceorb_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct spaceorb* spaceorb = serio->private; if (~data & 0x80) { - if (spaceorb->idx) spaceorb_process_packet(spaceorb); + if (spaceorb->idx) spaceorb_process_packet(spaceorb, regs); spaceorb->idx = 0; } if (spaceorb->idx < SPACEORB_MAX_LENGTH) diff -Nru a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c --- a/drivers/input/joystick/stinger.c Fri Feb 14 00:27:26 2003 +++ b/drivers/input/joystick/stinger.c Fri Feb 14 00:27:26 2003 @@ -64,13 +64,15 @@ * Stinger. It updates the data accordingly. */ -static void stinger_process_packet(struct stinger *stinger) +static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs) { struct input_dev *dev = &stinger->dev; unsigned char *data = stinger->data; if (!stinger->idx) return; + input_regs(dev, regs); + input_report_key(dev, BTN_A, ((data[0] & 0x20) >> 5)); input_report_key(dev, BTN_B, ((data[0] & 0x10) >> 4)); input_report_key(dev, BTN_C, ((data[0] & 0x08) >> 3)); @@ -96,7 +98,7 @@ * packet processing routine. */ -static void stinger_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +static void stinger_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct stinger* stinger = serio->private; @@ -106,7 +108,7 @@ stinger->data[stinger->idx++] = data; if (stinger->idx == 4) { - stinger_process_packet(stinger); + stinger_process_packet(stinger, regs); stinger->idx = 0; } diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c --- a/drivers/input/joystick/twidjoy.c Fri Feb 14 00:27:27 2003 +++ b/drivers/input/joystick/twidjoy.c Fri Feb 14 00:27:27 2003 @@ -101,7 +101,7 @@ * Twiddler. It updates the data accordingly. */ -static void twidjoy_process_packet(struct twidjoy *twidjoy) +static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs) { if (twidjoy->idx == TWIDJOY_MAX_LENGTH) { struct input_dev *dev = &twidjoy->dev; @@ -111,6 +111,8 @@ button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f); + input_regs(dev, regs); + for (bp = twidjoy_buttons; bp->bitmask; bp++) { int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift; int i; @@ -140,7 +142,7 @@ * packet processing routine. */ -static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struc pt_regs *regs) { struct twidjoy *twidjoy = serio->private; @@ -157,7 +159,7 @@ twidjoy->data[twidjoy->idx++] = data; if (twidjoy->idx == TWIDJOY_MAX_LENGTH) { - twidjoy_process_packet(twidjoy); + twidjoy_process_packet(twidjoy, regs); twidjoy->idx = 0; } diff -Nru a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c --- a/drivers/input/joystick/warrior.c Fri Feb 14 00:27:29 2003 +++ b/drivers/input/joystick/warrior.c Fri Feb 14 00:27:29 2003 @@ -63,13 +63,15 @@ * Warrior. It updates the data accordingly. */ -static void warrior_process_packet(struct warrior *warrior) +static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs) { struct input_dev *dev = &warrior->dev; unsigned char *data = warrior->data; if (!warrior->idx) return; + input_regs(dev, regs); + switch ((data[0] >> 4) & 7) { case 1: /* Button data */ input_report_key(dev, BTN_TRIGGER, data[3] & 1); @@ -97,12 +99,12 @@ * packet processing routine. */ -static void warrior_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +static void warrior_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct warrior* warrior = serio->private; if (data & 0x80) { - if (warrior->idx) warrior_process_packet(warrior); + if (warrior->idx) warrior_process_packet(warrior, regs); warrior->idx = 0; warrior->len = warrior_lengths[(data >> 4) & 7]; } @@ -111,7 +113,7 @@ warrior->data[warrior->idx++] = data; if (warrior->idx == warrior->len) { - if (warrior->idx) warrior_process_packet(warrior); + if (warrior->idx) warrior_process_packet(warrior, regs); warrior->idx = 0; warrior->len = 0; } diff -Nru a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c --- a/drivers/input/keyboard/amikbd.c Fri Feb 14 00:27:30 2003 +++ b/drivers/input/keyboard/amikbd.c Fri Feb 14 00:27:30 2003 @@ -87,6 +87,8 @@ scancode = amikbd_keycode[scancode]; + input_regs(&amikbd_dev, fp); + if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */ input_report_key(&amikbd_dev, scancode, 1); input_report_key(&amikbd_dev, scancode, 0); diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c --- a/drivers/input/keyboard/atkbd.c Fri Feb 14 00:27:29 2003 +++ b/drivers/input/keyboard/atkbd.c Fri Feb 14 00:27:29 2003 @@ -86,8 +86,7 @@ #define ATKBD_CMD_SETLEDS 0x10ed #define ATKBD_CMD_GSCANSET 0x11f0 #define ATKBD_CMD_SSCANSET 0x10f0 -#define ATKBD_CMD_GETID 0x01f2 -#define ATKBD_CMD_GETID2 0x0100 +#define ATKBD_CMD_GETID 0x02f2 #define ATKBD_CMD_ENABLE 0x00f4 #define ATKBD_CMD_RESET_DIS 0x00f5 #define ATKBD_CMD_RESET_BAT 0x01ff @@ -120,12 +119,12 @@ unsigned char cmdbuf[4]; unsigned char cmdcnt; unsigned char set; - unsigned char oldset; unsigned char release; - signed char ack; + volatile signed char ack; unsigned char emul; unsigned short id; unsigned char write; + unsigned char resend; }; /* @@ -133,7 +132,7 @@ * the keyboard into events. */ -static void atkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +static void atkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct atkbd *atkbd = serio->private; int code = data; @@ -142,11 +141,15 @@ printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags); #endif - if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && atkbd->write) { + if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { printk("atkbd.c: frame/parity error: %02x\n", flags); serio_write(serio, ATKBD_CMD_RESEND); + atkbd->resend = 1; return; } + + if (!flags) + atkbd->resend = 0; switch (code) { case ATKBD_RET_ACK: @@ -190,6 +193,7 @@ atkbd->set, code, serio->phys, atkbd->release ? "released" : "pressed"); break; default: + input_regs(&atkbd->dev, regs); input_report_key(&atkbd->dev, atkbd->keycode[code], !atkbd->release); input_sync(&atkbd->dev); } @@ -227,12 +231,15 @@ static int atkbd_command(struct atkbd *atkbd, unsigned char *param, int command) { - int timeout = 50000; /* 500 msec */ + int timeout = 500000; /* 500 msec */ int send = (command >> 12) & 0xf; int receive = (command >> 8) & 0xf; int i; atkbd->cmdcnt = receive; + + if (command == ATKBD_CMD_RESET_BAT) + timeout = 2000000; /* 2 sec */ if (command & 0xff) if (atkbd_sendbyte(atkbd, command & 0xff)) @@ -242,14 +249,28 @@ if (atkbd_sendbyte(atkbd, param[i])) return (atkbd->cmdcnt = 0) - 1; - while (atkbd->cmdcnt && timeout--) udelay(10); + while (atkbd->cmdcnt && timeout--) { + + if (atkbd->cmdcnt == 1 && command == ATKBD_CMD_RESET_BAT) + timeout = 100000; + + if (atkbd->cmdcnt == 1 && command == ATKBD_CMD_GETID && + atkbd->cmdbuf[1] != 0xab && atkbd->cmdbuf[1] != 0xac) { + atkbd->cmdcnt = 0; + break; + } + + udelay(1); + } if (param) for (i = 0; i < receive; i++) param[i] = atkbd->cmdbuf[(receive - 1) - i]; - if (atkbd->cmdcnt) - return (atkbd->cmdcnt = 0) - 1; + if (atkbd->cmdcnt) { + atkbd->cmdcnt = 0; + return -1; + } return 0; } @@ -303,13 +324,6 @@ unsigned char param[2]; /* - * Remember original scancode set value, so that we can restore it on exit. - */ - - if (atkbd_command(atkbd, &atkbd->oldset, ATKBD_CMD_GSCANSET)) - atkbd->oldset = 2; - -/* * For known special keyboards we can go ahead and set the correct set. * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and * IBM RapidAccess / IBM EzButton / Chicony KBP-8993 keyboards. @@ -376,8 +390,8 @@ */ if (atkbd_reset) - if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT)) - printk(KERN_WARNING "atkbd.c: keyboard reset failed\n"); + if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT)) + printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys); /* * Then we check the keyboard ID. We should get 0xab83 under normal conditions. @@ -401,10 +415,7 @@ if (param[0] != 0xab && param[0] != 0xac) return -1; - atkbd->id = param[0] << 8; - if (atkbd_command(atkbd, param, ATKBD_CMD_GETID2)) - return -1; - atkbd->id |= param[0]; + atkbd->id = (param[0] << 8) | param[1]; /* * Set the LEDs to a defined state. @@ -442,7 +453,7 @@ static void atkbd_cleanup(struct serio *serio) { struct atkbd *atkbd = serio->private; - atkbd_command(atkbd, &atkbd->oldset, ATKBD_CMD_SSCANSET); + atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT); } /* diff -Nru a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c --- a/drivers/input/keyboard/newtonkbd.c Fri Feb 14 00:27:26 2003 +++ b/drivers/input/keyboard/newtonkbd.c Fri Feb 14 00:27:26 2003 @@ -62,18 +62,20 @@ char phys[32]; }; -void nkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +void nkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct nkbd *nkbd = serio->private; /* invalid scan codes are probably the init sequence, so we ignore them */ - if (nkbd->keycode[data & NKBD_KEY]) + if (nkbd->keycode[data & NKBD_KEY]) { + input_regs(&nkbd->dev, regs); input_report_key(&nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS); + input_sync(&nkbd->dev); + } else if (data == 0xe7) /* end of init sequence */ printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys); - input_sync(&nkbd->dev); } void nkbd_connect(struct serio *serio, struct serio_dev *dev) diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c --- a/drivers/input/keyboard/sunkbd.c Fri Feb 14 00:27:26 2003 +++ b/drivers/input/keyboard/sunkbd.c Fri Feb 14 00:27:26 2003 @@ -89,7 +89,7 @@ * is received. */ -static void sunkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +static void sunkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct sunkbd* sunkbd = serio->private; @@ -119,6 +119,7 @@ default: if (sunkbd->keycode[data & SUNKBD_KEY]) { + input_regs(&sunkbd->dev, regs); input_report_key(&sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE)); input_sync(&sunkbd->dev); } else { @@ -267,7 +268,7 @@ sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type); memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode)); - for (i = 0; i < 255; i++) + for (i = 0; i < 127; i++) set_bit(sunkbd->keycode[i], sunkbd->dev.keybit); clear_bit(0, sunkbd->dev.keybit); diff -Nru a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c --- a/drivers/input/keyboard/xtkbd.c Fri Feb 14 00:27:28 2003 +++ b/drivers/input/keyboard/xtkbd.c Fri Feb 14 00:27:28 2003 @@ -63,7 +63,7 @@ char phys[32]; }; -void xtkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +void xtkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct xtkbd *xtkbd = serio->private; @@ -74,6 +74,7 @@ default: if (xtkbd->keycode[data & XTKBD_KEY]) { + input_regs(&xtkbd->dev, regs); input_report_key(&xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE)); input_sync(&xtkbd->dev); } else { diff -Nru a/drivers/input/misc/98spkr.c b/drivers/input/misc/98spkr.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/input/misc/98spkr.c Fri Feb 14 00:27:30 2003 @@ -0,0 +1,95 @@ +/* + * PC-9800 Speaker beeper driver for Linux + * + * Copyright (c) 2002 Osamu Tomita + * Copyright (c) 2002 Vojtech Pavlik + * Copyright (c) 1992 Orest Zborowski + * + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation + */ + +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Osamu Tomita "); +MODULE_DESCRIPTION("PC-9800 Speaker beeper driver"); +MODULE_LICENSE("GPL"); + +static char spkr98_name[] = "PC-9801 Speaker"; +static char spkr98_phys[] = "isa3fdb/input0"; +static struct input_dev spkr98_dev; + +spinlock_t i8253_beep_lock = SPIN_LOCK_UNLOCKED; + +static int spkr98_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) +{ + unsigned int count = 0; + unsigned long flags; + + if (type != EV_SND) + return -1; + + switch (code) { + case SND_BELL: if (value) value = 1000; + case SND_TONE: break; + default: return -1; + } + + if (value > 20 && value < 32767) + count = CLOCK_TICK_RATE / value; + + spin_lock_irqsave(&i8253_beep_lock, flags); + + if (count) { + outb(0x76, 0x3fdf); + outb(0, 0x5f); + outb(count & 0xff, 0x3fdb); + outb(0, 0x5f); + outb((count >> 8) & 0xff, 0x3fdb); + /* beep on */ + outb(6, 0x37); + } else { + /* beep off */ + outb(7, 0x37); + } + + spin_unlock_irqrestore(&i8253_beep_lock, flags); + + return 0; +} + +static int __init spkr98_init(void) +{ + spkr98_dev.evbit[0] = BIT(EV_SND); + spkr98_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); + spkr98_dev.event = spkr98_event; + + spkr98_dev.name = spkr98_name; + spkr98_dev.phys = spkr98_phys; + spkr98_dev.id.bustype = BUS_ISA; + spkr98_dev.id.vendor = 0x001f; + spkr98_dev.id.product = 0x0001; + spkr98_dev.id.version = 0x0100; + + input_register_device(&spkr98_dev); + + printk(KERN_INFO "input: %s\n", spkr98_name); + + return 0; +} + +static void __exit spkr98_exit(void) +{ + input_unregister_device(&spkr98_dev); +} + +module_init(spkr98_init); +module_exit(spkr98_exit); diff -Nru a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig --- a/drivers/input/misc/Kconfig Fri Feb 14 00:27:28 2003 +++ b/drivers/input/misc/Kconfig Fri Feb 14 00:27:28 2003 @@ -44,6 +44,10 @@ tristate "M68k Beeper support" depends on M68K && INPUT && INPUT_MISC +config INPUT_98SPKR + tristate "PC-9800 Speaker support" + depends on X86_PC9800 && INPUT && INPUT_MISC + config INPUT_UINPUT tristate "User level driver support" depends on INPUT && INPUT_MISC diff -Nru a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile --- a/drivers/input/misc/Makefile Fri Feb 14 00:27:28 2003 +++ b/drivers/input/misc/Makefile Fri Feb 14 00:27:28 2003 @@ -7,5 +7,6 @@ obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o +obj-$(CONFIG_INPUT_98SPKR) += 98spkr.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_GSC) += gsc_ps2.o diff -Nru a/drivers/input/misc/gsc_ps2.c b/drivers/input/misc/gsc_ps2.c --- a/drivers/input/misc/gsc_ps2.c Fri Feb 14 00:27:27 2003 +++ b/drivers/input/misc/gsc_ps2.c Fri Feb 14 00:27:27 2003 @@ -305,7 +305,7 @@ * Receives a keyboard scancode, analyses it and sends it to the input layer. */ -static void gscps2_kbd_docode(void) +static void gscps2_kbd_docode(struct pt_regs *regs) { int scancode = gscps2_readb_input(hpkeyb.addr); DPRINTK("rel=%d scancode=%d, esc=%d ", hpkeyb.released, scancode, hpkeyb.escaped); @@ -341,6 +341,7 @@ default: hpkeyb.scancode = scancode; DPRINTK("sent=%d, rel=%d\n",hpkeyb.scancode, hpkeyb.released); + input_regs(regs); input_report_key(&hpkeyb.dev, hpkeyb_keycode[hpkeyb.scancode], !hpkeyb.released); input_sync(&hpkeyb.dev); if (hpkeyb.escaped) @@ -359,7 +360,7 @@ * correct events to the input layer. */ -static void gscps2_mouse_docode(void) +static void gscps2_mouse_docode(struct pt_regs *regs) { int xrel, yrel; @@ -368,7 +369,7 @@ hpmouse.nbread--; /* stolen from psmouse.c */ - if (hpmouse.nbread && time_after(jiffies, hpmouse.last + HZ/20)) { + if (hpmouse.nbread && time_after(jiffies, hpmouse.last + HZ/2)) { printk(KERN_DEBUG "%s:%d : Lost mouse synchronization, throwing %d bytes away.\n", __FILE__, __LINE__, hpmouse.nbread); hpmouse.nbread = 0; @@ -387,6 +388,8 @@ if ((hpmouse.bytes[PACKET_CTRL] & (MOUSE_XOVFLOW | MOUSE_YOVFLOW))) DPRINTK("Mouse: position overflow\n"); + input_regs(regs); + input_report_key(&hpmouse.dev, BTN_LEFT, hpmouse.bytes[PACKET_CTRL] & MOUSE_LEFTBTN); input_report_key(&hpmouse.dev, BTN_MIDDLE, hpmouse.bytes[PACKET_CTRL] & MOUSE_MIDBTN); input_report_key(&hpmouse.dev, BTN_RIGHT, hpmouse.bytes[PACKET_CTRL] & MOUSE_RIGHTBTN); @@ -421,11 +424,11 @@ { /* process mouse actions */ while (gscps2_readb_status(hpmouse.addr) & GSC_STAT_RBNE) - gscps2_mouse_docode(); + gscps2_mouse_docode(reg); /* process keyboard scancode */ while (gscps2_readb_status(hpkeyb.addr) & GSC_STAT_RBNE) - gscps2_kbd_docode(); + gscps2_kbd_docode(reg); } diff -Nru a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c --- a/drivers/input/mouse/amimouse.c Fri Feb 14 00:27:27 2003 +++ b/drivers/input/mouse/amimouse.c Fri Feb 14 00:27:27 2003 @@ -63,6 +63,8 @@ potgor = custom.potgor; + input_regs(&amimouse_dev, fp); + input_report_rel(&amimouse_dev, REL_X, dx); input_report_rel(&amimouse_dev, REL_Y, dy); diff -Nru a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c --- a/drivers/input/mouse/inport.c Fri Feb 14 00:27:28 2003 +++ b/drivers/input/mouse/inport.c Fri Feb 14 00:27:28 2003 @@ -131,6 +131,8 @@ outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); + input_regs(&inport_dev, regs); + outb(INPORT_REG_X, INPORT_CONTROL_PORT); input_report_rel(&inport_dev, REL_X, inb(INPORT_DATA_PORT)); diff -Nru a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c --- a/drivers/input/mouse/logibm.c Fri Feb 14 00:27:28 2003 +++ b/drivers/input/mouse/logibm.c Fri Feb 14 00:27:28 2003 @@ -130,6 +130,7 @@ dy |= (buttons & 0xf) << 4; buttons = ~buttons >> 5; + input_regs(&logibm_dev, regs); input_report_rel(&logibm_dev, REL_X, dx); input_report_rel(&logibm_dev, REL_Y, dy); input_report_key(&logibm_dev, BTN_RIGHT, buttons & 1); diff -Nru a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c --- a/drivers/input/mouse/pc110pad.c Fri Feb 14 00:27:27 2003 +++ b/drivers/input/mouse/pc110pad.c Fri Feb 14 00:27:27 2003 @@ -73,6 +73,7 @@ if (pc110pad_count < 3) return; + input_regs(&pc110pad_dev, regs); input_report_key(&pc110pad_dev, BTN_TOUCH, pc110pad_data[0] & 0x01); input_report_abs(&pc110pad_dev, ABS_X, diff -Nru a/drivers/input/mouse/psmouse.c b/drivers/input/mouse/psmouse.c --- a/drivers/input/mouse/psmouse.c Fri Feb 14 00:27:27 2003 +++ b/drivers/input/mouse/psmouse.c Fri Feb 14 00:27:27 2003 @@ -30,8 +30,7 @@ #define PSMOUSE_CMD_GETINFO 0x03e9 #define PSMOUSE_CMD_SETSTREAM 0x00ea #define PSMOUSE_CMD_POLL 0x03eb -#define PSMOUSE_CMD_GETID 0x01f2 -#define PSMOUSE_CMD_GETID2 0x0100 +#define PSMOUSE_CMD_GETID 0x02f2 #define PSMOUSE_CMD_SETRATE 0x10f3 #define PSMOUSE_CMD_ENABLE 0x00f4 #define PSMOUSE_CMD_RESET_DIS 0x00f6 @@ -54,7 +53,7 @@ unsigned char model; unsigned long last; char acking; - char ack; + volatile char ack; char error; char devname[64]; char phys[32]; @@ -74,20 +73,22 @@ * reports relevant events to the input module. */ -static void psmouse_process_packet(struct psmouse *psmouse) +static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs) { struct input_dev *dev = &psmouse->dev; unsigned char *packet = psmouse->packet; + input_regs(dev, regs); + /* * The PS2++ protocol is a little bit complex */ if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP) { - if ((packet[0] & 0x40) == 0x40 && (int) packet[1] - (int) ((packet[0] & 0x10) << 4) > 191 ) { + if ((packet[0] & 0x40) == 0x40 && abs((int)packet[1] - (((int)packet[0] & 0x10) << 4)) > 191 ) { - switch (((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0xc0)) { + switch (((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c)) { case 1: /* Mouse extra info */ @@ -106,10 +107,11 @@ break; +#ifdef DEBUG default: - printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n", - ((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0xc0)); + ((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c)); +#endif } @@ -165,7 +167,7 @@ * packets or passing them to the command routine as command output. */ -static void psmouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +static void psmouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct psmouse *psmouse = serio->private; @@ -201,7 +203,7 @@ psmouse->packet[psmouse->pktcnt++] = data; if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) { - psmouse_process_packet(psmouse); + psmouse_process_packet(psmouse, regs); psmouse->pktcnt = 0; return; } @@ -248,6 +250,9 @@ psmouse->cmdcnt = receive; + if (command == PSMOUSE_CMD_RESET_BAT) + timeout = 2000000; /* 2 sec */ + if (command & 0xff) if (psmouse_sendbyte(psmouse, command & 0xff)) return (psmouse->cmdcnt = 0) - 1; @@ -256,7 +261,19 @@ if (psmouse_sendbyte(psmouse, param[i])) return (psmouse->cmdcnt = 0) - 1; - while (psmouse->cmdcnt && timeout--) udelay(1); + while (psmouse->cmdcnt && timeout--) { + + if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_RESET_BAT) + timeout = 100000; + + if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_GETID && + psmouse->cmdbuf[1] != 0xab && psmouse->cmdbuf[1] != 0xac) { + psmouse->cmdcnt = 0; + break; + } + + udelay(1); + } for (i = 0; i < receive; i++) param[i] = psmouse->cmdbuf[(receive - 1) - i]; @@ -497,11 +514,6 @@ if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETID)) return -1; - - if (param[0] == 0xab || param[0] == 0xac) { - psmouse_command(psmouse, param, PSMOUSE_CMD_GETID2); - return -1; - } if (param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04) return -1; diff -Nru a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c --- a/drivers/input/mouse/rpcmouse.c Fri Feb 14 00:27:28 2003 +++ b/drivers/input/mouse/rpcmouse.c Fri Feb 14 00:27:28 2003 @@ -64,6 +64,8 @@ rpcmouse_lastx = x; rpcmouse_lasty = y; + input_regs(dev, regs); + input_report_rel(dev, REL_X, dx); input_report_rel(dev, REL_Y, -dy); diff -Nru a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c --- a/drivers/input/mouse/sermouse.c Fri Feb 14 00:27:29 2003 +++ b/drivers/input/mouse/sermouse.c Fri Feb 14 00:27:29 2003 @@ -60,11 +60,13 @@ * second, which is as good as a PS/2 or USB mouse. */ -static void sermouse_process_msc(struct sermouse *sermouse, signed char data) +static void sermouse_process_msc(struct sermouse *sermouse, signed char data, struct pt_regs *regs) { struct input_dev *dev = &sermouse->dev; signed char *buf = sermouse->buf; + input_regs(dev, regs); + switch (sermouse->count) { case 0: @@ -101,13 +103,15 @@ * standard 3-byte packets and 1200 bps. */ -static void sermouse_process_ms(struct sermouse *sermouse, signed char data) +static void sermouse_process_ms(struct sermouse *sermouse, signed char data, struct pt_regs *regs) { struct input_dev *dev = &sermouse->dev; signed char *buf = sermouse->buf; if (data & 0x40) sermouse->count = 0; + input_regs(dev, regs); + switch (sermouse->count) { case 0: @@ -200,7 +204,7 @@ * packets or passing them to the command routine as command output. */ -static void sermouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +static void sermouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct sermouse *sermouse = serio->private; @@ -208,9 +212,9 @@ sermouse->last = jiffies; if (sermouse->type > SERIO_SUN) - sermouse_process_ms(sermouse, data); + sermouse_process_ms(sermouse, data, regs); else - sermouse_process_msc(sermouse, data); + sermouse_process_msc(sermouse, data, regs); } /* diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c --- a/drivers/input/mousedev.c Fri Feb 14 00:27:30 2003 +++ b/drivers/input/mousedev.c Fri Feb 14 00:27:30 2003 @@ -454,7 +454,11 @@ .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) }, .relbit = { BIT(REL_X) | BIT(REL_Y) }, }, /* A mouse like device, at least one button, two relative axes */ - + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_RELBIT, + .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, + .relbit = { BIT(REL_WHEEL) }, + }, /* A separate scrollwheel */ { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c --- a/drivers/input/serio/ambakmi.c Fri Feb 14 00:27:29 2003 +++ b/drivers/input/serio/ambakmi.c Fri Feb 14 00:27:29 2003 @@ -23,8 +23,6 @@ #include #include -extern struct pt_regs *kbd_pt_regs; - #define KMI_BASE (kmi->base) struct amba_kmi_port { @@ -42,10 +40,8 @@ struct amba_kmi_port *kmi = dev_id; unsigned int status = __raw_readb(KMIIR); - kbd_pt_regs = regs; - while (status & KMIIR_RXINTR) { - serio_interrupt(&kmi->io, __raw_readb(KMIDATA), 0); + serio_interrupt(&kmi->io, __raw_readb(KMIDATA), 0, regs); status = __raw_readb(KMIIR); } } diff -Nru a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c --- a/drivers/input/serio/ct82c710.c Fri Feb 14 00:27:26 2003 +++ b/drivers/input/serio/ct82c710.c Fri Feb 14 00:27:26 2003 @@ -156,7 +156,7 @@ static void ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs) { - serio_interrupt(&ct82c710_port, inb(ct82c710_data), 0); + serio_interrupt(&ct82c710_port, inb(ct82c710_data), 0, regs); } /* diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c --- a/drivers/input/serio/i8042.c Fri Feb 14 00:27:27 2003 +++ b/drivers/input/serio/i8042.c Fri Feb 14 00:27:27 2003 @@ -62,8 +62,6 @@ static unsigned char i8042_mux_open; struct timer_list i8042_timer; -extern struct pt_regs *kbd_pt_regs; - static unsigned long i8042_unxlate_seen[256 / BITS_PER_LONG]; static unsigned char i8042_unxlate_table[128] = { 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13, @@ -345,10 +343,6 @@ } buffer[I8042_BUFFER_SIZE]; int i, j = 0; -#ifdef CONFIG_VT - kbd_pt_regs = regs; -#endif - spin_lock_irqsave(&i8042_lock, flags); while (j < I8042_BUFFER_SIZE && @@ -381,7 +375,7 @@ dfl & SERIO_PARITY ? ", bad parity" : "", dfl & SERIO_TIMEOUT ? ", timeout" : ""); - serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl); + serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, regs); continue; } @@ -391,7 +385,7 @@ dfl & SERIO_TIMEOUT ? ", timeout" : ""); if (i8042_aux_values.exists && (str & I8042_STR_AUXDATA)) { - serio_interrupt(&i8042_aux_port, data, dfl); + serio_interrupt(&i8042_aux_port, data, dfl, regs); continue; } @@ -399,7 +393,7 @@ continue; if (i8042_direct) { - serio_interrupt(&i8042_kbd_port, data, dfl); + serio_interrupt(&i8042_kbd_port, data, dfl, regs); continue; } @@ -408,7 +402,7 @@ if (index == 0xaa || index == 0xb6) set_bit(index, i8042_unxlate_seen); if (test_and_clear_bit(index, i8042_unxlate_seen)) { - serio_interrupt(&i8042_kbd_port, 0xf0, dfl); + serio_interrupt(&i8042_kbd_port, 0xf0, dfl, regs); data = i8042_unxlate_table[data & 0x7f]; } } else { @@ -418,7 +412,7 @@ i8042_last_e0 = (data == 0xe0); - serio_interrupt(&i8042_kbd_port, data, dfl); + serio_interrupt(&i8042_kbd_port, data, dfl, regs); } } diff -Nru a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c --- a/drivers/input/serio/parkbd.c Fri Feb 14 00:27:26 2003 +++ b/drivers/input/serio/parkbd.c Fri Feb 14 00:27:26 2003 @@ -136,7 +136,7 @@ parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++; if (parkbd_counter == parkbd_mode + 10) - serio_interrupt(&parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0); + serio_interrupt(&parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0, regs); } parkbd_last = jiffies; diff -Nru a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c --- a/drivers/input/serio/q40kbd.c Fri Feb 14 00:27:27 2003 +++ b/drivers/input/serio/q40kbd.c Fri Feb 14 00:27:27 2003 @@ -69,8 +69,7 @@ static void q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs) { if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)) - if (q40kbd_port.dev) - q40kbd_port.dev->interrupt(&q40kbd_port, master_inb(KEYCODE_REG), 0); + serio_interrupt(&q40kbd_port, master_inb(KEYCODE_REG), 0, regs); master_outb(-1, KEYBOARD_UNLOCK_REG); } diff -Nru a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c --- a/drivers/input/serio/rpckbd.c Fri Feb 14 00:27:26 2003 +++ b/drivers/input/serio/rpckbd.c Fri Feb 14 00:27:26 2003 @@ -44,8 +44,6 @@ MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver"); MODULE_LICENSE("GPL"); -extern struct pt_regs *kbd_pt_regs; - static int rpckbd_write(struct serio *port, unsigned char val) { while (!(iomd_readb(IOMD_KCTRL) & (1 << 7))) @@ -60,12 +58,11 @@ { struct serio *port = dev_id; unsigned int byte; - kbd_pt_regs = regs; while (iomd_readb(IOMD_KCTRL) & (1 << 5)) { byte = iomd_readb(IOMD_KARTRX); - serio_interrupt(port, byte, 0); + serio_interrupt(port, byte, 0, regs); } } diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c --- a/drivers/input/serio/sa1111ps2.c Fri Feb 14 00:27:28 2003 +++ b/drivers/input/serio/sa1111ps2.c Fri Feb 14 00:27:28 2003 @@ -24,8 +24,6 @@ #include -extern struct pt_regs *kbd_pt_regs; - struct ps2if { struct serio io; struct sa1111_dev *dev; @@ -47,8 +45,6 @@ struct ps2if *ps2if = dev_id; unsigned int scancode, flag, status; - kbd_pt_regs = regs; - status = sa1111_readl(ps2if->base + SA1111_PS2STAT); while (status & PS2STAT_RXF) { if (status & PS2STAT_STP) @@ -62,7 +58,7 @@ if (hweight8(scancode) & 1) flag ^= SERIO_PARITY; - serio_interrupt(&ps2if->io, scancode, flag); + serio_interrupt(&ps2if->io, scancode, flag, regs); status = sa1111_readl(ps2if->base + SA1111_PS2STAT); } diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c --- a/drivers/input/serio/serio.c Fri Feb 14 00:27:26 2003 +++ b/drivers/input/serio/serio.c Fri Feb 14 00:27:26 2003 @@ -105,8 +105,8 @@ static int serio_thread(void *nothing) { lock_kernel(); - daemonize(); - strcpy(current->comm, "kseriod"); + daemonize("kseriod"); + allow_signal(SIGTERM); do { serio_handle_events(); @@ -135,10 +135,10 @@ wake_up(&serio_wait); } -void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { if (serio->dev && serio->dev->interrupt) - serio->dev->interrupt(serio, data, flags); + serio->dev->interrupt(serio, data, flags, regs); else if (!flags) serio_rescan(serio); diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c --- a/drivers/input/serio/serport.c Fri Feb 14 00:27:30 2003 +++ b/drivers/input/serio/serport.c Fri Feb 14 00:27:30 2003 @@ -114,6 +114,9 @@ * serport_ldisc_receive() is called by the low level tty driver when characters * are ready for us. We forward the characters, one by one to the 'interrupt' * routine. + * + * FIXME: We should get pt_regs from the tty layer and forward them to + * serio_interrupt here. */ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) @@ -121,7 +124,7 @@ struct serport *serport = (struct serport*) tty->disc_data; int i; for (i = 0; i < count; i++) - serio_interrupt(&serport->serio, cp[i], 0); + serio_interrupt(&serport->serio, cp[i], 0, NULL); } /* diff -Nru a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c --- a/drivers/input/touchscreen/gunze.c Fri Feb 14 00:27:27 2003 +++ b/drivers/input/touchscreen/gunze.c Fri Feb 14 00:27:27 2003 @@ -60,7 +60,7 @@ char phys[32]; }; -static void gunze_process_packet(struct gunze* gunze) +static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs) { struct input_dev *dev = &gunze->dev; @@ -71,18 +71,19 @@ return; } + input_regs(dev, regs); input_report_abs(dev, ABS_X, simple_strtoul(gunze->data + 1, NULL, 10) * 4); input_report_abs(dev, ABS_Y, 3072 - simple_strtoul(gunze->data + 6, NULL, 10) * 3); input_report_key(dev, BTN_TOUCH, gunze->data[0] == 'T'); input_sync(dev); } -static void gunze_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +static void gunze_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct gunze* gunze = serio->private; if (data == '\r') { - gunze_process_packet(gunze); + gunze_process_packet(gunze, regs); gunze->idx = 0; } else { if (gunze->idx < GUNZE_MAX_LENGTH) diff -Nru a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c --- a/drivers/input/touchscreen/h3600_ts_input.c Fri Feb 14 00:27:29 2003 +++ b/drivers/input/touchscreen/h3600_ts_input.c Fri Feb 14 00:27:29 2003 @@ -108,6 +108,7 @@ int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1; struct input_dev *dev = (struct input_dev *) dev_id; + input_regs(dev, regs); input_report_key(dev, KEY_ENTER, down); input_sync(dev); } @@ -121,6 +122,7 @@ * This interrupt is only called when we release the key. So we have * to fake a key press. */ + input_regs(dev, regs); input_report_key(dev, KEY_SUSPEND, 1); input_report_key(dev, KEY_SUSPEND, down); input_sync(dev); @@ -183,11 +185,13 @@ * packets. Some packets coming from serial are not touchscreen related. In * this case we send them off to be processed elsewhere. */ -static void h3600ts_process_packet(struct h3600_dev *ts) +static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) { struct input_dev *dev = &ts->dev; static int touched = 0; int key, down = 0; + + input_regs(dev, regs); switch (ts->event) { /* diff -Nru a/drivers/isdn/hardware/eicon/diva.c b/drivers/isdn/hardware/eicon/diva.c --- a/drivers/isdn/hardware/eicon/diva.c Fri Feb 14 00:27:29 2003 +++ b/drivers/isdn/hardware/eicon/diva.c Fri Feb 14 00:27:29 2003 @@ -563,10 +563,11 @@ Requests[31] = DivaIdiRequest31; } +/* card: 1-based card number */ void diva_xdi_display_adapter_features(int card) { dword features; - if (!card || ((card - 1) > MAX_ADAPTER) || !IoAdapters[card - 1]) { + if (!card || ((card - 1) >= MAX_ADAPTER) || !IoAdapters[card - 1]) { return; } card--; diff -Nru a/drivers/isdn/hardware/eicon/i4l_idi.c b/drivers/isdn/hardware/eicon/i4l_idi.c --- a/drivers/isdn/hardware/eicon/i4l_idi.c Fri Feb 14 00:27:28 2003 +++ b/drivers/isdn/hardware/eicon/i4l_idi.c Fri Feb 14 00:27:28 2003 @@ -3057,7 +3057,7 @@ } timeout = jiffies + 50; - while (timeout > jiffies) { + while (time_before(jiffies, timeout)) { if (chan->e.B2Id) break; SLEEP(10); } @@ -3119,7 +3119,7 @@ eicon_tx_request(card); timeout = jiffies + 50; - while (timeout > jiffies) { + while (time_before(jiffies, timeout)) { if (chan->fsm_state) break; SLEEP(10); } diff -Nru a/drivers/isdn/hardware/eicon/i4lididrv.c b/drivers/isdn/hardware/eicon/i4lididrv.c --- a/drivers/isdn/hardware/eicon/i4lididrv.c Fri Feb 14 00:27:30 2003 +++ b/drivers/isdn/hardware/eicon/i4lididrv.c Fri Feb 14 00:27:30 2003 @@ -326,10 +326,7 @@ if(!(atomic_read(&thread_running))) break; if(signal_pending(current)) { - /* we may want to do something on signals here */ - spin_lock_irq(¤t->sigmask_lock); flush_signals(current); - spin_unlock_irq(¤t->sigmask_lock); } else { run_task_queue(&tq_divad); } diff -Nru a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c --- a/drivers/macintosh/adb.c Fri Feb 14 00:27:30 2003 +++ b/drivers/macintosh/adb.c Fri Feb 14 00:27:30 2003 @@ -244,12 +244,13 @@ static int adb_probe_task(void *x) { + sigset_t blocked; + strcpy(current->comm, "kadbprobe"); - - spin_lock_irq(¤t->sighand->siglock); - sigfillset(¤t->blocked); + + sigfillset(&blocked); + sicprocmask(SIG_BLOCK, &blocked, NULL); flush_signals(current); - spin_unlock_irq(¤t->sighand->siglock); printk(KERN_INFO "adb: starting probe task...\n"); do_adb_reset_bus(); diff -Nru a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c --- a/drivers/macintosh/adbhid.c Fri Feb 14 00:27:30 2003 +++ b/drivers/macintosh/adbhid.c Fri Feb 14 00:27:30 2003 @@ -52,8 +52,6 @@ #define KEYB_LEDREG 2 /* register # for leds on ADB keyboard */ #define MOUSE_DATAREG 0 /* reg# for movement/button codes from mouse */ -extern struct pt_regs *kbd_pt_regs; - static int adb_message_handler(struct notifier_block *, unsigned long, void *); static struct notifier_block adbhid_adb_notifier = { .notifier_call = adb_message_handler, @@ -136,14 +134,13 @@ /* first check this is from register 0 */ if (nb != 3 || (data[0] & 3) != KEYB_KEYREG) return; /* ignore it */ - kbd_pt_regs = regs; - adbhid_input_keycode(id, data[1], 0); + adbhid_input_keycode(id, data[1], 0, regs); if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f))) - adbhid_input_keycode(id, data[2], 0); + adbhid_input_keycode(id, data[2], 0, regs); } static void -adbhid_input_keycode(int id, int keycode, int repeat) +adbhid_input_keycode(int id, int keycode, int repeat, pt_regs *regs) { int up_flag; @@ -152,21 +149,24 @@ switch (keycode) { case 0x39: /* Generate down/up events for CapsLock everytime. */ + input_regs(&adbhid[id]->input, regs); input_report_key(&adbhid[id]->input, KEY_CAPSLOCK, 1); input_report_key(&adbhid[id]->input, KEY_CAPSLOCK, 0); + input_sync(&adbhid[id]->input); return; case 0x3f: /* ignore Powerbook Fn key */ return; } - if (adbhid[id]->keycode[keycode]) + if (adbhid[id]->keycode[keycode]) { + input_regs(&adbhid[id]->input, regs); input_report_key(&adbhid[id]->input, adbhid[id]->keycode[keycode], !up_flag); - else + input_sync(&adbhid[id]->input); + } else printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode, up_flag ? "released" : "pressed"); - input_sync(&adbhid[id]->input); } static void @@ -253,6 +253,8 @@ break; } + input_regs(&adbhid[id]->input, regs); + input_report_key(&adbhid[id]->input, BTN_LEFT, !((data[1] >> 7) & 1)); input_report_key(&adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1)); @@ -276,6 +278,8 @@ printk(KERN_ERR "ADB HID on ID %d not yet registered\n", id); return; } + + input_regs(&adbhid[id]->input, regs); switch (adbhid[id]->original_handler_id) { default: diff -Nru a/drivers/md/md.c b/drivers/md/md.c --- a/drivers/md/md.c Fri Feb 14 00:27:27 2003 +++ b/drivers/md/md.c Fri Feb 14 00:27:27 2003 @@ -2444,9 +2444,7 @@ static inline void flush_curr_signals(void) { - spin_lock(¤t->sighand->siglock); flush_signals(current); - spin_unlock(¤t->sighand->siglock); } int md_thread(void * arg) @@ -2459,12 +2457,10 @@ * Detach thread */ - daemonize(); + daemonize(thread->name); - sprintf(current->comm, thread->name); current->exit_signal = SIGCHLD; - siginitsetinv(¤t->blocked, sigmask(SIGKILL)); - flush_curr_signals(); + allow_signal(SIGKILL); thread->tsk = current; /* diff -Nru a/drivers/media/dvb/av7110/av7110.c b/drivers/media/dvb/av7110/av7110.c --- a/drivers/media/dvb/av7110/av7110.c Fri Feb 14 00:27:26 2003 +++ b/drivers/media/dvb/av7110/av7110.c Fri Feb 14 00:27:26 2003 @@ -349,13 +349,13 @@ lock_kernel(); #if 0 - daemonize(); + daemonize("arm_mon"); #else exit_mm(current); current->session=current->pgrp=1; -#endif sigfillset(¤t->blocked); strcpy(current->comm, "arm_mon"); +#endif av7110->arm_thread = current; unlock_kernel(); @@ -3243,7 +3243,7 @@ u16 handle; handle=dvbdmxfilter->hw_handle; - if (handle>32) { + if (handle >= MAXFILT) { dprintk("dvb: StopHWFilter tried to stop invalid filter %d.\n", handle); dprintk("dvb: filter type = %d\n", dvbdmxfilter->type); @@ -4408,7 +4408,7 @@ dvbdemux->priv=(void *) av7110; if (av7110->saa->card_type==DVB_CARD_TT_SIEMENS) { - for (i=0; i<32; i++) + for (i = 0; i < MAXFILT; i++) av7110->handle2filter[i]=NULL; dvbdemux->filternum=32; diff -Nru a/drivers/media/dvb/av7110/av7110.h b/drivers/media/dvb/av7110/av7110.h --- a/drivers/media/dvb/av7110/av7110.h Fri Feb 14 00:27:29 2003 +++ b/drivers/media/dvb/av7110/av7110.h Fri Feb 14 00:27:29 2003 @@ -580,7 +580,7 @@ #define TRICK_FREEZE 3 struct audio_status audiostate; - struct dvb_demux_filter *handle2filter[32]; + struct dvb_demux_filter *handle2filter[MAXFILT]; p2t_t p2t_filter[MAXFILT]; dvb_filter_pes2ts_t p2t[2]; struct ipack_s ipack[2]; diff -Nru a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c --- a/drivers/media/dvb/dvb-core/dvb_frontend.c Fri Feb 14 00:27:27 2003 +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c Fri Feb 14 00:27:27 2003 @@ -482,9 +482,7 @@ dprintk ("%s\n", __FUNCTION__); lock_kernel (); - daemonize (); - sigfillset (¤t->blocked); - strncpy (current->comm, "kdvb-fe", sizeof (current->comm)); + daemonize("kdvb-fe"); fe->thread = current; unlock_kernel (); diff -Nru a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c --- a/drivers/media/video/bttv-cards.c Fri Feb 14 00:27:28 2003 +++ b/drivers/media/video/bttv-cards.c Fri Feb 14 00:27:28 2003 @@ -2172,8 +2172,9 @@ tuner = eeprom_data[9]; radio = eeprom_data[blk2-1] & 0x01; - if (tuner < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) - btv->tuner_type = hauppauge_tuner[tuner].id; + if (tuner >= ARRAY_SIZE(hauppauge_tuner)) + tuner = 0; + btv->tuner_type = hauppauge_tuner[tuner].id; if (radio) btv->has_radio = 1; diff -Nru a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c --- a/drivers/media/video/msp3400.c Fri Feb 14 00:27:29 2003 +++ b/drivers/media/video/msp3400.c Fri Feb 14 00:27:29 2003 @@ -755,9 +755,7 @@ lock_kernel(); #endif - daemonize(); - sigfillset(¤t->blocked); - strcpy(current->comm,"msp3400"); + daemonize("msp3400"); msp->thread = current; @@ -1011,9 +1009,7 @@ lock_kernel(); #endif - daemonize(); - sigfillset(¤t->blocked); - strcpy(current->comm,"msp3410 [auto]"); + daemonize("msp3410 [auto]"); msp->thread = current; diff -Nru a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c --- a/drivers/media/video/saa5249.c Fri Feb 14 00:27:29 2003 +++ b/drivers/media/video/saa5249.c Fri Feb 14 00:27:29 2003 @@ -254,21 +254,19 @@ static struct i2c_driver i2c_driver_videotext = { - IF_NAME, /* name */ - I2C_DRIVERID_SAA5249, /* in i2c.h */ - I2C_DF_NOTIFY, - saa5249_probe, - saa5249_detach, - saa5249_command + .owner = THIS_MODULE, + .name = IF_NAME, /* name */ + .id = I2C_DRIVERID_SAA5249, /* in i2c.h */ + .flags = I2C_DF_NOTIFY, + .attach_adapter = saa5249_probe, + .detach_client = saa5249_detach, + .command = saa5249_command }; static struct i2c_client client_template = { - "(unset)", - -1, - 0, - 0, - NULL, - &i2c_driver_videotext + .name = "(unset)", + .id = -1, + .driver = &i2c_driver_videotext }; /* diff -Nru a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c --- a/drivers/media/video/saa7110.c Fri Feb 14 00:27:26 2003 +++ b/drivers/media/video/saa7110.c Fri Feb 14 00:27:26 2003 @@ -381,20 +381,18 @@ static struct i2c_driver i2c_driver_saa7110 = { - IF_NAME, /* name */ - I2C_DRIVERID_SAA7110, /* in i2c.h */ - I2C_DF_NOTIFY, /* Addr range */ - saa7110_probe, - saa7110_detach, - saa7110_command + .owner = THIS_MODULE, + .name = IF_NAME, /* name */ + .id = I2C_DRIVERID_SAA7110, /* in i2c.h */ + .flags = I2C_DF_NOTIFY, /* Addr range */ + .attach_adapter = saa7110_probe, + .detach_client = saa7110_detach, + .command = saa7110_command }; static struct i2c_client client_template = { - "saa7110_client", - -1, - 0, - 0, - NULL, - &i2c_driver_saa7110 + .name = "saa7110_client", + .id = -1, + .driver = &i2c_driver_saa7110 }; static int saa7110_init(void) diff -Nru a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c --- a/drivers/media/video/saa7134/saa7134-tvaudio.c Fri Feb 14 00:27:26 2003 +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c Fri Feb 14 00:27:26 2003 @@ -393,9 +393,7 @@ int i,max,carrier,audio; lock_kernel(); - daemonize(); - sigfillset(¤t->blocked); - sprintf(current->comm, "%s", dev->name); + daemonize("%s", dev->name); dev->thread.task = current; unlock_kernel(); if (dev->thread.notify != NULL) diff -Nru a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c --- a/drivers/media/video/tvaudio.c Fri Feb 14 00:27:27 2003 +++ b/drivers/media/video/tvaudio.c Fri Feb 14 00:27:27 2003 @@ -272,9 +272,7 @@ #ifdef CONFIG_SMP lock_kernel(); #endif - daemonize(); - sigfillset(¤t->blocked); - strcpy(current->comm,chip->c.name); + daemonize("%s", chip->c.name); chip->thread = current; #ifdef CONFIG_SMP unlock_kernel(); diff -Nru a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c --- a/drivers/message/i2o/i2o_block.c Fri Feb 14 00:27:29 2003 +++ b/drivers/message/i2o/i2o_block.c Fri Feb 14 00:27:29 2003 @@ -629,11 +629,9 @@ u8 data[16]; } *evt_local; - lock_kernel(); - daemonize(); - unlock_kernel(); + daemonize("i2oblock"); + allow_signal(SIGKILL); - strcpy(current->comm, "i2oblock"); evt_running = 1; while(1) diff -Nru a/drivers/message/i2o/i2o_core.c b/drivers/message/i2o/i2o_core.c --- a/drivers/message/i2o/i2o_core.c Fri Feb 14 00:27:29 2003 +++ b/drivers/message/i2o/i2o_core.c Fri Feb 14 00:27:29 2003 @@ -879,11 +879,9 @@ struct i2o_controller *c = NULL; unsigned long flags; - lock_kernel(); - daemonize(); - unlock_kernel(); + daemonize("i2oevtd"); + allow_signal(SIGKILL); - strcpy(current->comm, "i2oevtd"); evt_running = 1; while(1) @@ -1047,15 +1045,10 @@ int found = 0; int entries; void *tmp; - char name[16]; - lock_kernel(); - daemonize(); - unlock_kernel(); + daemonize("iop%d_lctd", c->unit); + allow_signal(SIGKILL); - sprintf(name, "iop%d_lctd", c->unit); - strcpy(current->comm, name); - c->lct_running = 1; while(1) @@ -3060,7 +3053,7 @@ "PROGRESS_REPORT" }; - if (req_status > I2O_REPLY_STATUS_PROGRESS_REPORT) + if (req_status >= ARRAY_SIZE(REPLY_STATUS)) printk("RequestStatus = %0#2x", req_status); else printk("%s", REPLY_STATUS[req_status]); diff -Nru a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c --- a/drivers/mtd/devices/blkmtd.c Fri Feb 14 00:27:26 2003 +++ b/drivers/mtd/devices/blkmtd.c Fri Feb 14 00:27:26 2003 @@ -303,12 +303,7 @@ DECLARE_WAITQUEUE(wait, tsk); DEBUG(1, "blkmtd: writetask: starting (pid = %d)\n", tsk->pid); - daemonize(); - strcpy(tsk->comm, "blkmtdd"); - spin_lock_irq(&tsk->sighand->siglock); - sigfillset(&tsk->blocked); - recalc_sigpending(); - spin_unlock_irq(&tsk->sighand->siglock); + daemonize("blkmtdd"); if(alloc_kiovec(1, &iobuf)) { printk("blkmtd: write_queue_task cant allocate kiobuf\n"); diff -Nru a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c --- a/drivers/mtd/mtdblock.c Fri Feb 14 00:27:27 2003 +++ b/drivers/mtd/mtdblock.c Fri Feb 14 00:27:27 2003 @@ -452,12 +452,7 @@ /* we might get involved when memory gets low, so use PF_MEMALLOC */ tsk->flags |= PF_MEMALLOC; - strcpy(tsk->comm, "mtdblockd"); - spin_lock_irq(&tsk->sighand->siglock); - sigfillset(&tsk->blocked); - recalc_sigpending(); - spin_unlock_irq(&tsk->sighand->siglock); - daemonize(); + daemonize("mtdblockd"); while (!leaving) { add_wait_queue(&thr_wq, &wait); diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c --- a/drivers/net/3c509.c Fri Feb 14 00:27:26 2003 +++ b/drivers/net/3c509.c Fri Feb 14 00:27:26 2003 @@ -338,16 +338,6 @@ dev->watchdog_timeo = TX_TIMEOUT; dev->do_ioctl = netdev_ioctl; -#ifdef CONFIG_PM - /* register power management */ - lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback); - if (lp->pmdev) { - struct pm_dev *p; - p = lp->pmdev; - p->data = (struct net_device *)dev; - } -#endif - return 0; } @@ -417,6 +407,13 @@ phys_addr[j] = htons(read_eeprom(ioaddr, j)); if_port = read_eeprom(ioaddr, 8) >> 14; + if (!(dev = init_etherdev(NULL, sizeof(struct el3_private)))) { + release_region(ioaddr, EL3_IO_EXTENT); + pnp_device_detach(idev); + return -ENOMEM; + } + + SET_MODULE_OWNER(dev); pnp_cards++; goto found; } @@ -497,24 +494,29 @@ } irq = id_read_eeprom(9) >> 12; -#if 0 /* Huh ? - Can someone explain what is this for ? */ - if (dev) { /* Set passed-in IRQ or I/O Addr. */ - if (dev->irq > 1 && dev->irq < 16) + if (!(dev = init_etherdev(NULL, sizeof(struct el3_private)))) + return -ENOMEM; + + SET_MODULE_OWNER(dev); + + /* Set passed-in IRQ or I/O Addr. */ + if (dev->irq > 1 && dev->irq < 16) irq = dev->irq; - if (dev->base_addr) { + if (dev->base_addr) { if (dev->mem_end == 0x3c509 /* Magic key */ && dev->base_addr >= 0x200 && dev->base_addr <= 0x3e0) - ioaddr = dev->base_addr & 0x3f0; - else if (dev->base_addr != ioaddr) - return -ENODEV; - } + ioaddr = dev->base_addr & 0x3f0; + else if (dev->base_addr != ioaddr) { + unregister_netdev (dev); + return -ENODEV; + } } -#endif - if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) - return -EBUSY; + if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) { + unregister_netdev (dev); + return -EBUSY; + } /* Set the adaptor tag so that the next card can be found. */ outb(0xd0 + ++current_tag, id_port); @@ -524,6 +526,7 @@ EL3WINDOW(0); if (inw(ioaddr) != 0x6d50) { + unregister_netdev (dev); release_region(ioaddr, EL3_IO_EXTENT); return -ENODEV; } @@ -531,12 +534,9 @@ /* Free the interrupt so that some other card can use it. */ outw(0x0f00, ioaddr + WN0_IRQ); - dev = init_etherdev(NULL, sizeof(struct el3_private)); - if (dev == NULL) { - release_region(ioaddr, EL3_IO_EXTENT); - return -ENOMEM; - } - SET_MODULE_OWNER(dev); +#ifdef __ISAPNP__ + found: /* PNP jumps here... */ +#endif /* __ISAPNP__ */ memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); dev->base_addr = ioaddr; @@ -547,6 +547,16 @@ lp->dev = &idev->dev; #endif +#ifdef CONFIG_PM + /* register power management */ + lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback); + if (lp->pmdev) { + struct pm_dev *p; + p = lp->pmdev; + p->data = (struct net_device *)dev; + } +#endif + return el3_common_init (dev); } @@ -667,6 +677,7 @@ } #endif +#if defined(CONFIG_EISA) || defined(CONFIG_MCA) /* This remove works for all device types. * * The net dev must be stored in the driver_data field */ @@ -679,6 +690,7 @@ el3_common_remove (dev); return 0; } +#endif /* Read a word from the EEPROM using the regular EEPROM access register. Assume that we are in register window zero. diff -Nru a/drivers/net/3c59x.c b/drivers/net/3c59x.c --- a/drivers/net/3c59x.c Fri Feb 14 00:27:26 2003 +++ b/drivers/net/3c59x.c Fri Feb 14 00:27:26 2003 @@ -181,7 +181,7 @@ - See http://www.zip.com.au/~akpm/linux/#3c59x-2.3 for more details. - Also see Documentation/networking/vortex.txt - LK1.1.19 10Nov09 Marc Zyngier + LK1.1.19 10Nov02 Marc Zyngier - EISA sysfs integration. */ @@ -817,7 +817,11 @@ u32 power_state[16]; }; +#ifdef CONFIG_PCI #define DEVICE_PCI(dev) (((dev)->bus == &pci_bus_type) ? to_pci_dev((dev)) : NULL) +#else +#define DEVICE_PCI(dev) NULL +#endif #define VORTEX_PCI(vp) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL) diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c --- a/drivers/net/8139too.c Fri Feb 14 00:27:26 2003 +++ b/drivers/net/8139too.c Fri Feb 14 00:27:26 2003 @@ -1588,14 +1588,8 @@ struct rtl8139_private *tp = dev->priv; unsigned long timeout; - daemonize(); - spin_lock_irq(¤t->sighand->siglock); - sigemptyset(¤t->blocked); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - strncpy (current->comm, dev->name, sizeof(current->comm) - 1); - current->comm[sizeof(current->comm) - 1] = '\0'; + daemonize("%s", dev->name); + allow_signal(SIGKILL); while (1) { timeout = next_tick; @@ -1604,9 +1598,7 @@ } while (!signal_pending (current) && (timeout > 0)); if (signal_pending (current)) { - spin_lock_irq(¤t->sighand->siglock); flush_signals(current); - spin_unlock_irq(¤t->sighand->siglock); } if (tp->time_to_die) diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig --- a/drivers/net/Kconfig Fri Feb 14 00:27:29 2003 +++ b/drivers/net/Kconfig Fri Feb 14 00:27:29 2003 @@ -1258,6 +1258,18 @@ say M here and read . This is recommended. The module will be called starfire. +config ADAPTEC_STARFIRE_NAPI + bool "Use Rx Polling (NAPI) (EXPERIMENTAL)" + depends on ADAPTEC_STARFIRE && EXPERIMENTAL + help + NAPI is a new driver API designed to reduce CPU and interrupt load + when the driver is receiving lots of packets from the card. It is + still somewhat experimental and thus not yet enabled by default. + + If your estimated Rx load is 10kpps or more, or if the card will be + deployed on potentially unfriendly networks (e.g. in a firewall), + then say Y here. + config AC3200 tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)" depends on NET_PCI && (ISA || EISA) && EXPERIMENTAL diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c --- a/drivers/net/Space.c Fri Feb 14 00:27:27 2003 +++ b/drivers/net/Space.c Fri Feb 14 00:27:27 2003 @@ -224,9 +224,6 @@ #ifdef CONFIG_EL2 /* 3c503 */ {el2_probe, 0}, #endif -#ifdef CONFIG_EL3 - {el3_probe, 0}, -#endif #ifdef CONFIG_HPLAN {hp_probe, 0}, #endif diff -Nru a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c --- a/drivers/net/amd8111e.c Fri Feb 14 00:27:28 2003 +++ b/drivers/net/amd8111e.c Fri Feb 14 00:27:28 2003 @@ -953,7 +953,7 @@ reg_buff = kmalloc( AMD8111E_REG_DUMP_LEN,GFP_KERNEL); if(NULL == reg_buff) return NULL; - for( i=0; i< AMD8111E_REG_DUMP_LEN;i+=4); + for (i=0; i < AMD8111E_REG_DUMP_LEN; i+=4) reg_buff[i]= readl(mmio + i); return reg_buff; } diff -Nru a/drivers/net/arlan.c b/drivers/net/arlan.c --- a/drivers/net/arlan.c Fri Feb 14 00:27:29 2003 +++ b/drivers/net/arlan.c Fri Feb 14 00:27:29 2003 @@ -1124,24 +1124,6 @@ return -ENODEV; } -static int __init arlan_find_devices(void) -{ - int m; - int found = 0; - - ARLAN_DEBUG_ENTRY("arlan_find_devices"); - if (mem != 0 && numDevices == 1) /* Check a single specified location. */ - return 1; - for (m =(int) phys_to_virt(0xc0000); m <=(int) phys_to_virt(0xDE000); m += 0x2000) - { - if (arlan_check_fingerprint(m) == 0) - found++; - } - ARLAN_DEBUG_EXIT("arlan_find_devices"); - - return found; -} - static int arlan_change_mtu(struct net_device *dev, int new_mtu) { @@ -1199,7 +1181,7 @@ return 0; } ap = dev->priv; - ap->config = dev->priv + sizeof(struct arlan_private); + ap->conf = dev->priv + sizeof(struct arlan_private); ap->init_etherdev_alloc = 1; } else { dev = devs; @@ -1209,7 +1191,7 @@ return 0; } ap = dev->priv; - ap->config = dev->priv + sizeof(struct arlan_private); + ap->conf = dev->priv + sizeof(struct arlan_private); memset(ap, 0, sizeof(*ap)); } @@ -2007,6 +1989,24 @@ #ifdef MODULE +static int __init arlan_find_devices(void) +{ + int m; + int found = 0; + + ARLAN_DEBUG_ENTRY("arlan_find_devices"); + if (mem != 0 && numDevices == 1) /* Check a single specified location. */ + return 1; + for (m =(int) phys_to_virt(0xc0000); m <=(int) phys_to_virt(0xDE000); m += 0x2000) + { + if (arlan_check_fingerprint(m) == 0) + found++; + } + ARLAN_DEBUG_EXIT("arlan_find_devices"); + + return found; +} + int init_module(void) { int i = 0; @@ -2045,7 +2045,7 @@ void cleanup_module(void) { int i = 0; - struct arlan_private ap; + struct arlan_private *ap; ARLAN_DEBUG_ENTRY("cleanup_module"); diff -Nru a/drivers/net/fc/iph5526.c b/drivers/net/fc/iph5526.c --- a/drivers/net/fc/iph5526.c Fri Feb 14 00:27:27 2003 +++ b/drivers/net/fc/iph5526.c Fri Feb 14 00:27:27 2003 @@ -3769,7 +3769,7 @@ for (i = 0; i <= MAX_FC_CARDS; i++) fc[i] = NULL; - for (i = 0; i < clone_list[i].vendor_id != 0; i++) + for (i = 0; clone_list[i].vendor_id != 0; i++) while ((pdev = pci_find_device(clone_list[i].vendor_id, clone_list[i].device_id, pdev))) { unsigned short pci_command; if (pci_enable_device(pdev)) diff -Nru a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c --- a/drivers/net/hamradio/scc.c Fri Feb 14 00:27:29 2003 +++ b/drivers/net/hamradio/scc.c Fri Feb 14 00:27:29 2003 @@ -1763,7 +1763,7 @@ if (hwcfg.irq == 2) hwcfg.irq = 9; - if (hwcfg.irq <0 || hwcfg.irq > NR_IRQS) + if (hwcfg.irq < 0 || hwcfg.irq >= NR_IRQS) return -EINVAL; if (!Ivec[hwcfg.irq].used && hwcfg.irq) diff -Nru a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c --- a/drivers/net/hamradio/yam.c Fri Feb 14 00:27:29 2003 +++ b/drivers/net/hamradio/yam.c Fri Feb 14 00:27:29 2003 @@ -350,7 +350,7 @@ wrd <<= 1; outb(0xfc, THR(iobase)); while ((inb(LSR(iobase)) & LSR_TSRE) == 0) - if (jiffies > timeout) + if (time_after(jiffies, timeout)) return -1; } diff -Nru a/drivers/net/irda/sir_kthread.c b/drivers/net/irda/sir_kthread.c --- a/drivers/net/irda/sir_kthread.c Fri Feb 14 00:27:29 2003 +++ b/drivers/net/irda/sir_kthread.c Fri Feb 14 00:27:29 2003 @@ -113,13 +113,7 @@ { DECLARE_WAITQUEUE(wait, current); - daemonize(); - strcpy(current->comm, "kIrDAd"); - - spin_lock_irq(¤t->sighand->siglock); - sigfillset(¤t->blocked); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + daemonize("kIrDAd"); set_fs(KERNEL_DS); diff -Nru a/drivers/net/irda/smc-ircc.c b/drivers/net/irda/smc-ircc.c --- a/drivers/net/irda/smc-ircc.c Fri Feb 14 00:27:26 2003 +++ b/drivers/net/irda/smc-ircc.c Fri Feb 14 00:27:26 2003 @@ -469,7 +469,7 @@ "firport 0x%03x, sirport 0x%03x dma=%d, irq=%d\n", chip & 0x0f, version, fir_base, sir_base, dma, irq); - if (dev_count>DIM(dev_self)) { + if (dev_count >= DIM(dev_self)) { IRDA_DEBUG(0, "%s(), to many devices!\n", __FUNCTION__ ); return -ENOMEM; diff -Nru a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c --- a/drivers/net/pcmcia/xirc2ps_cs.c Fri Feb 14 00:27:28 2003 +++ b/drivers/net/pcmcia/xirc2ps_cs.c Fri Feb 14 00:27:28 2003 @@ -447,7 +447,7 @@ u_long flags; save_flags(flags); sti(); - while (timeout >= jiffies) + while (time_before_eq(jiffies, timeout)) ; restore_flags(flags); } else { diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c --- a/drivers/net/sis900.c Fri Feb 14 00:27:28 2003 +++ b/drivers/net/sis900.c Fri Feb 14 00:27:28 2003 @@ -591,7 +591,7 @@ yield(); poll_bit ^= (mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS) & poll_bit); - if (jiffies >= timeout) { + if (time_after_eq(jiffies, timeout)) { printk(KERN_WARNING "%s: reset phy and link down now\n", net_dev->name); return -ETIME; } diff -Nru a/drivers/net/starfire.c b/drivers/net/starfire.c --- a/drivers/net/starfire.c Fri Feb 14 00:27:27 2003 +++ b/drivers/net/starfire.c Fri Feb 14 00:27:27 2003 @@ -4,7 +4,7 @@ Current maintainer is Ion Badulescu . Please send all bug reports to me, and not to Donald Becker, as this code - has been modified quite a bit from Donald's original version. + has been heavily modified from Donald's original version. This software may be used and distributed according to the terms of the GNU General Public License (GPL), incorporated herein by reference. @@ -13,6 +13,8 @@ a complete program and may only be used when the entire operating system is licensed under the GPL. + The information below comes from Donald Becker's original driver: + The author may be reached as becker@scyld.com, or C/O Scyld Computing Corporation 410 Severn Ave., Suite 210 @@ -101,15 +103,40 @@ - Better stats and error handling (Ion Badulescu) - Use new pci_set_mwi() PCI API function (jgarzik) -TODO: - - implement tx_timeout() properly + LK1.3.7 (Ion Badulescu) + - minimal implementation of tx_timeout() + - correctly shutdown the Rx/Tx engines in netdev_close() + - added calls to netif_carrier_on/off + (patch from Stefan Rompf ) - VLAN support + + LK1.3.8 (Ion Badulescu) + - adjust DMA burst size on sparc64 + - 64-bit support + - reworked zerocopy support for 64-bit buffers + - working and usable interrupt mitigation/latency + - reduced Tx interrupt frequency for lower interrupt overhead + + LK1.3.9 (Ion Badulescu) + - bugfix for mcast filter + - enable the right kind of Tx interrupts (TxDMADone, not TxDone) + + LK1.4.0 (Ion Badulescu) + - NAPI support + + LK1.4.1 (Ion Badulescu) + - flush PCI posting buffers after disabling Rx interrupts + - put the chip to a D3 slumber on driver unload + - added config option to enable/disable NAPI + +TODO: bugfixes (no bugs known as of right now) */ #define DRV_NAME "starfire" -#define DRV_VERSION "1.03+LK1.3.6" -#define DRV_RELDATE "March 7, 2002" +#define DRV_VERSION "1.03+LK1.4.1" +#define DRV_RELDATE "February 10, 2002" +#include #include #include #include @@ -118,27 +145,23 @@ #include #include #include -#include #include /* Processor type for cache alignment. */ #include #include /* - * Adaptec's license for their Novell drivers (which is where I got the + * Adaptec's license for their drivers (which is where I got the * firmware files) does not allow one to redistribute them. Thus, we can't * include the firmware with this driver. * - * However, an end-user is allowed to download and use it, after - * converting it to C header files using starfire_firmware.pl. + * However, should a legal-to-distribute firmware become available, + * the driver developer would need only to obtain the firmware in the + * form of a C header file. * Once that's done, the #undef below must be changed into a #define * for this driver to really use the firmware. Note that Rx/Tx * hardware TCP checksumming is not possible without the firmware. * - * If Adaptec could allow redistribution of the firmware (even in binary - * format), life would become a lot easier. Unfortunately, I've lost my - * Adaptec contacts, so progress on this front is rather unlikely to - * occur. If anybody from Adaptec reads this and can help with this matter, - * please let me know... + * WANTED: legal firmware to include with this GPL'd driver. */ #undef HAS_FIRMWARE /* @@ -157,11 +180,20 @@ #include "starfire_firmware.h" #endif /* HAS_FIRMWARE */ +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#define VLAN_SUPPORT +#endif + +#ifndef CONFIG_ADAPTEC_STARFIRE_NAPI +#undef HAVE_NETDEV_POLL +#endif + /* The user-configurable values. These may be modified when a driver module is loaded.*/ /* Used for tuning interrupt latency vs. overhead. */ -static int interrupt_mitigation; +static int intr_latency; +static int small_frames; static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ static int max_interrupt_work = 20; @@ -169,6 +201,12 @@ /* Maximum number of multicast addresses to filter (vs. rx-all-multicast). The Starfire has a 512 element hash table based on the Ethernet CRC. */ static int multicast_filter_limit = 512; +/* Whether to do TCP/UDP checksums in hardware */ +#ifdef HAS_FIRMWARE +static int enable_hw_cksum = 1; +#else +static int enable_hw_cksum = 0; +#endif #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ /* @@ -181,7 +219,9 @@ * packets as the starfire doesn't allow for misaligned DMAs ;-( * 23/10/2000 - Jes * - * The Alpha and the Sparc don't allow unaligned loads, either. -Ion + * The Alpha and the Sparc don't like unaligned loads, either. On Sparc64, + * at least, having unaligned frames leads to a rather serious performance + * penalty. -Ion */ #if defined(__ia64__) || defined(__alpha__) || defined(__sparc__) static int rx_copybreak = PKT_BUF_SZ; @@ -189,9 +229,17 @@ static int rx_copybreak /* = 0 */; #endif +/* PCI DMA burst size -- on sparc64 we want to force it to 64 bytes, on the others the default of 128 is fine. */ +#ifdef __sparc__ +#define DMA_BURST_SIZE 64 +#else +#define DMA_BURST_SIZE 128 +#endif + /* Used to pass the media type, etc. Both 'options[]' and 'full_duplex[]' exist for driver interoperability. The media type is usually passed in 'options[]'. + These variables are deprecated, use ethtool instead. -Ion */ #define MAX_UNITS 8 /* More are supported, limit only on options */ static int options[MAX_UNITS] = {0, }; @@ -201,33 +249,55 @@ /* The "native" ring sizes are either 256 or 2048. However in some modes a descriptor may be marked to wrap the ring earlier. - The driver allocates a single page for each descriptor ring, constraining - the maximum size in an architecture-dependent way. */ #define RX_RING_SIZE 256 #define TX_RING_SIZE 32 /* The completion queues are fixed at 1024 entries i.e. 4K or 8KB. */ #define DONE_Q_SIZE 1024 +/* All queues must be aligned on a 256-byte boundary */ +#define QUEUE_ALIGN 256 + +#if RX_RING_SIZE > 256 +#define RX_Q_ENTRIES Rx2048QEntries +#else +#define RX_Q_ENTRIES Rx256QEntries +#endif /* Operational parameters that usually are not changed. */ /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (2 * HZ) -#ifdef ZEROCOPY -#if MAX_SKB_FRAGS <= 6 -#define MAX_STARFIRE_FRAGS 6 -#else /* MAX_STARFIRE_FRAGS > 6 */ -#warning This driver will not work with more than 6 skb fragments. -#warning Turning off zerocopy support. -#undef ZEROCOPY -#endif /* MAX_STARFIRE_FRAGS > 6 */ -#endif /* ZEROCOPY */ +/* + * This SUCKS. + * We need a much better method to determine if dma_addr_t is 64-bit. + */ +#if (defined(__i386__) && defined(CONFIG_HIGHMEM) && (LINUX_VERSION_CODE > 0x20500 || defined(CONFIG_HIGHMEM64G))) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) +/* 64-bit dma_addr_t */ +#define ADDR_64BITS /* This chip uses 64 bit addresses. */ +#define cpu_to_dma(x) cpu_to_le64(x) +#define dma_to_cpu(x) le64_to_cpu(x) +#define RX_DESC_Q_ADDR_SIZE RxDescQAddr64bit +#define TX_DESC_Q_ADDR_SIZE TxDescQAddr64bit +#define RX_COMPL_Q_ADDR_SIZE RxComplQAddr64bit +#define TX_COMPL_Q_ADDR_SIZE TxComplQAddr64bit +#define RX_DESC_ADDR_SIZE RxDescAddr64bit +#else /* 32-bit dma_addr_t */ +#define cpu_to_dma(x) cpu_to_le32(x) +#define dma_to_cpu(x) le32_to_cpu(x) +#define RX_DESC_Q_ADDR_SIZE RxDescQAddr32bit +#define TX_DESC_Q_ADDR_SIZE TxDescQAddr32bit +#define RX_COMPL_Q_ADDR_SIZE RxComplQAddr32bit +#define TX_COMPL_Q_ADDR_SIZE TxComplQAddr32bit +#define RX_DESC_ADDR_SIZE RxDescAddr32bit +#endif -#ifdef ZEROCOPY +#ifdef MAX_SKB_FRAGS #define skb_first_frag_len(skb) skb_headlen(skb) -#else /* not ZEROCOPY */ +#define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1) +#else /* not MAX_SKB_FRAGS */ #define skb_first_frag_len(skb) (skb->len) -#endif /* not ZEROCOPY */ +#define skb_num_frags(skb) 1 +#endif /* not MAX_SKB_FRAGS */ /* 2.2.x compatibility code */ #if LINUX_VERSION_CODE < 0x20300 @@ -236,9 +306,12 @@ #else /* LINUX_VERSION_CODE > 0x20300 */ +#include #include #include +#include + #define COMPAT_MOD_INC_USE_COUNT #define COMPAT_MOD_DEC_USE_COUNT @@ -253,6 +326,43 @@ #define PCI_SLOT_NAME(pci_dev) (pci_dev)->slot_name #endif /* LINUX_VERSION_CODE > 0x20300 */ + +#ifdef HAVE_NETDEV_POLL +#define init_poll(dev) \ + dev->poll = &netdev_poll; \ + dev->weight = max_interrupt_work; +#define netdev_rx(dev, ioaddr) \ +do { \ + u32 intr_enable; \ + if (netif_rx_schedule_prep(dev)) { \ + __netif_rx_schedule(dev); \ + intr_enable = readl(ioaddr + IntrEnable); \ + intr_enable &= ~(IntrRxDone | IntrRxEmpty); \ + writel(intr_enable, ioaddr + IntrEnable); \ + readl(ioaddr + IntrEnable); \ /* flush PCI posting buffers */ + } else { \ + /* Paranoia check */ \ + intr_enable = readl(ioaddr + IntrEnable); \ + if (intr_enable & (IntrRxDone | IntrRxEmpty)) { \ + printk("%s: interrupt while in polling mode!\n", dev->name); \ + intr_enable &= ~(IntrRxDone | IntrRxEmpty); \ + writel(intr_enable, ioaddr + IntrEnable); \ + } \ + } \ +} while (0) +#define netdev_receive_skb(skb) netif_receive_skb(skb) +#define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_receive_skb(skb, vlgrp, vlid) +static int netdev_poll(struct net_device *dev, int *budget); +#else /* not HAVE_NETDEV_POLL */ +#define init_poll(dev) +#define netdev_receive_skb(skb) netif_rx(skb) +#define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_rx(skb, vlgrp, vlid) +#define netdev_rx(dev, ioaddr) \ +do { \ + int quota = np->dirty_rx + RX_RING_SIZE - np->cur_rx; \ + __netdev_rx(dev, "a);\ +} while (0) +#endif /* not HAVE_NETDEV_POLL */ /* end of compatibility code */ @@ -269,15 +379,20 @@ MODULE_PARM(mtu, "i"); MODULE_PARM(debug, "i"); MODULE_PARM(rx_copybreak, "i"); -MODULE_PARM(interrupt_mitigation, "i"); +MODULE_PARM(intr_latency, "i"); +MODULE_PARM(small_frames, "i"); MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); -MODULE_PARM_DESC(max_interrupt_work, "Starfire maximum events handled per interrupt"); -MODULE_PARM_DESC(mtu, "Starfire MTU (all boards)"); -MODULE_PARM_DESC(debug, "Starfire debug level (0-6)"); -MODULE_PARM_DESC(rx_copybreak, "Starfire copy breakpoint for copy-only-tiny-frames"); -MODULE_PARM_DESC(options, "Starfire: Bits 0-3: media type, bit 17: full duplex"); -MODULE_PARM_DESC(full_duplex, "Starfire full duplex setting(s) (1)"); +MODULE_PARM(enable_hw_cksum, "i"); +MODULE_PARM_DESC(max_interrupt_work, "Maximum events handled per interrupt"); +MODULE_PARM_DESC(mtu, "MTU (all boards)"); +MODULE_PARM_DESC(debug, "Debug level (0-6)"); +MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); +MODULE_PARM_DESC(intr_latency, "Maximum interrupt latency, in microseconds"); +MODULE_PARM_DESC(small_frames, "Maximum size of receive frames that bypass interrupt latency (0,64,128,256,512)"); +MODULE_PARM_DESC(options, "Deprecated: Bits 0-3: media type, bit 17: full duplex"); +MODULE_PARM_DESC(full_duplex, "Deprecated: Forced full-duplex setting (0/1)"); +MODULE_PARM_DESC(enable_hw_cksum, "Enable/disable hardware cksum support (0/1)"); /* Theory of Operation @@ -306,14 +421,14 @@ IIIb/c. Transmit/Receive Structure See the Adaptec manual for the many possible structures, and options for -each structure. There are far too many to document here. +each structure. There are far too many to document all of them here. For transmit this driver uses type 0/1 transmit descriptors (depending -on the presence of the zerocopy infrastructure), and relies on automatic +on the 32/64 bitness of the architecture), and relies on automatic minimum-length padding. It does not use the completion queue consumer index, but instead checks for non-zero status entries. -For receive this driver uses type 0 receive descriptors. The driver +For receive this driver uses type 0/1/2/3 receive descriptors. The driver allocates full frame size skbuffs for the Rx ring buffers, so all frames should fit in a single descriptor. The driver does not use the completion queue consumer index, but instead checks for non-zero status entries. @@ -338,15 +453,15 @@ dev->tbusy flag. The other thread is the interrupt handler, which is single threaded by the hardware and interrupt handling software. -The send packet thread has partial control over the Tx ring and 'dev->tbusy' -flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next -queue slot is empty, it clears the tbusy flag when finished otherwise it sets -the 'lp->tx_full' flag. +The send packet thread has partial control over the Tx ring and the netif_queue +status. If the number of free Tx slots in the ring falls below a certain number +(currently hardcoded to 4), it signals the upper layer to stop the queue. The interrupt handler has exclusive control over the Rx ring and records stats from the Tx ring. After reaping the stats, it marks the Tx queue entry as -empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it -clears both the tx_full and tbusy flags. +empty by incrementing the dirty_tx mark. Iff the netif_queue is stopped and the +number of free Tx slow is above the threshold, it signals the upper layer to +restart the queue. IV. Notes @@ -358,18 +473,15 @@ IVc. Errata +- StopOnPerr is broken, don't enable +- Hardware ethernet padding exposes random data, perform software padding + instead (unverified -- works correctly for all the hardware I have) + */ enum chip_capability_flags {CanHaveMII=1, }; -#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR0) - -#if 0 -#define ADDR_64BITS 1 /* This chip uses 64 bit addresses. */ -#endif - -#define HAS_IP_COPYSUM 1 enum chipset { CH_6915 = 0, @@ -401,7 +513,7 @@ enum register_offsets { PCIDeviceConfig=0x50040, GenCtrl=0x50070, IntrTimerCtrl=0x50074, IntrClear=0x50080, IntrStatus=0x50084, IntrEnable=0x50088, - MIICtrl=0x52000, StationAddr=0x50120, EEPROMCtrl=0x51000, + MIICtrl=0x52000, TxStationAddr=0x50120, EEPROMCtrl=0x51000, GPIOCtrl=0x5008C, TxDescCtrl=0x50090, TxRingPtr=0x50098, HiPriTxRingPtr=0x50094, /* Low and High priority. */ TxRingHiAddr=0x5009C, /* 64 bit address extension. */ @@ -412,11 +524,16 @@ CompletionQConsumerIdx=0x500C4, RxDMACtrl=0x500D0, RxDescQCtrl=0x500D4, RxDescQHiAddr=0x500DC, RxDescQAddr=0x500E0, RxDescQIdx=0x500E8, RxDMAStatus=0x500F0, RxFilterMode=0x500F4, - TxMode=0x55000, PerfFilterTable=0x56000, HashTable=0x56100, + TxMode=0x55000, VlanType=0x55064, + PerfFilterTable=0x56000, HashTable=0x56100, TxGfpMem=0x58000, RxGfpMem=0x5a000, }; -/* Bits in the interrupt status/mask registers. */ +/* + * Bits in the interrupt status/mask registers. + * Warning: setting Intr[Ab]NormalSummary in the IntrEnable register + * enables all the interrupt sources that are or'ed into those status bits. + */ enum intr_status_bits { IntrLinkChange=0xf0000000, IntrStatsMax=0x08000000, IntrAbnormalSummary=0x02000000, IntrGeneralTimer=0x01000000, @@ -441,7 +558,16 @@ /* Bits in the RxFilterMode register. */ enum rx_mode_bits { AcceptBroadcast=0x04, AcceptAllMulticast=0x02, AcceptAll=0x01, - AcceptMulticast=0x10, AcceptMyPhys=0xE040, + AcceptMulticast=0x10, PerfectFilter=0x40, HashFilter=0x30, + PerfectFilterVlan=0x80, MinVLANPrio=0xE000, VlanMode=0x0200, + WakeupOnGFP=0x0800, +}; + +/* Bits in the TxMode register */ +enum tx_mode_bits { + MiiSoftReset=0x8000, MIILoopback=0x4000, + TxFlowEnable=0x0800, RxFlowEnable=0x0400, + PadEnable=0x04, FullDuplex=0x02, HugeFrame=0x01, }; /* Bits in the TxDescCtrl register. */ @@ -450,7 +576,8 @@ TxDescSpace128=0x30, TxDescSpace256=0x40, TxDescType0=0x00, TxDescType1=0x01, TxDescType2=0x02, TxDescType3=0x03, TxDescType4=0x04, - TxNoDMACompletion=0x08, TxDescQ64bit=0x80, + TxNoDMACompletion=0x08, + TxDescQAddr64bit=0x80, TxDescQAddr32bit=0, TxHiPriFIFOThreshShift=24, TxPadLenShift=16, TxDMABurstSizeShift=8, }; @@ -458,81 +585,144 @@ /* Bits in the RxDescQCtrl register. */ enum rx_ctrl_bits { RxBufferLenShift=16, RxMinDescrThreshShift=0, - RxPrefetchMode=0x8000, Rx2048QEntries=0x4000, - RxVariableQ=0x2000, RxDesc64bit=0x1000, - RxDescQAddr64bit=0x0100, + RxPrefetchMode=0x8000, RxVariableQ=0x2000, + Rx2048QEntries=0x4000, Rx256QEntries=0, + RxDescAddr64bit=0x1000, RxDescAddr32bit=0, + RxDescQAddr64bit=0x0100, RxDescQAddr32bit=0, RxDescSpace4=0x000, RxDescSpace8=0x100, RxDescSpace16=0x200, RxDescSpace32=0x300, RxDescSpace64=0x400, RxDescSpace128=0x500, RxConsumerWrEn=0x80, }; +/* Bits in the RxDMACtrl register. */ +enum rx_dmactrl_bits { + RxReportBadFrames=0x80000000, RxDMAShortFrames=0x40000000, + RxDMABadFrames=0x20000000, RxDMACrcErrorFrames=0x10000000, + RxDMAControlFrame=0x08000000, RxDMAPauseFrame=0x04000000, + RxChecksumIgnore=0, RxChecksumRejectTCPUDP=0x02000000, + RxChecksumRejectTCPOnly=0x01000000, + RxCompletionQ2Enable=0x800000, + RxDMAQ2Disable=0, RxDMAQ2FPOnly=0x100000, + RxDMAQ2SmallPkt=0x200000, RxDMAQ2HighPrio=0x300000, + RxDMAQ2NonIP=0x400000, + RxUseBackupQueue=0x080000, RxDMACRC=0x040000, + RxEarlyIntThreshShift=12, RxHighPrioThreshShift=8, + RxBurstSizeShift=0, +}; + /* Bits in the RxCompletionAddr register */ enum rx_compl_bits { - RxComplQAddr64bit=0x80, TxComplProducerWrEn=0x40, + RxComplQAddr64bit=0x80, RxComplQAddr32bit=0, + RxComplProducerWrEn=0x40, RxComplType0=0x00, RxComplType1=0x10, RxComplType2=0x20, RxComplType3=0x30, RxComplThreshShift=0, }; +/* Bits in the TxCompletionAddr register */ +enum tx_compl_bits { + TxComplQAddr64bit=0x80, TxComplQAddr32bit=0, + TxComplProducerWrEn=0x40, + TxComplIntrStatus=0x20, + CommonQueueMode=0x10, + TxComplThreshShift=0, +}; + +/* Bits in the GenCtrl register */ +enum gen_ctrl_bits { + RxEnable=0x05, TxEnable=0x0a, + RxGFPEnable=0x10, TxGFPEnable=0x20, +}; + +/* Bits in the IntrTimerCtrl register */ +enum intr_ctrl_bits { + Timer10X=0x800, EnableIntrMasking=0x60, SmallFrameBypass=0x100, + SmallFrame64=0, SmallFrame128=0x200, SmallFrame256=0x400, SmallFrame512=0x600, + IntrLatencyMask=0x1f, +}; + /* The Rx and Tx buffer descriptors. */ struct starfire_rx_desc { - u32 rxaddr; /* Optionally 64 bits. */ + dma_addr_t rxaddr; }; enum rx_desc_bits { RxDescValid=1, RxDescEndRing=2, }; -/* Completion queue entry. - You must update the page allocation, init_ring and the shift count in rx() - if using a larger format. */ -#ifdef HAS_FIRMWARE -#define csum_rx_status -#endif /* HAS_FIRMWARE */ -struct rx_done_desc { +/* Completion queue entry. */ +struct short_rx_done_desc { + u32 status; /* Low 16 bits is length. */ +}; +struct basic_rx_done_desc { u32 status; /* Low 16 bits is length. */ -#ifdef csum_rx_status - u32 status2; /* Low 16 bits is csum */ -#endif /* csum_rx_status */ -#ifdef full_rx_status - u32 status2; + u16 vlanid; + u16 status2; +}; +struct csum_rx_done_desc { + u32 status; /* Low 16 bits is length. */ + u16 csum; /* Partial checksum */ + u16 status2; +}; +struct full_rx_done_desc { + u32 status; /* Low 16 bits is length. */ + u16 status3; + u16 status2; u16 vlanid; u16 csum; /* partial checksum */ u32 timestamp; -#endif /* full_rx_status */ }; +/* XXX: this is ugly and I'm not sure it's worth the trouble -Ion */ +#ifdef HAS_FIRMWARE +#ifdef VLAN_SUPPORT +typedef struct full_rx_done_desc rx_done_desc; +#define RxComplType RxComplType3 +#else /* not VLAN_SUPPORT */ +typedef struct csum_rx_done_desc rx_done_desc; +#define RxComplType RxComplType2 +#endif /* not VLAN_SUPPORT */ +#else /* not HAS_FIRMWARE */ +#ifdef VLAN_SUPPORT +typedef struct basic_rx_done_desc rx_done_desc; +#define RxComplType RxComplType1 +#else /* not VLAN_SUPPORT */ +typedef struct short_rx_done_desc rx_done_desc; +#define RxComplType RxComplType0 +#endif /* not VLAN_SUPPORT */ +#endif /* not HAS_FIRMWARE */ + enum rx_done_bits { RxOK=0x20000000, RxFIFOErr=0x10000000, RxBufQ2=0x08000000, }; -#ifdef ZEROCOPY -/* Type 0 Tx descriptor. */ -/* If more fragments are needed, don't forget to change the - descriptor spacing as well! */ -struct starfire_tx_desc { - u32 status; - u32 nbufs; - u32 first_addr; - u16 first_len; - u16 total_len; - struct { - u32 addr; - u32 len; - } frag[MAX_STARFIRE_FRAGS]; -}; -#else /* not ZEROCOPY */ /* Type 1 Tx descriptor. */ -struct starfire_tx_desc { +struct starfire_tx_desc_1 { u32 status; /* Upper bits are status, lower 16 length. */ - u32 first_addr; + u32 addr; }; -#endif /* not ZEROCOPY */ + +/* Type 2 Tx descriptor. */ +struct starfire_tx_desc_2 { + u32 status; /* Upper bits are status, lower 16 length. */ + u32 reserved; + u64 addr; +}; + +#ifdef ADDR_64BITS +typedef struct starfire_tx_desc_2 starfire_tx_desc; +#define TX_DESC_TYPE TxDescType2 +#else /* not ADDR_64BITS */ +typedef struct starfire_tx_desc_1 starfire_tx_desc; +#define TX_DESC_TYPE TxDescType1 +#endif /* not ADDR_64BITS */ +#define TX_DESC_SPACING TxDescSpaceUnlim + enum tx_desc_bits { TxDescID=0xB0000000, TxCRCEn=0x01000000, TxDescIntr=0x08000000, TxRingWrap=0x04000000, TxCalTCP=0x02000000, }; -struct tx_done_report { +struct tx_done_desc { u32 status; /* timestamp, index. */ #if 0 u32 intrstatus; /* interrupt status */ @@ -545,41 +735,45 @@ }; struct tx_ring_info { struct sk_buff *skb; - dma_addr_t first_mapping; -#ifdef ZEROCOPY - dma_addr_t frag_mapping[MAX_STARFIRE_FRAGS]; -#endif /* ZEROCOPY */ + dma_addr_t mapping; + unsigned int used_slots; }; #define PHY_CNT 2 struct netdev_private { /* Descriptor rings first for alignment. */ struct starfire_rx_desc *rx_ring; - struct starfire_tx_desc *tx_ring; + starfire_tx_desc *tx_ring; dma_addr_t rx_ring_dma; dma_addr_t tx_ring_dma; /* The addresses of rx/tx-in-place skbuffs. */ struct rx_ring_info rx_info[RX_RING_SIZE]; struct tx_ring_info tx_info[TX_RING_SIZE]; /* Pointers to completion queues (full pages). */ - struct rx_done_desc *rx_done_q; + rx_done_desc *rx_done_q; dma_addr_t rx_done_q_dma; unsigned int rx_done; - struct tx_done_report *tx_done_q; + struct tx_done_desc *tx_done_q; dma_addr_t tx_done_q_dma; unsigned int tx_done; struct net_device_stats stats; struct pci_dev *pci_dev; +#ifdef VLAN_SUPPORT + struct vlan_group *vlgrp; +#endif + void *queue_mem; + dma_addr_t queue_mem_dma; + size_t queue_mem_size; + /* Frequently used values: keep some adjacent for cache effect. */ spinlock_t lock; unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */ - unsigned int cur_tx, dirty_tx; + unsigned int cur_tx, dirty_tx, reap_tx; unsigned int rx_buf_sz; /* Based on MTU+slack. */ - unsigned int tx_full:1, /* The Tx queue is full. */ /* These values keep track of the transceiver/media in use. */ - speed100:1; /* Set if speed == 100MBit. */ - unsigned int intr_mitigation; + int speed100; /* Set if speed == 100MBit. */ u32 tx_mode; + u32 intr_timer_ctrl; u8 tx_threshold; /* MII transceiver section. */ struct mii_if_info mii_if; /* MII lib hooks/info */ @@ -597,7 +791,8 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev); static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs); static void netdev_error(struct net_device *dev, int intr_status); -static int netdev_rx(struct net_device *dev); +static int __netdev_rx(struct net_device *dev, int *quota); +static void refill_rx_ring(struct net_device *dev); static void netdev_error(struct net_device *dev, int intr_status); static void set_rx_mode(struct net_device *dev); static struct net_device_stats *get_stats(struct net_device *dev); @@ -606,6 +801,44 @@ static void netdev_media_change(struct net_device *dev); +#ifdef VLAN_SUPPORT +static void netdev_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) +{ + struct netdev_private *np = dev->priv; + + spin_lock(&np->lock); + if (debug > 2) + printk("%s: Setting vlgrp to %p\n", dev->name, grp); + np->vlgrp = grp; + set_rx_mode(dev); + spin_unlock(&np->lock); +} + +static void netdev_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) +{ + struct netdev_private *np = dev->priv; + + spin_lock(&np->lock); + if (debug > 1) + printk("%s: Adding vlanid %d to vlan filter\n", dev->name, vid); + set_rx_mode(dev); + spin_unlock(&np->lock); +} + +static void netdev_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) +{ + struct netdev_private *np = dev->priv; + + spin_lock(&np->lock); + if (debug > 1) + printk("%s: removing vlanid %d from vlan filter\n", dev->name, vid); + if (np->vlgrp) + np->vlgrp->vlan_devices[vid] = NULL; + set_rx_mode(dev); + spin_unlock(&np->lock); +} +#endif /* VLAN_SUPPORT */ + static int __devinit starfire_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -617,10 +850,6 @@ long ioaddr; int drv_flags, io_size; int boguscnt; -#ifndef HAVE_PCI_SET_MWI - u16 cmd; - u8 cache; -#endif /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -637,13 +866,13 @@ ioaddr = pci_resource_start(pdev, 0); io_size = pci_resource_len(pdev, 0); if (!ioaddr || ((pci_resource_flags(pdev, 0) & IORESOURCE_MEM) == 0)) { - printk (KERN_ERR DRV_NAME " %d: no PCI MEM resources, aborting\n", card_idx); + printk(KERN_ERR DRV_NAME " %d: no PCI MEM resources, aborting\n", card_idx); return -ENODEV; } dev = alloc_etherdev(sizeof(*np)); if (!dev) { - printk (KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx); + printk(KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx); return -ENOMEM; } SET_MODULE_OWNER(dev); @@ -651,7 +880,7 @@ irq = pdev->irq; if (pci_request_regions (pdev, dev->name)) { - printk (KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx); + printk(KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx); goto err_out_free_netdev; } @@ -659,7 +888,7 @@ #if !defined(CONFIG_SPARC64) || LINUX_VERSION_CODE > 0x20300 ioaddr = (long) ioremap(ioaddr, io_size); if (!ioaddr) { - printk (KERN_ERR DRV_NAME " %d: cannot remap 0x%x @ 0x%lx, aborting\n", + printk(KERN_ERR DRV_NAME " %d: cannot remap %#x @ %#lx, aborting\n", card_idx, io_size, ioaddr); goto err_out_free_res; } @@ -667,29 +896,26 @@ pci_set_master(pdev); -#ifdef HAVE_PCI_SET_MWI - pci_set_mwi(pdev); -#else /* enable MWI -- it vastly improves Rx performance on sparc64 */ - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_INVALIDATE; - pci_write_config_word(pdev, PCI_COMMAND, cmd); - - /* set PCI cache size */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache); - if ((cache << 2) != SMP_CACHE_BYTES) { - printk(KERN_INFO " PCI cache line size set incorrectly " - "(%i bytes) by BIOS/FW, correcting to %i\n", - (cache << 2), SMP_CACHE_BYTES); - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, - SMP_CACHE_BYTES >> 2); - } -#endif + pci_set_mwi(pdev); +#ifdef MAX_SKB_FRAGS + dev->features |= NETIF_F_SG; +#endif /* MAX_SKB_FRAGS */ #ifdef ZEROCOPY - /* Starfire can do SG and TCP/UDP checksumming */ - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + /* Starfire can do TCP/UDP checksumming */ + if (enable_hw_cksum) + dev->features |= NETIF_F_IP_CSUM; #endif /* ZEROCOPY */ +#ifdef VLAN_SUPPORT + dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; + dev->vlan_rx_register = netdev_vlan_rx_register; + dev->vlan_rx_add_vid = netdev_vlan_rx_add_vid; + dev->vlan_rx_kill_vid = netdev_vlan_rx_kill_vid; +#endif /* VLAN_RX_KILL_VID */ +#ifdef ADDR_64BITS + dev->features |= NETIF_F_HIGHDMA; +#endif /* ADDR_64BITS */ /* Serial EEPROM reads are hidden by the hardware. */ for (i = 0; i < 6; i++) @@ -704,7 +930,7 @@ #endif /* Issue soft reset */ - writel(0x8000, ioaddr + TxMode); + writel(MiiSoftReset, ioaddr + TxMode); udelay(1000); writel(0, ioaddr + TxMode); @@ -750,15 +976,40 @@ np->mii_if.full_duplex = 1; if (np->mii_if.full_duplex) - np->mii_if.force_media = 0; - else np->mii_if.force_media = 1; + else + np->mii_if.force_media = 0; np->speed100 = 1; + /* timer resolution is 128 * 0.8us */ + np->intr_timer_ctrl = (((intr_latency * 10) / 1024) & IntrLatencyMask) | + Timer10X | EnableIntrMasking; + + if (small_frames > 0) { + np->intr_timer_ctrl |= SmallFrameBypass; + switch (small_frames) { + case 1 ... 64: + np->intr_timer_ctrl |= SmallFrame64; + break; + case 65 ... 128: + np->intr_timer_ctrl |= SmallFrame128; + break; + case 129 ... 256: + np->intr_timer_ctrl |= SmallFrame256; + break; + default: + np->intr_timer_ctrl |= SmallFrame512; + if (small_frames > 512) + printk("Adjusting small_frames down to 512\n"); + break; + } + } + /* The chip-specific entries in the device structure. */ dev->open = &netdev_open; dev->hard_start_xmit = &start_tx; init_tx_timer(dev, tx_timeout, TX_TIMEOUT); + init_poll(dev); dev->stop = &netdev_close; dev->get_stats = &get_stats; dev->set_multicast_list = &set_rx_mode; @@ -767,11 +1018,10 @@ if (mtu) dev->mtu = mtu; - i = register_netdev(dev); - if (i) + if (register_netdev(dev)) goto err_out_cleardev; - printk(KERN_INFO "%s: %s at 0x%lx, ", + printk(KERN_INFO "%s: %s at %#lx, ", dev->name, netdrv_tbl[chip_idx].name, ioaddr); for (i = 0; i < 5; i++) printk("%2.2x:", dev->dev_addr[i]); @@ -796,7 +1046,7 @@ np->phys[phy_idx++] = phy; np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE); printk(KERN_INFO "%s: MII PHY found at address %d, status " - "0x%4.4x advertising %4.4x.\n", + "%#4.4x advertising %#4.4x.\n", dev->name, phy, mii_status, np->mii_if.advertising); /* there can be only one PHY on-board */ break; @@ -809,14 +1059,8 @@ memset(&np->mii_if, 0, sizeof(np->mii_if)); } -#ifdef ZEROCOPY - printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming enabled.\n", - dev->name); -#else /* not ZEROCOPY */ - printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming disabled.\n", - dev->name); -#endif /* not ZEROCOPY */ - + printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming %s.\n", + dev->name, enable_hw_cksum ? "enabled" : "disabled"); return 0; err_out_cleardev: @@ -825,7 +1069,6 @@ err_out_free_res: pci_release_regions (pdev); err_out_free_netdev: - unregister_netdev(dev); kfree(dev); return -ENODEV; } @@ -861,6 +1104,7 @@ struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; int i, retval; + size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size; /* Do we ever need to reset the chip??? */ @@ -878,62 +1122,61 @@ if (debug > 1) printk(KERN_DEBUG "%s: netdev_open() irq %d.\n", dev->name, dev->irq); - /* Allocate the various queues, failing gracefully. */ - if (np->tx_done_q == 0) - np->tx_done_q = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_done_q_dma); - if (np->rx_done_q == 0) - np->rx_done_q = pci_alloc_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE, &np->rx_done_q_dma); - if (np->tx_ring == 0) - np->tx_ring = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_ring_dma); - if (np->rx_ring == 0) - np->rx_ring = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->rx_ring_dma); - if (np->tx_done_q == 0 || np->rx_done_q == 0 - || np->rx_ring == 0 || np->tx_ring == 0) { - if (np->tx_done_q) - pci_free_consistent(np->pci_dev, PAGE_SIZE, - np->tx_done_q, np->tx_done_q_dma); - if (np->rx_done_q) - pci_free_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE, - np->rx_done_q, np->rx_done_q_dma); - if (np->tx_ring) - pci_free_consistent(np->pci_dev, PAGE_SIZE, - np->tx_ring, np->tx_ring_dma); - if (np->rx_ring) - pci_free_consistent(np->pci_dev, PAGE_SIZE, - np->rx_ring, np->rx_ring_dma); - COMPAT_MOD_DEC_USE_COUNT; - return -ENOMEM; + + /* Allocate the various queues. */ + if (np->queue_mem == 0) { + tx_done_q_size = ((sizeof(struct tx_done_desc) * DONE_Q_SIZE + QUEUE_ALIGN - 1) / QUEUE_ALIGN) * QUEUE_ALIGN; + rx_done_q_size = ((sizeof(rx_done_desc) * DONE_Q_SIZE + QUEUE_ALIGN - 1) / QUEUE_ALIGN) * QUEUE_ALIGN; + tx_ring_size = ((sizeof(starfire_tx_desc) * TX_RING_SIZE + QUEUE_ALIGN - 1) / QUEUE_ALIGN) * QUEUE_ALIGN; + rx_ring_size = sizeof(struct starfire_rx_desc) * RX_RING_SIZE; + np->queue_mem_size = tx_done_q_size + rx_done_q_size + tx_ring_size + rx_ring_size; + np->queue_mem = pci_alloc_consistent(np->pci_dev, np->queue_mem_size, &np->queue_mem_dma); + if (np->queue_mem == 0) { + COMPAT_MOD_DEC_USE_COUNT; + return -ENOMEM; + } + + np->tx_done_q = np->queue_mem; + np->tx_done_q_dma = np->queue_mem_dma; + np->rx_done_q = (void *) np->tx_done_q + tx_done_q_size; + np->rx_done_q_dma = np->tx_done_q_dma + tx_done_q_size; + np->tx_ring = (void *) np->rx_done_q + rx_done_q_size; + np->tx_ring_dma = np->rx_done_q_dma + rx_done_q_size; + np->rx_ring = (void *) np->tx_ring + tx_ring_size; + np->rx_ring_dma = np->tx_ring_dma + tx_ring_size; } + /* Start with no carrier, it gets adjusted later */ netif_carrier_off(dev); init_ring(dev); /* Set the size of the Rx buffers. */ writel((np->rx_buf_sz << RxBufferLenShift) | (0 << RxMinDescrThreshShift) | RxPrefetchMode | RxVariableQ | + RX_Q_ENTRIES | + RX_DESC_Q_ADDR_SIZE | RX_DESC_ADDR_SIZE | RxDescSpace4, ioaddr + RxDescQCtrl); -#ifdef ZEROCOPY - /* Set Tx descriptor to type 0 and spacing to 64 bytes. */ - writel((2 << TxHiPriFIFOThreshShift) | - (0 << TxPadLenShift) | - (4 << TxDMABurstSizeShift) | - TxDescSpace64 | TxDescType0, - ioaddr + TxDescCtrl); -#else /* not ZEROCOPY */ - /* Set Tx descriptor to type 1 and padding to 0 bytes. */ + /* Set up the Rx DMA controller. */ + writel(RxChecksumIgnore | + (0 << RxEarlyIntThreshShift) | + (6 << RxHighPrioThreshShift) | + ((DMA_BURST_SIZE / 32) << RxBurstSizeShift), + ioaddr + RxDMACtrl); + + /* Set Tx descriptor */ writel((2 << TxHiPriFIFOThreshShift) | (0 << TxPadLenShift) | - (4 << TxDMABurstSizeShift) | - TxDescSpaceUnlim | TxDescType1, + ((DMA_BURST_SIZE / 32) << TxDMABurstSizeShift) | + TX_DESC_Q_ADDR_SIZE | + TX_DESC_SPACING | TX_DESC_TYPE, ioaddr + TxDescCtrl); -#endif /* not ZEROCOPY */ -#if defined(ADDR_64BITS) && defined(__alpha__) - /* XXX We really need a 64-bit PCI dma interfaces too... -DaveM */ - writel(np->rx_ring_dma >> 32, ioaddr + RxDescQHiAddr); - writel(np->tx_ring_dma >> 32, ioaddr + TxRingHiAddr); +#if defined(ADDR_64BITS) + writel(np->queue_mem_dma >> 32, ioaddr + RxDescQHiAddr); + writel(np->queue_mem_dma >> 32, ioaddr + TxRingHiAddr); + writel(np->queue_mem_dma >> 32, ioaddr + CompletionHiAddr); #else writel(0, ioaddr + RxDescQHiAddr); writel(0, ioaddr + TxRingHiAddr); @@ -943,32 +1186,23 @@ writel(np->tx_ring_dma, ioaddr + TxRingPtr); writel(np->tx_done_q_dma, ioaddr + TxCompletionAddr); -#ifdef full_rx_status writel(np->rx_done_q_dma | - RxComplType3 | + RxComplType | (0 << RxComplThreshShift), ioaddr + RxCompletionAddr); -#else /* not full_rx_status */ -#ifdef csum_rx_status - writel(np->rx_done_q_dma | - RxComplType2 | - (0 << RxComplThreshShift), - ioaddr + RxCompletionAddr); -#else /* not csum_rx_status */ - writel(np->rx_done_q_dma | - RxComplType0 | - (0 << RxComplThreshShift), - ioaddr + RxCompletionAddr); -#endif /* not csum_rx_status */ -#endif /* not full_rx_status */ if (debug > 1) printk(KERN_DEBUG "%s: Filling in the station address.\n", dev->name); - /* Fill both the unused Tx SA register and the Rx perfect filter. */ + /* Fill both the Tx SA register and the Rx perfect filter. */ for (i = 0; i < 6; i++) - writeb(dev->dev_addr[i], ioaddr + StationAddr + 5 - i); - for (i = 0; i < 16; i++) { + writeb(dev->dev_addr[i], ioaddr + TxStationAddr + 5 - i); + /* The first entry is special because it bypasses the VLAN filter. + Don't use it. */ + writew(0, ioaddr + PerfFilterTable); + writew(0, ioaddr + PerfFilterTable + 4); + writew(0, ioaddr + PerfFilterTable + 8); + for (i = 1; i < 16; i++) { u16 *eaddrs = (u16 *)dev->dev_addr; long setup_frm = ioaddr + PerfFilterTable + i * 16; writew(cpu_to_be16(eaddrs[2]), setup_frm); setup_frm += 4; @@ -978,16 +1212,14 @@ /* Initialize other registers. */ /* Configure the PCI bus bursts and FIFO thresholds. */ - np->tx_mode = 0x0C04; /* modified when link is up. */ - writel(0x8000 | np->tx_mode, ioaddr + TxMode); + np->tx_mode = TxFlowEnable|RxFlowEnable|PadEnable; /* modified when link is up. */ + writel(MiiSoftReset | np->tx_mode, ioaddr + TxMode); udelay(1000); writel(np->tx_mode, ioaddr + TxMode); np->tx_threshold = 4; writel(np->tx_threshold, ioaddr + TxThreshold); - interrupt_mitigation &= 0x1f; - np->intr_mitigation = interrupt_mitigation; - writel(np->intr_mitigation, ioaddr + IntrTimerCtrl); + writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl); netif_start_if(dev); netif_start_queue(dev); @@ -1002,29 +1234,35 @@ /* Enable GPIO interrupts on link change */ writel(0x0f00ff00, ioaddr + GPIOCtrl); - /* Set the interrupt mask and enable PCI interrupts. */ + /* Set the interrupt mask */ writel(IntrRxDone | IntrRxEmpty | IntrDMAErr | - IntrTxDone | IntrStatsMax | IntrLinkChange | - IntrNormalSummary | IntrAbnormalSummary | + IntrTxDMADone | IntrStatsMax | IntrLinkChange | IntrRxGFPDead | IntrNoTxCsum | IntrTxBadID, ioaddr + IntrEnable); + /* Enable PCI interrupts. */ writel(0x00800000 | readl(ioaddr + PCIDeviceConfig), ioaddr + PCIDeviceConfig); +#ifdef VLAN_SUPPORT + /* Set VLAN type to 802.1q */ + writel(ETH_P_8021Q, ioaddr + VlanType); +#endif /* VLAN_SUPPORT */ + #ifdef HAS_FIRMWARE /* Load Rx/Tx firmware into the frame processors */ for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++) writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4); for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++) writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4); - /* Enable the Rx and Tx units, and the Rx/Tx frame processors. */ - writel(0x003F, ioaddr + GenCtrl); -#else /* not HAS_FIRMWARE */ - /* Enable the Rx and Tx units only. */ - writel(0x000F, ioaddr + GenCtrl); -#endif /* not HAS_FIRMWARE */ +#endif /* HAS_FIRMWARE */ + if (enable_hw_cksum) + /* Enable the Rx and Tx units, and the Rx/Tx frame processors. */ + writel(TxEnable|TxGFPEnable|RxEnable|RxGFPEnable, ioaddr + GenCtrl); + else + /* Enable the Rx and Tx units only. */ + writel(TxEnable|RxEnable, ioaddr + GenCtrl); - if (debug > 2) + if (debug > 1) printk(KERN_DEBUG "%s: Done netdev_open().\n", dev->name); @@ -1036,11 +1274,17 @@ { struct netdev_private *np = dev->priv; u16 reg0; + int silly_count = 1000; mdio_write(dev, np->phys[0], MII_ADVERTISE, np->mii_if.advertising); mdio_write(dev, np->phys[0], MII_BMCR, BMCR_RESET); udelay(500); - while (mdio_read(dev, np->phys[0], MII_BMCR) & BMCR_RESET); + while (--silly_count && mdio_read(dev, np->phys[0], MII_BMCR) & BMCR_RESET) + /* do nothing */; + if (!silly_count) { + printk("%s: MII reset failed!\n", dev->name); + return; + } reg0 = mdio_read(dev, np->phys[0], MII_BMCR); @@ -1065,25 +1309,22 @@ { struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; + int old_debug; - printk(KERN_WARNING "%s: Transmit timed out, status %8.8x," - " resetting...\n", dev->name, (int)readl(ioaddr + IntrStatus)); - -#ifndef __alpha__ - { - int i; - printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring); - for (i = 0; i < RX_RING_SIZE; i++) - printk(" %8.8x", (unsigned int)le32_to_cpu(np->rx_ring[i].rxaddr)); - printk("\n"KERN_DEBUG" Tx ring %p: ", np->tx_ring); - for (i = 0; i < TX_RING_SIZE; i++) - printk(" %4.4x", le32_to_cpu(np->tx_ring[i].status)); - printk("\n"); - } -#endif + printk(KERN_WARNING "%s: Transmit timed out, status %#8.8x, " + "resetting...\n", dev->name, (int) readl(ioaddr + IntrStatus)); /* Perhaps we should reinitialize the hardware here. */ - /* Stop and restart the chip's Tx processes . */ + + /* + * Stop and restart the interface. + * Cheat and increase the debug level temporarily. + */ + old_debug = debug; + debug = 2; + netdev_close(dev); + netdev_open(dev); + debug = old_debug; /* Trigger an immediate transmit demand. */ @@ -1099,9 +1340,8 @@ struct netdev_private *np = dev->priv; int i; - np->tx_full = 0; - np->cur_rx = np->cur_tx = 0; - np->dirty_rx = np->rx_done = np->dirty_tx = np->tx_done = 0; + np->cur_rx = np->cur_tx = np->reap_tx = 0; + np->dirty_rx = np->dirty_tx = np->rx_done = np->tx_done = 0; np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32); @@ -1114,7 +1354,7 @@ np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; /* Mark as being used by this device. */ /* Grrr, we cannot offset to correctly align the IP header. */ - np->rx_ring[i].rxaddr = cpu_to_le32(np->rx_info[i].mapping | RxDescValid); + np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid); } writew(i - 1, dev->base_addr + RxDescQIdx); np->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -1126,7 +1366,7 @@ np->rx_info[i].mapping = 0; } /* Mark the last entry as wrapping the ring. */ - np->rx_ring[i-1].rxaddr |= cpu_to_le32(RxDescEndRing); + np->rx_ring[RX_RING_SIZE - 1].rxaddr |= cpu_to_dma(RxDescEndRing); /* Clear the completion rings. */ for (i = 0; i < DONE_Q_SIZE; i++) { @@ -1134,18 +1374,9 @@ np->tx_done_q[i].status = 0; } - for (i = 0; i < TX_RING_SIZE; i++) { - np->tx_info[i].skb = NULL; - np->tx_info[i].first_mapping = 0; -#ifdef ZEROCOPY - { - int j; - for (j = 0; j < MAX_STARFIRE_FRAGS; j++) - np->tx_info[i].frag_mapping[j] = 0; - } -#endif /* ZEROCOPY */ - np->tx_ring[i].status = 0; - } + for (i = 0; i < TX_RING_SIZE; i++) + memset(&np->tx_info[i], 0, sizeof(np->tx_info[i])); + return; } @@ -1154,19 +1385,21 @@ { struct netdev_private *np = dev->priv; unsigned int entry; -#ifdef ZEROCOPY + u32 status; int i; -#endif kick_tx_timer(dev, tx_timeout, TX_TIMEOUT); - /* Caution: the write order is important here, set the field - with the "ownership" bits last. */ - - /* Calculate the next Tx descriptor entry. */ - entry = np->cur_tx % TX_RING_SIZE; + /* + * be cautious here, wrapping the queue has weird semantics + * and we may not have enough slots even when it seems we do. + */ + if ((np->cur_tx - np->dirty_tx) + skb_num_frags(skb) * 2 > TX_RING_SIZE) { + netif_stop_queue(dev); + return 1; + } -#if defined(ZEROCOPY) && defined(HAS_FIRMWARE) && defined(HAS_BROKEN_FIRMWARE) +#if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE) { int has_bad_length = 0; @@ -1183,85 +1416,72 @@ if (has_bad_length) skb_checksum_help(skb); } -#endif /* ZEROCOPY && HAS_FIRMWARE && HAS_BROKEN_FIRMWARE */ - - np->tx_info[entry].skb = skb; - np->tx_info[entry].first_mapping = - pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE); - - np->tx_ring[entry].first_addr = cpu_to_le32(np->tx_info[entry].first_mapping); -#ifdef ZEROCOPY - np->tx_ring[entry].first_len = cpu_to_le16(skb_first_frag_len(skb)); - np->tx_ring[entry].total_len = cpu_to_le16(skb->len); - /* Add "| TxDescIntr" to generate Tx-done interrupts. */ - np->tx_ring[entry].status = cpu_to_le32(TxDescID | TxCRCEn); - np->tx_ring[entry].nbufs = cpu_to_le32(skb_shinfo(skb)->nr_frags + 1); -#else /* not ZEROCOPY */ - /* Add "| TxDescIntr" to generate Tx-done interrupts. */ - np->tx_ring[entry].status = cpu_to_le32(skb->len | TxDescID | TxCRCEn | 1 << 16); -#endif /* not ZEROCOPY */ +#endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */ - if (entry >= TX_RING_SIZE-1) /* Wrap ring */ - np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr); - -#ifdef ZEROCOPY - if (skb->ip_summed == CHECKSUM_HW) { - np->tx_ring[entry].status |= cpu_to_le32(TxCalTCP); - np->stats.tx_compressed++; - } -#endif /* ZEROCOPY */ + entry = np->cur_tx % TX_RING_SIZE; + for (i = 0; i < skb_num_frags(skb); i++) { + int wrap_ring = 0; + status = TxDescID; + + if (i == 0) { + np->tx_info[entry].skb = skb; + status |= TxCRCEn; + if (entry >= TX_RING_SIZE - skb_num_frags(skb)) { + status |= TxRingWrap; + wrap_ring = 1; + } + if (np->reap_tx) { + status |= TxDescIntr; + np->reap_tx = 0; + } + if (skb->ip_summed == CHECKSUM_HW) { + status |= TxCalTCP; + np->stats.tx_compressed++; + } + status |= skb_first_frag_len(skb) | (skb_num_frags(skb) << 16); - if (debug > 5) { -#ifdef ZEROCOPY - printk(KERN_DEBUG "%s: Tx #%d slot %d status %8.8x nbufs %d len %4.4x/%4.4x.\n", - dev->name, np->cur_tx, entry, - le32_to_cpu(np->tx_ring[entry].status), - le32_to_cpu(np->tx_ring[entry].nbufs), - le32_to_cpu(np->tx_ring[entry].first_len), - le32_to_cpu(np->tx_ring[entry].total_len)); -#else /* not ZEROCOPY */ - printk(KERN_DEBUG "%s: Tx #%d slot %d status %8.8x.\n", - dev->name, np->cur_tx, entry, - le32_to_cpu(np->tx_ring[entry].status)); -#endif /* not ZEROCOPY */ + np->tx_info[entry].mapping = + pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE); + } else { +#ifdef MAX_SKB_FRAGS + skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i - 1]; + status |= this_frag->size; + np->tx_info[entry].mapping = + pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE); +#endif /* MAX_SKB_FRAGS */ + } + + np->tx_ring[entry].addr = cpu_to_dma(np->tx_info[entry].mapping); + np->tx_ring[entry].status = cpu_to_le32(status); + if (debug > 3) + printk(KERN_DEBUG "%s: Tx #%d/#%d slot %d status %#8.8x.\n", + dev->name, np->cur_tx, np->dirty_tx, + entry, status); + if (wrap_ring) { + np->tx_info[entry].used_slots = TX_RING_SIZE - entry; + np->cur_tx += np->tx_info[entry].used_slots; + entry = 0; + } else { + np->tx_info[entry].used_slots = 1; + np->cur_tx += np->tx_info[entry].used_slots; + entry++; + } + /* scavenge the tx descriptors twice per TX_RING_SIZE */ + if (np->cur_tx % (TX_RING_SIZE / 2) == 0) + np->reap_tx = 1; } -#ifdef ZEROCOPY - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i]; - - /* we already have the proper value in entry */ - np->tx_info[entry].frag_mapping[i] = - pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE); - - np->tx_ring[entry].frag[i].addr = cpu_to_le32(np->tx_info[entry].frag_mapping[i]); - np->tx_ring[entry].frag[i].len = cpu_to_le32(this_frag->size); - if (debug > 5) { - printk(KERN_DEBUG "%s: Tx #%d frag %d len %4.4x.\n", - dev->name, np->cur_tx, i, - le32_to_cpu(np->tx_ring[entry].frag[i].len)); - } - } -#endif /* ZEROCOPY */ - - np->cur_tx++; - - if (entry >= TX_RING_SIZE-1) /* Wrap ring */ - entry = -1; - entry++; - /* Non-x86: explicitly flush descriptor cache lines here. */ - /* Ensure everything is written back above before the transmit is + /* Ensure all descriptors are written back before the transmit is initiated. - Jes */ wmb(); /* Update the producer index. */ - writel(entry * (sizeof(struct starfire_tx_desc) / 8), dev->base_addr + TxProducerIdx); + writel(entry * (sizeof(starfire_tx_desc) / 8), dev->base_addr + TxProducerIdx); - if (np->cur_tx - np->dirty_tx >= TX_RING_SIZE - 1) { - np->tx_full = 1; + /* 4 is arbitrary, but should be ok */ + if ((np->cur_tx - np->dirty_tx) + 4 > TX_RING_SIZE) netif_stop_queue(dev); - } dev->trans_start = jiffies; @@ -1273,20 +1493,13 @@ after the Tx thread. */ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { - struct net_device *dev = (struct net_device *)dev_instance; + struct net_device *dev = dev_instance; struct netdev_private *np; long ioaddr; int boguscnt = max_interrupt_work; int consumer; int tx_status; -#ifndef final_version /* Can never occur. */ - if (dev == NULL) { - printk (KERN_ERR "Netdev interrupt handler(): IRQ %d for unknown device.\n", irq); - return; - } -#endif - ioaddr = dev->base_addr; np = dev->priv; @@ -1294,83 +1507,69 @@ u32 intr_status = readl(ioaddr + IntrClear); if (debug > 4) - printk(KERN_DEBUG "%s: Interrupt status %4.4x.\n", + printk(KERN_DEBUG "%s: Interrupt status %#8.8x.\n", dev->name, intr_status); - if (intr_status == 0) + if (intr_status == 0 || intr_status == (u32) -1) break; - if (intr_status & IntrRxDone) - netdev_rx(dev); + if (intr_status & (IntrRxDone | IntrRxEmpty)) + netdev_rx(dev, ioaddr); /* Scavenge the skbuff list based on the Tx-done queue. There are redundant checks here that may be cleaned up after the driver has proven to be reliable. */ consumer = readl(ioaddr + TxConsumerIdx); - if (debug > 4) + if (debug > 3) printk(KERN_DEBUG "%s: Tx Consumer index is %d.\n", dev->name, consumer); -#if 0 - if (np->tx_done >= 250 || np->tx_done == 0) - printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x, %d is %8.8x.\n", - dev->name, np->tx_done, - le32_to_cpu(np->tx_done_q[np->tx_done].status), - (np->tx_done+1) & (DONE_Q_SIZE-1), - le32_to_cpu(np->tx_done_q[(np->tx_done+1)&(DONE_Q_SIZE-1)].status)); -#endif while ((tx_status = le32_to_cpu(np->tx_done_q[np->tx_done].status)) != 0) { - if (debug > 4) - printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x.\n", - dev->name, np->tx_done, tx_status); + if (debug > 3) + printk(KERN_DEBUG "%s: Tx completion #%d entry %d is %#8.8x.\n", + dev->name, np->dirty_tx, np->tx_done, tx_status); if ((tx_status & 0xe0000000) == 0xa0000000) { np->stats.tx_packets++; } else if ((tx_status & 0xe0000000) == 0x80000000) { - struct sk_buff *skb; -#ifdef ZEROCOPY - int i; -#endif /* ZEROCOPY */ - u16 entry = tx_status; /* Implicit truncate */ - entry /= sizeof(struct starfire_tx_desc); - - skb = np->tx_info[entry].skb; + u16 entry = (tx_status & 0x7fff) / sizeof(starfire_tx_desc); + struct sk_buff *skb = np->tx_info[entry].skb; np->tx_info[entry].skb = NULL; pci_unmap_single(np->pci_dev, - np->tx_info[entry].first_mapping, + np->tx_info[entry].mapping, skb_first_frag_len(skb), PCI_DMA_TODEVICE); - np->tx_info[entry].first_mapping = 0; - -#ifdef ZEROCOPY - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - pci_unmap_single(np->pci_dev, - np->tx_info[entry].frag_mapping[i], - skb_shinfo(skb)->frags[i].size, - PCI_DMA_TODEVICE); - np->tx_info[entry].frag_mapping[i] = 0; + np->tx_info[entry].mapping = 0; + np->dirty_tx += np->tx_info[entry].used_slots; + entry = (entry + np->tx_info[entry].used_slots) % TX_RING_SIZE; +#ifdef MAX_SKB_FRAGS + { + int i; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + pci_unmap_single(np->pci_dev, + np->tx_info[entry].mapping, + skb_shinfo(skb)->frags[i].size, + PCI_DMA_TODEVICE); + np->dirty_tx++; + entry++; + } } -#endif /* ZEROCOPY */ - - /* Scavenge the descriptor. */ +#endif /* MAX_SKB_FRAGS */ dev_kfree_skb_irq(skb); - - np->dirty_tx++; } np->tx_done_q[np->tx_done].status = 0; - np->tx_done = (np->tx_done+1) & (DONE_Q_SIZE-1); + np->tx_done = (np->tx_done + 1) % DONE_Q_SIZE; } writew(np->tx_done, ioaddr + CompletionQConsumerIdx + 2); - if (np->tx_full && np->cur_tx - np->dirty_tx < TX_RING_SIZE - 4) { + if (netif_queue_stopped(dev) && + (np->cur_tx - np->dirty_tx + 4 < TX_RING_SIZE)) { /* The ring is no longer full, wake the queue. */ - np->tx_full = 0; netif_wake_queue(dev); } /* Stats overflow */ - if (intr_status & IntrStatsMax) { + if (intr_status & IntrStatsMax) get_stats(dev); - } /* Media change interrupt. */ if (intr_status & IntrLinkChange) @@ -1381,72 +1580,58 @@ netdev_error(dev, intr_status); if (--boguscnt < 0) { - printk(KERN_WARNING "%s: Too much work at interrupt, " - "status=0x%4.4x.\n", - dev->name, intr_status); + if (debug > 1) + printk(KERN_WARNING "%s: Too much work at interrupt, " + "status=%#8.8x.\n", + dev->name, intr_status); break; } } while (1); if (debug > 4) - printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n", - dev->name, (int)readl(ioaddr + IntrStatus)); - -#ifndef final_version - /* Code that should never be run! Remove after testing.. */ - { - static int stopit = 10; - if (!netif_running(dev) && --stopit < 0) { - printk(KERN_ERR "%s: Emergency stop, looping startup interrupt.\n", - dev->name); - free_irq(irq, dev); - } - } -#endif + printk(KERN_DEBUG "%s: exiting interrupt, status=%#8.8x.\n", + dev->name, (int) readl(ioaddr + IntrStatus)); } -/* This routine is logically part of the interrupt handler, but separated - for clarity and better register allocation. */ -static int netdev_rx(struct net_device *dev) +/* This routine is logically part of the interrupt/poll handler, but separated + for clarity, code sharing between NAPI/non-NAPI, and better register allocation. */ +static int __netdev_rx(struct net_device *dev, int *quota) { struct netdev_private *np = dev->priv; - int boguscnt = np->dirty_rx + RX_RING_SIZE - np->cur_rx; u32 desc_status; - - if (np->rx_done_q == 0) { - printk(KERN_ERR "%s: rx_done_q is NULL! rx_done is %d. %p.\n", - dev->name, np->rx_done, np->tx_done_q); - return 0; - } + int retcode = 0; /* If EOP is set on the next entry, it's a new packet. Send it up. */ while ((desc_status = le32_to_cpu(np->rx_done_q[np->rx_done].status)) != 0) { struct sk_buff *skb; u16 pkt_len; int entry; + rx_done_desc *desc = &np->rx_done_q[np->rx_done]; if (debug > 4) - printk(KERN_DEBUG " netdev_rx() status of %d was %8.8x.\n", np->rx_done, desc_status); - if (--boguscnt < 0) - break; - if ( ! (desc_status & RxOK)) { + printk(KERN_DEBUG " netdev_rx() status of %d was %#8.8x.\n", np->rx_done, desc_status); + if (!(desc_status & RxOK)) { /* There was a error. */ if (debug > 2) - printk(KERN_DEBUG " netdev_rx() Rx error was %8.8x.\n", desc_status); + printk(KERN_DEBUG " netdev_rx() Rx error was %#8.8x.\n", desc_status); np->stats.rx_errors++; if (desc_status & RxFIFOErr) np->stats.rx_fifo_errors++; goto next_rx; } + if (*quota <= 0) { /* out of rx quota */ + retcode = 1; + goto out; + } + (*quota)--; + pkt_len = desc_status; /* Implicitly Truncate */ entry = (desc_status >> 16) & 0x7ff; -#ifndef final_version if (debug > 4) - printk(KERN_DEBUG " netdev_rx() normal Rx pkt length %d, bogus_cnt %d.\n", pkt_len, boguscnt); -#endif + printk(KERN_DEBUG " netdev_rx() normal Rx pkt length %d, quota %d.\n", pkt_len, *quota); /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ if (pkt_len < rx_copybreak @@ -1456,12 +1641,8 @@ pci_dma_sync_single(np->pci_dev, np->rx_info[entry].mapping, pkt_len, PCI_DMA_FROMDEVICE); -#if HAS_IP_COPYSUM /* Call copy + cksum if available. */ eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0); skb_put(skb, pkt_len); -#else - memcpy(skb_put(skb, pkt_len), np->rx_info[entry].skb->tail, pkt_len); -#endif } else { pci_unmap_single(np->pci_dev, np->rx_info[entry].mapping, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb = np->rx_info[entry].skb; @@ -1473,51 +1654,109 @@ /* You will want this info for the initial debug. */ if (debug > 5) printk(KERN_DEBUG " Rx data %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:" - "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x " - "%d.%d.%d.%d.\n", + "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x.\n", skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], skb->data[5], skb->data[6], skb->data[7], skb->data[8], skb->data[9], skb->data[10], - skb->data[11], skb->data[12], skb->data[13], - skb->data[14], skb->data[15], skb->data[16], - skb->data[17]); + skb->data[11], skb->data[12], skb->data[13]); #endif + skb->protocol = eth_type_trans(skb, dev); -#if defined(full_rx_status) || defined(csum_rx_status) - if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) { +#if defined(HAS_FIRMWARE) || defined(VLAN_SUPPORT) + if (debug > 4) + printk(KERN_DEBUG " netdev_rx() status2 of %d was %#4.4x.\n", np->rx_done, le16_to_cpu(desc->status2)); +#endif +#ifdef HAS_FIRMWARE + if (le16_to_cpu(desc->status2) & 0x0100) { skb->ip_summed = CHECKSUM_UNNECESSARY; np->stats.rx_compressed++; } /* * This feature doesn't seem to be working, at least * with the two firmware versions I have. If the GFP sees - * a fragment, it either ignores it completely, or reports + * an IP fragment, it either ignores it completely, or reports * "bad checksum" on it. * * Maybe I missed something -- corrections are welcome. * Until then, the printk stays. :-) -Ion */ - else if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x00400000) { + else if (le16_to_cpu(desc->status2) & 0x0040) { skb->ip_summed = CHECKSUM_HW; - skb->csum = le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0xffff; - printk(KERN_DEBUG "%s: checksum_hw, status2 = %x\n", dev->name, np->rx_done_q[np->rx_done].status2); + skb->csum = le16_to_cpu(desc->csum); + printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2)); } -#endif - netif_rx(skb); +#endif /* HAS_FIRMWARE */ +#ifdef VLAN_SUPPORT + if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) { + if (debug > 4) + printk(KERN_DEBUG " netdev_rx() vlanid = %d\n", le16_to_cpu(desc->vlanid)); + /* vlan_netdev_receive_skb() expects a packet with the VLAN tag stripped out */ + vlan_netdev_receive_skb(skb, np->vlgrp, le16_to_cpu(desc->vlanid) & VLAN_VID_MASK); + } else +#endif /* VLAN_SUPPORT */ + netdev_receive_skb(skb); dev->last_rx = jiffies; np->stats.rx_packets++; -next_rx: + next_rx: np->cur_rx++; - np->rx_done_q[np->rx_done].status = 0; - np->rx_done = (np->rx_done + 1) & (DONE_Q_SIZE-1); + desc->status = 0; + np->rx_done = (np->rx_done + 1) % DONE_Q_SIZE; } writew(np->rx_done, dev->base_addr + CompletionQConsumerIdx); + out: + refill_rx_ring(dev); + if (debug > 5) + printk(KERN_DEBUG " exiting netdev_rx(): %d, status of %d was %#8.8x.\n", + retcode, np->rx_done, desc_status); + return retcode; +} + + +#ifdef HAVE_NETDEV_POLL +static int netdev_poll(struct net_device *dev, int *budget) +{ + u32 intr_status; + long ioaddr = dev->base_addr; + int retcode = 0, quota = dev->quota; + + do { + writel(IntrRxDone | IntrRxEmpty, ioaddr + IntrClear); + + retcode = __netdev_rx(dev, "a); + *budget -= (dev->quota - quota); + dev->quota = quota; + if (retcode) + goto out; + + intr_status = readl(ioaddr + IntrStatus); + } while (intr_status & (IntrRxDone | IntrRxEmpty)); + + netif_rx_complete(dev); + intr_status = readl(ioaddr + IntrEnable); + intr_status |= IntrRxDone | IntrRxEmpty; + writel(intr_status, ioaddr + IntrEnable); + + out: + if (debug > 5) + printk(KERN_DEBUG " exiting netdev_poll(): %d.\n", retcode); + + /* Restart Rx engine if stopped. */ + return retcode; +} +#endif /* HAVE_NETDEV_POLL */ + + +static void refill_rx_ring(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + struct sk_buff *skb; + int entry = -1; + /* Refill the Rx ring buffers. */ for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) { - struct sk_buff *skb; - int entry = np->dirty_rx % RX_RING_SIZE; + entry = np->dirty_rx % RX_RING_SIZE; if (np->rx_info[entry].skb == NULL) { skb = dev_alloc_skb(np->rx_buf_sz); np->rx_info[entry].skb = skb; @@ -1527,20 +1766,13 @@ pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; /* Mark as being used by this device. */ np->rx_ring[entry].rxaddr = - cpu_to_le32(np->rx_info[entry].mapping | RxDescValid); + cpu_to_dma(np->rx_info[entry].mapping | RxDescValid); } if (entry == RX_RING_SIZE - 1) - np->rx_ring[entry].rxaddr |= cpu_to_le32(RxDescEndRing); - /* We could defer this until later... */ - writew(entry, dev->base_addr + RxDescQIdx); + np->rx_ring[entry].rxaddr |= cpu_to_dma(RxDescEndRing); } - - if (debug > 5) - printk(KERN_DEBUG " exiting netdev_rx() status of %d was %8.8x.\n", - np->rx_done, desc_status); - - /* Restart Rx engine if stopped. */ - return 0; + if (entry >= 0) + writew(entry, dev->base_addr + RxDescQIdx); } @@ -1550,6 +1782,7 @@ long ioaddr = dev->base_addr; u16 reg0, reg1, reg4, reg5; u32 new_tx_mode; + u32 new_intr_timer_ctrl; /* reset status first */ mdio_read(dev, np->phys[0], MII_BMCR); @@ -1594,15 +1827,23 @@ np->speed100 ? "100" : "10", np->mii_if.full_duplex ? "full" : "half"); - new_tx_mode = np->tx_mode & ~0x2; /* duplex setting */ + new_tx_mode = np->tx_mode & ~FullDuplex; /* duplex setting */ if (np->mii_if.full_duplex) - new_tx_mode |= 2; + new_tx_mode |= FullDuplex; if (np->tx_mode != new_tx_mode) { np->tx_mode = new_tx_mode; - writel(np->tx_mode | 0x8000, ioaddr + TxMode); + writel(np->tx_mode | MiiSoftReset, ioaddr + TxMode); udelay(1000); writel(np->tx_mode, ioaddr + TxMode); } + + new_intr_timer_ctrl = np->intr_timer_ctrl & ~Timer10X; + if (np->speed100) + new_intr_timer_ctrl |= Timer10X; + if (np->intr_timer_ctrl != new_intr_timer_ctrl) { + np->intr_timer_ctrl = new_intr_timer_ctrl; + writel(new_intr_timer_ctrl, ioaddr + IntrTimerCtrl); + } } else { netif_carrier_off(dev); printk(KERN_DEBUG "%s: Link is down\n", dev->name); @@ -1616,9 +1857,12 @@ /* Came close to underrunning the Tx FIFO, increase threshold. */ if (intr_status & IntrTxDataLow) { - writel(++np->tx_threshold, dev->base_addr + TxThreshold); - printk(KERN_NOTICE "%s: Increasing Tx FIFO threshold to %d bytes\n", - dev->name, np->tx_threshold * 16); + if (np->tx_threshold <= PKT_BUF_SZ / 16) { + writel(++np->tx_threshold, dev->base_addr + TxThreshold); + printk(KERN_NOTICE "%s: PCI bus congestion, increasing Tx FIFO threshold to %d bytes\n", + dev->name, np->tx_threshold * 16); + } else + printk(KERN_WARNING "%s: PCI Tx underflow -- adapter is probably malfunctioning\n", dev->name); } if (intr_status & IntrRxGFPDead) { np->stats.rx_fifo_errors++; @@ -1629,7 +1873,7 @@ np->stats.tx_errors++; } if ((intr_status & ~(IntrNormalMask | IntrAbnormalSummary | IntrLinkChange | IntrStatsMax | IntrTxDataLow | IntrRxGFPDead | IntrNoTxCsum | IntrPCIPad)) && debug) - printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n", + printk(KERN_ERR "%s: Something Wicked happened! %#8.8x.\n", dev->name, intr_status); } @@ -1664,39 +1908,67 @@ /* Chips may use the upper or lower CRC bits, and may reverse and/or invert them. Select the endian-ness that results in minimal calculations. */ - static void set_rx_mode(struct net_device *dev) { long ioaddr = dev->base_addr; - u32 rx_mode; + u32 rx_mode = MinVLANPrio; struct dev_mc_list *mclist; int i; +#ifdef VLAN_SUPPORT + struct netdev_private *np = dev->priv; + + rx_mode |= VlanMode; + if (np->vlgrp) { + int vlan_count = 0; + long filter_addr = ioaddr + HashTable + 8; + for (i = 0; i < VLAN_VID_MASK; i++) { + if (np->vlgrp->vlan_devices[i]) { + if (vlan_count >= 32) + break; + writew(cpu_to_be16(i), filter_addr); + filter_addr += 16; + vlan_count++; + } + } + if (i == VLAN_VID_MASK) { + rx_mode |= PerfectFilterVlan; + while (vlan_count < 32) { + writew(0, filter_addr); + filter_addr += 16; + vlan_count++; + } + } + } +#endif /* VLAN_SUPPORT */ if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ - rx_mode = AcceptBroadcast|AcceptAllMulticast|AcceptAll|AcceptMyPhys; + rx_mode |= AcceptAll; } else if ((dev->mc_count > multicast_filter_limit) || (dev->flags & IFF_ALLMULTI)) { /* Too many to match, or accept all multicasts. */ - rx_mode = AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys; - } else if (dev->mc_count <= 15) { - /* Use the 16 element perfect filter, skip first entry. */ - long filter_addr = ioaddr + PerfFilterTable + 1 * 16; - for (i = 1, mclist = dev->mc_list; mclist && i <= dev->mc_count; + rx_mode |= AcceptBroadcast|AcceptAllMulticast|PerfectFilter; + } else if (dev->mc_count <= 14) { + /* Use the 16 element perfect filter, skip first two entries. */ + long filter_addr = ioaddr + PerfFilterTable + 2 * 16; + u16 *eaddrs; + for (i = 2, mclist = dev->mc_list; mclist && i < dev->mc_count + 2; i++, mclist = mclist->next) { - u16 *eaddrs = (u16 *)mclist->dmi_addr; + eaddrs = (u16 *)mclist->dmi_addr; writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 4; writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4; writew(cpu_to_be16(eaddrs[0]), filter_addr); filter_addr += 8; } + eaddrs = (u16 *)dev->dev_addr; while (i++ < 16) { - writew(0xffff, filter_addr); filter_addr += 4; - writew(0xffff, filter_addr); filter_addr += 4; - writew(0xffff, filter_addr); filter_addr += 8; + writew(cpu_to_be16(eaddrs[0]), filter_addr); filter_addr += 4; + writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4; + writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 8; } - rx_mode = AcceptBroadcast | AcceptMyPhys; + rx_mode |= AcceptBroadcast|PerfectFilter; } else { /* Must use a multicast hash table. */ long filter_addr; + u16 *eaddrs; u16 mc_filter[32] __attribute__ ((aligned(sizeof(long)))); /* Multicast hash filter */ memset(mc_filter, 0, sizeof(mc_filter)); @@ -1707,16 +1979,17 @@ *fptr |= cpu_to_le32(1 << (bit_nr & 31)); } - /* Clear the perfect filter list, skip first entry. */ - filter_addr = ioaddr + PerfFilterTable + 1 * 16; - for (i = 1; i < 16; i++) { - writew(0xffff, filter_addr); filter_addr += 4; - writew(0xffff, filter_addr); filter_addr += 4; - writew(0xffff, filter_addr); filter_addr += 8; + /* Clear the perfect filter list, skip first two entries. */ + filter_addr = ioaddr + PerfFilterTable + 2 * 16; + eaddrs = (u16 *)dev->dev_addr; + for (i = 2; i < 16; i++) { + writew(cpu_to_be16(eaddrs[0]), filter_addr); filter_addr += 4; + writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4; + writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 8; } - for (filter_addr = ioaddr + HashTable, i=0; i < 32; filter_addr+= 16, i++) + for (filter_addr = ioaddr + HashTable, i = 0; i < 32; filter_addr+= 16, i++) writew(mc_filter[i], filter_addr); - rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + rx_mode |= AcceptBroadcast|PerfectFilter|HashFilter; } writel(rx_mode, ioaddr + RxFilterMode); } @@ -1763,6 +2036,7 @@ spin_lock_irq(&np->lock); r = mii_ethtool_sset(&np->mii_if, &ecmd); spin_unlock_irq(&np->lock); + check_duplex(dev); return r; } /* restart autonegotiation */ @@ -1816,7 +2090,7 @@ spin_lock_irq(&np->lock); rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL); spin_unlock_irq(&np->lock); - + if ((cmd == SIOCSMIIREG) && (data->phy_id == np->phys[0])) check_duplex(dev); } @@ -1834,41 +2108,42 @@ netif_stop_if(dev); if (debug > 1) { - printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %4.4x.\n", - dev->name, (int)readl(ioaddr + IntrStatus)); - printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n", - dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx); + printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %#8.8x.\n", + dev->name, (int) readl(ioaddr + IntrStatus)); + printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n", + dev->name, np->cur_tx, np->dirty_tx, + np->cur_rx, np->dirty_rx); } /* Disable interrupts by clearing the interrupt mask. */ writel(0, ioaddr + IntrEnable); /* Stop the chip's Tx and Rx processes. */ + writel(0, ioaddr + GenCtrl); + readl(ioaddr + GenCtrl); -#ifdef __i386__ - if (debug > 2) { - printk("\n"KERN_DEBUG" Tx ring at %9.9Lx:\n", - (u64) np->tx_ring_dma); + if (debug > 5) { + printk(KERN_DEBUG" Tx ring at %#llx:\n", + (long long) np->tx_ring_dma); for (i = 0; i < 8 /* TX_RING_SIZE is huge! */; i++) - printk(KERN_DEBUG " #%d desc. %8.8x %8.8x -> %8.8x.\n", + printk(KERN_DEBUG " #%d desc. %#8.8x %#llx -> %#8.8x.\n", i, le32_to_cpu(np->tx_ring[i].status), - le32_to_cpu(np->tx_ring[i].first_addr), + (long long) dma_to_cpu(np->tx_ring[i].addr), le32_to_cpu(np->tx_done_q[i].status)); - printk(KERN_DEBUG " Rx ring at %9.9Lx -> %p:\n", - (u64) np->rx_ring_dma, np->rx_done_q); + printk(KERN_DEBUG " Rx ring at %#llx -> %p:\n", + (long long) np->rx_ring_dma, np->rx_done_q); if (np->rx_done_q) for (i = 0; i < 8 /* RX_RING_SIZE */; i++) { - printk(KERN_DEBUG " #%d desc. %8.8x -> %8.8x\n", - i, le32_to_cpu(np->rx_ring[i].rxaddr), le32_to_cpu(np->rx_done_q[i].status)); + printk(KERN_DEBUG " #%d desc. %#llx -> %#8.8x\n", + i, (long long) dma_to_cpu(np->rx_ring[i].rxaddr), le32_to_cpu(np->rx_done_q[i].status)); } } -#endif /* __i386__ debugging only */ free_irq(dev->irq, dev); /* Free all the skbuffs in the Rx queue. */ for (i = 0; i < RX_RING_SIZE; i++) { - np->rx_ring[i].rxaddr = cpu_to_le32(0xBADF00D0); /* An invalid address. */ + np->rx_ring[i].rxaddr = cpu_to_dma(0xBADF00D0); /* An invalid address. */ if (np->rx_info[i].skb != NULL) { pci_unmap_single(np->pci_dev, np->rx_info[i].mapping, np->rx_buf_sz, PCI_DMA_FROMDEVICE); dev_kfree_skb(np->rx_info[i].skb); @@ -1878,28 +2153,14 @@ } for (i = 0; i < TX_RING_SIZE; i++) { struct sk_buff *skb = np->tx_info[i].skb; -#ifdef ZEROCOPY - int j; -#endif /* ZEROCOPY */ if (skb == NULL) continue; pci_unmap_single(np->pci_dev, - np->tx_info[i].first_mapping, + np->tx_info[i].mapping, skb_first_frag_len(skb), PCI_DMA_TODEVICE); - np->tx_info[i].first_mapping = 0; + np->tx_info[i].mapping = 0; dev_kfree_skb(skb); np->tx_info[i].skb = NULL; -#ifdef ZEROCOPY - for (j = 0; j < MAX_STARFIRE_FRAGS; j++) - if (np->tx_info[i].frag_mapping[j]) { - pci_unmap_single(np->pci_dev, - np->tx_info[i].frag_mapping[j], - skb_shinfo(skb)->frags[j].size, - PCI_DMA_TODEVICE); - np->tx_info[i].frag_mapping[j] = 0; - } else - break; -#endif /* ZEROCOPY */ } COMPAT_MOD_DEC_USE_COUNT; @@ -1917,21 +2178,15 @@ BUG(); np = dev->priv; - if (np->tx_done_q) - pci_free_consistent(pdev, PAGE_SIZE, - np->tx_done_q, np->tx_done_q_dma); - if (np->rx_done_q) - pci_free_consistent(pdev, - sizeof(struct rx_done_desc) * DONE_Q_SIZE, - np->rx_done_q, np->rx_done_q_dma); - if (np->tx_ring) - pci_free_consistent(pdev, PAGE_SIZE, - np->tx_ring, np->tx_ring_dma); - if (np->rx_ring) - pci_free_consistent(pdev, PAGE_SIZE, - np->rx_ring, np->rx_ring_dma); + if (np->queue_mem) + pci_free_consistent(pdev, np->queue_mem_size, np->queue_mem, np->queue_mem_dma); unregister_netdev(dev); + + /* XXX: add wakeup code -- requires firmware for MagicPacket */ + pci_set_power_state(pdev, 3); /* go to sleep in D3 mode */ + pci_disable_device(pdev); + iounmap((char *)dev->base_addr); pci_release_regions(pdev); @@ -1954,6 +2209,17 @@ #ifdef MODULE printk(version); #endif +#ifndef ADDR_64BITS + /* we can do this test only at run-time... sigh */ + if (sizeof(dma_addr_t) == sizeof(u64)) { + printk("This driver has not been ported to this 64-bit architecture yet\n"); + return -ENODEV; + } +#endif /* not ADDR_64BITS */ +#ifndef HAS_FIRMWARE + /* unconditionally disable hw cksums if firmware is not present */ + enable_hw_cksum = 0; +#endif /* not HAS_FIRMWARE */ return pci_module_init (&starfire_driver); } @@ -1970,8 +2236,6 @@ /* * Local variables: - * compile-command: "gcc -DMODULE -Wall -Wstrict-prototypes -O2 -c starfire.c" - * simple-compile-command: "gcc -DMODULE -O2 -c starfire.c" * c-basic-offset: 8 * tab-width: 8 * End: diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c --- a/drivers/net/tg3.c Fri Feb 14 00:27:28 2003 +++ b/drivers/net/tg3.c Fri Feb 14 00:27:28 2003 @@ -6479,8 +6479,11 @@ } #endif - /* Remove this if it causes problems for some boards. */ - tp->dma_rwctrl |= DMA_RWCTRL_USE_MEM_READ_MULT; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { + /* Remove this if it causes problems for some boards. */ + tp->dma_rwctrl |= DMA_RWCTRL_USE_MEM_READ_MULT; + } tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); diff -Nru a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c --- a/drivers/net/tokenring/smctr.c Fri Feb 14 00:27:28 2003 +++ b/drivers/net/tokenring/smctr.c Fri Feb 14 00:27:28 2003 @@ -3064,7 +3064,7 @@ __u8 r; /* Check if node address has been specified by user. (non-0) */ - for(i = 0; ((i < 6) && (dev->dev_addr[i] == 0)); i++); + for(i = 0; ((i < 6) && (dev->dev_addr[i] == 0)); i++) { if(i != 6) { diff -Nru a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c --- a/drivers/net/tulip/de4x5.c Fri Feb 14 00:27:26 2003 +++ b/drivers/net/tulip/de4x5.c Fri Feb 14 00:27:26 2003 @@ -440,8 +440,6 @@ ========================================================================= */ -static char version[] __initdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n"; - #include #include #include @@ -476,6 +474,8 @@ #endif /* CONFIG_PPC */ #include "de4x5.h" + +static char version[] __initdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n"; #define c_char const char #define TWIDDLE(a) (u_short)le16_to_cpu(get_unaligned((u_short *)(a))) diff -Nru a/drivers/net/wan/comx-hw-comx.c b/drivers/net/wan/comx-hw-comx.c --- a/drivers/net/wan/comx-hw-comx.c Fri Feb 14 00:27:27 2003 +++ b/drivers/net/wan/comx-hw-comx.c Fri Feb 14 00:27:27 2003 @@ -492,11 +492,11 @@ COMX_CMD(dev, COMX_CMD_INIT); jiffs = jiffies; - while (COMX_readw(dev, OFF_A_L2_LINKUP) != 1 && jiffies < jiffs + HZ) { + while (COMX_readw(dev, OFF_A_L2_LINKUP) != 1 && time_before(jiffies, jiffs + HZ)) { schedule_timeout(1); } - if (jiffies >= jiffs + HZ) { + if (time_after_eq(jiffies, jiffs + HZ)) { printk(KERN_ERR "%s: board timeout on INIT command\n", dev->name); ch->HW_release_board(dev, savep); retval=-EIO; @@ -507,11 +507,11 @@ COMX_CMD(dev, COMX_CMD_OPEN); jiffs = jiffies; - while (COMX_readw(dev, OFF_A_L2_LINKUP) != 3 && jiffies < jiffs + HZ) { + while (COMX_readw(dev, OFF_A_L2_LINKUP) != 3 && time_before(jiffies, jiffs + HZ)) { schedule_timeout(1); } - if (jiffies >= jiffs + HZ) { + if (time_after_eq(jiffies, jiffs + HZ)) { printk(KERN_ERR "%s: board timeout on OPEN command\n", dev->name); ch->HW_release_board(dev, savep); retval=-EIO; diff -Nru a/drivers/net/wan/comx-hw-mixcom.c b/drivers/net/wan/comx-hw-mixcom.c --- a/drivers/net/wan/comx-hw-mixcom.c Fri Feb 14 00:27:30 2003 +++ b/drivers/net/wan/comx-hw-mixcom.c Fri Feb 14 00:27:30 2003 @@ -104,7 +104,7 @@ unsigned delay = 0; while ((cec = (rd_hscx(dev, HSCX_STAR) & HSCX_CEC) != 0) && - (jiffs + HZ > jiffies)) { + time_before(jiffies, jiffs + HZ)) { udelay(1); if (++delay > (100000 / HZ)) break; } diff -Nru a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c --- a/drivers/net/wireless/orinoco.c Fri Feb 14 00:27:30 2003 +++ b/drivers/net/wireless/orinoco.c Fri Feb 14 00:27:30 2003 @@ -3057,7 +3057,7 @@ ratemode = priv->bitratemode; - if ( (ratemode < 0) || (ratemode > BITRATE_TABLE_SIZE) ) + if ( (ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE) ) BUG(); rrq->value = bitrate_table[ratemode].bitrate * 100000; diff -Nru a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c --- a/drivers/oprofile/buffer_sync.c Fri Feb 14 00:27:27 2003 +++ b/drivers/oprofile/buffer_sync.c Fri Feb 14 00:27:27 2003 @@ -199,8 +199,16 @@ last_cookie = ~0UL; } +static void add_kernel_ctx_switch(unsigned int in_kernel) +{ + add_event_entry(ESCAPE_CODE); + if (in_kernel) + add_event_entry(KERNEL_ENTER_SWITCH_CODE); + else + add_event_entry(KERNEL_EXIT_SWITCH_CODE); +} -static void add_ctx_switch(pid_t pid, unsigned long cookie) +static void add_user_ctx_switch(pid_t pid, unsigned long cookie) { add_event_entry(ESCAPE_CODE); add_event_entry(CTX_SWITCH_CODE); @@ -243,19 +251,13 @@ } -static inline int is_kernel(unsigned long val) -{ - return val > PAGE_OFFSET; -} - - /* Add a sample to the global event buffer. If possible the * sample is converted into a persistent dentry/offset pair * for later lookup from userspace. */ -static void add_sample(struct mm_struct * mm, struct op_sample * s) +static void add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel) { - if (is_kernel(s->eip)) { + if (in_kernel) { add_sample_entry(s->eip, s->event); } else if (mm) { add_us_sample(mm, s); @@ -319,26 +321,34 @@ struct mm_struct * mm = 0; struct task_struct * new; unsigned long cookie; + int in_kernel = 1; int i; for (i=0; i < cpu_buf->pos; ++i) { struct op_sample * s = &cpu_buf->buffer[i]; if (is_ctx_switch(s->eip)) { - new = (struct task_struct *)s->event; - - release_mm(mm); - mm = take_task_mm(new); - - cookie = get_exec_dcookie(mm); - add_ctx_switch(new->pid, cookie); + if (s->event <= 1) { + /* kernel/userspace switch */ + in_kernel = s->event; + add_kernel_ctx_switch(s->event); + } else { + /* userspace context switch */ + new = (struct task_struct *)s->event; + + release_mm(mm); + mm = take_task_mm(new); + + cookie = get_exec_dcookie(mm); + add_user_ctx_switch(new->pid, cookie); + } } else { - add_sample(mm, s); + add_sample(mm, s, in_kernel); } } release_mm(mm); - cpu_buf->pos = 0; + cpu_buffer_reset(cpu_buf); } @@ -364,10 +374,12 @@ * lockers only, and this region is already * protected by buffer_sem. It's raw to prevent * the preempt bogometer firing. Fruity, huh ? */ - _raw_spin_lock(&cpu_buf->int_lock); - add_cpu_switch(i); - sync_buffer(cpu_buf); - _raw_spin_unlock(&cpu_buf->int_lock); + if (cpu_buf->pos > 0) { + _raw_spin_lock(&cpu_buf->int_lock); + add_cpu_switch(i); + sync_buffer(cpu_buf); + _raw_spin_unlock(&cpu_buf->int_lock); + } } up(&buffer_sem); @@ -393,3 +405,4 @@ schedule_work(&sync_wq); /* timer is re-added by the scheduled task */ } + diff -Nru a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c --- a/drivers/oprofile/cpu_buffer.c Fri Feb 14 00:27:26 2003 +++ b/drivers/oprofile/cpu_buffer.c Fri Feb 14 00:27:26 2003 @@ -62,6 +62,7 @@ spin_lock_init(&b->int_lock); b->pos = 0; b->last_task = 0; + b->last_is_kernel = -1; b->sample_received = 0; b->sample_lost_locked = 0; b->sample_lost_overflow = 0; @@ -84,12 +85,20 @@ * be safe from any context. Instead we trylock the CPU's int_lock. * int_lock is taken by the processing code in sync_cpu_buffers() * so we avoid disturbing that. + * + * is_kernel is needed because on some architectures you cannot + * tell if you are in kernel or user space simply by looking at + * eip. We tag this in the buffer by generating kernel enter/exit + * events whenever is_kernel changes */ -void oprofile_add_sample(unsigned long eip, unsigned long event, int cpu) +void oprofile_add_sample(unsigned long eip, unsigned int is_kernel, + unsigned long event, int cpu) { struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[cpu]; struct task_struct * task; + is_kernel = !!is_kernel; + cpu_buf->sample_received++; if (!spin_trylock(&cpu_buf->int_lock)) { @@ -101,9 +110,17 @@ cpu_buf->sample_lost_overflow++; goto out; } - + task = current; + /* notice a switch from user->kernel or vice versa */ + if (cpu_buf->last_is_kernel != is_kernel) { + cpu_buf->last_is_kernel = is_kernel; + cpu_buf->buffer[cpu_buf->pos].eip = ~0UL; + cpu_buf->buffer[cpu_buf->pos].event = is_kernel; + cpu_buf->pos++; + } + /* notice a task switch */ if (cpu_buf->last_task != task) { cpu_buf->last_task = task; @@ -130,3 +147,19 @@ out: spin_unlock(&cpu_buf->int_lock); } + +/* resets the cpu buffer to a sane state - should be called with + * cpu_buf->int_lock held + */ +void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf) +{ + cpu_buf->pos = 0; + + /* reset these to invalid values; the next sample + * collected will populate the buffer with proper + * values to initialize the buffer + */ + cpu_buf->last_is_kernel = -1; + cpu_buf->last_task = 0; +} + diff -Nru a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h --- a/drivers/oprofile/cpu_buffer.h Fri Feb 14 00:27:30 2003 +++ b/drivers/oprofile/cpu_buffer.h Fri Feb 14 00:27:30 2003 @@ -20,7 +20,7 @@ int alloc_cpu_buffers(void); void free_cpu_buffers(void); - + /* CPU buffer is composed of such entries (which are * also used for context switch notes) */ @@ -34,6 +34,7 @@ /* protected by int_lock */ unsigned long pos; struct task_struct * last_task; + int last_is_kernel; struct op_sample * buffer; unsigned long sample_received; unsigned long sample_lost_locked; @@ -42,5 +43,7 @@ } ____cacheline_aligned; extern struct oprofile_cpu_buffer cpu_buffer[]; + +void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf); #endif /* OPROFILE_CPU_BUFFER_H */ diff -Nru a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h --- a/drivers/oprofile/event_buffer.h Fri Feb 14 00:27:27 2003 +++ b/drivers/oprofile/event_buffer.h Fri Feb 14 00:27:27 2003 @@ -25,9 +25,11 @@ * relevant data. */ #define ESCAPE_CODE ~0UL -#define CTX_SWITCH_CODE 1 -#define CPU_SWITCH_CODE 2 -#define COOKIE_SWITCH_CODE 3 +#define CTX_SWITCH_CODE 1 +#define CPU_SWITCH_CODE 2 +#define COOKIE_SWITCH_CODE 3 +#define KERNEL_ENTER_SWITCH_CODE 4 +#define KERNEL_EXIT_SWITCH_CODE 5 /* add data to the event buffer */ void add_event_entry(unsigned long data); diff -Nru a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c --- a/drivers/oprofile/oprof.c Fri Feb 14 00:27:27 2003 +++ b/drivers/oprofile/oprof.c Fri Feb 14 00:27:27 2003 @@ -20,7 +20,6 @@ #include "oprofile_stats.h" struct oprofile_operations * oprofile_ops; -enum oprofile_cpu oprofile_cpu_type; unsigned long oprofile_started; static unsigned long is_setup; static DECLARE_MUTEX(start_sem); @@ -127,9 +126,15 @@ /* Architecture must fill in the interrupt ops and the * logical CPU type. */ - err = oprofile_arch_init(&oprofile_ops, &oprofile_cpu_type); + err = oprofile_arch_init(&oprofile_ops); if (err) goto out; + + if (!oprofile_ops->cpu_type) { + printk(KERN_ERR "oprofile: cpu_type not set !\n"); + err = -EFAULT; + goto out; + } err = oprofilefs_register(); if (err) diff -Nru a/drivers/oprofile/oprof.h b/drivers/oprofile/oprof.h --- a/drivers/oprofile/oprof.h Fri Feb 14 00:27:27 2003 +++ b/drivers/oprofile/oprof.h Fri Feb 14 00:27:27 2003 @@ -24,7 +24,6 @@ extern unsigned long fs_buffer_size; extern unsigned long fs_cpu_buffer_size; extern unsigned long fs_buffer_watershed; -extern enum oprofile_cpu oprofile_cpu_type; extern struct oprofile_operations * oprofile_ops; extern unsigned long oprofile_started; diff -Nru a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c --- a/drivers/oprofile/oprofile_files.c Fri Feb 14 00:27:28 2003 +++ b/drivers/oprofile/oprofile_files.c Fri Feb 14 00:27:28 2003 @@ -21,9 +21,7 @@ static ssize_t cpu_type_read(struct file * file, char * buf, size_t count, loff_t * offset) { - unsigned long cpu_type = oprofile_cpu_type; - - return oprofilefs_ulong_to_user(&cpu_type, buf, count, offset); + return oprofilefs_str_to_user(oprofile_ops->cpu_type, buf, count, offset); } diff -Nru a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c --- a/drivers/oprofile/oprofilefs.c Fri Feb 14 00:27:27 2003 +++ b/drivers/oprofile/oprofilefs.c Fri Feb 14 00:27:27 2003 @@ -44,6 +44,29 @@ .drop_inode = generic_delete_inode, }; + +ssize_t oprofilefs_str_to_user(char const * str, char * buf, size_t count, loff_t * offset) +{ + size_t len = strlen(str); + + if (!count) + return 0; + + if (*offset > len) + return 0; + + if (count > len - *offset) + count = len - *offset; + + if (copy_to_user(buf, str + *offset, count)) + return -EFAULT; + + *offset += count; + + return count; +} + + #define TMPBUFSIZE 50 ssize_t oprofilefs_ulong_to_user(unsigned long * val, char * buf, size_t count, loff_t * offset) @@ -91,7 +114,7 @@ return -EFAULT; spin_lock(&oprofilefs_lock); - *val = simple_strtoul(tmpbuf, NULL, 10); + *val = simple_strtoul(tmpbuf, NULL, 0); spin_unlock(&oprofilefs_lock); return 0; } diff -Nru a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c --- a/drivers/pcmcia/i82092.c Fri Feb 14 00:27:30 2003 +++ b/drivers/pcmcia/i82092.c Fri Feb 14 00:27:30 2003 @@ -384,7 +384,7 @@ unsigned int val; enter("card_present"); - if ((socketno<0) || (socketno > MAX_SOCKETS)) + if ((socketno<0) || (socketno >= MAX_SOCKETS)) return 0; if (sockets[socketno].io_base == 0) return 0; diff -Nru a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c --- a/drivers/pnp/pnpbios/core.c Fri Feb 14 00:27:26 2003 +++ b/drivers/pnp/pnpbios/core.c Fri Feb 14 00:27:26 2003 @@ -615,8 +615,8 @@ { static struct pnp_docking_station_info now; int docked = -1, d = 0; - daemonize(); - strcpy(current->comm, "kpnpbiosd"); + daemonize("kpnpbiosd"); + allow_signal(SIGKILL); while(!unloading && !signal_pending(current)) { int status; diff -Nru a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c --- a/drivers/s390/net/lcs.c Fri Feb 14 00:27:27 2003 +++ b/drivers/s390/net/lcs.c Fri Feb 14 00:27:27 2003 @@ -908,7 +908,7 @@ card = (struct lcs_card *) data; - daemonize(); + daemonize("fixipm"); LCS_DBF_TEXT(5, trace, "fixipm"); spin_lock(&card->lock); list_for_each_safe(l, n, &card->ipm_list) { @@ -1370,7 +1370,7 @@ struct lcs_card *card; card = (struct lcs_card *) data; - daemonize(); + daemonize("lgwstpln"); LCS_DBF_TEXT(4, trace, "lgwstpln"); if (card->dev) netif_stop_queue(card->dev); @@ -1397,7 +1397,7 @@ struct lcs_card *card; card = (struct lcs_card *) data; - daemonize(); + daemonize("lgwstpln"); LCS_DBF_TEXT(4, trace, "lgwstpln"); if (card->dev) netif_stop_queue(card->dev); @@ -1436,7 +1436,7 @@ struct lcs_card *card; card = (struct lcs_card *) data; - daemonize(); + daemonize("lgwstop"); LCS_DBF_TEXT(4, trace, "lgwstop"); if (card->dev) netif_stop_queue(card->dev); diff -Nru a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c --- a/drivers/sbus/char/bbc_envctrl.c Fri Feb 14 00:27:28 2003 +++ b/drivers/sbus/char/bbc_envctrl.c Fri Feb 14 00:27:28 2003 @@ -457,8 +457,8 @@ static int kenvctrld(void *__unused) { - daemonize(); - strcpy(current->comm, "kenvctrld"); + daemonize("kenvctrld"); + allow_signal(SIGKILL); kenvctrld_task = current; printk(KERN_INFO "bbc_envctrl: kenvctrld starting...\n"); diff -Nru a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c --- a/drivers/sbus/char/envctrl.c Fri Feb 14 00:27:27 2003 +++ b/drivers/sbus/char/envctrl.c Fri Feb 14 00:27:27 2003 @@ -1016,8 +1016,9 @@ poll_interval = 5 * HZ; /* TODO env_mon_interval */ - daemonize(); - strcpy(current->comm, "kenvctrld"); + daemonize("kenvctrld"); + allow_signal(SIGKILL); + kenvctrld_task = current; printk(KERN_INFO "envctrl: %s starting...\n", current->comm); diff -Nru a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c --- a/drivers/scsi/aacraid/aachba.c Fri Feb 14 00:27:28 2003 +++ b/drivers/scsi/aacraid/aachba.c Fri Feb 14 00:27:28 2003 @@ -1094,7 +1094,7 @@ qd.cnum = TARGET_LUN_TO_CONTAINER(qd.target, qd.lun); else if ((qd.bus == -1) && (qd.target == -1) && (qd.lun == -1)) { - if (qd.cnum < 0 || qd.cnum > MAXIMUM_NUM_CONTAINERS) + if (qd.cnum < 0 || qd.cnum >= MAXIMUM_NUM_CONTAINERS) return -EINVAL; qd.instance = dev->scsi_host_ptr->host_no; qd.bus = 0; @@ -1129,7 +1129,7 @@ if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk))) return -EFAULT; - if (dd.cnum > MAXIMUM_NUM_CONTAINERS) + if (dd.cnum >= MAXIMUM_NUM_CONTAINERS) return -EINVAL; /* * Mark this container as being deleted. @@ -1152,7 +1152,7 @@ if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk))) return -EFAULT; - if (dd.cnum > MAXIMUM_NUM_CONTAINERS) + if (dd.cnum >= MAXIMUM_NUM_CONTAINERS) return -EINVAL; /* * If the container is locked, it can not be deleted by the API. diff -Nru a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c --- a/drivers/scsi/aacraid/commsup.c Fri Feb 14 00:27:29 2003 +++ b/drivers/scsi/aacraid/commsup.c Fri Feb 14 00:27:29 2003 @@ -816,8 +816,8 @@ * Set up the name that will appear in 'ps' * stored in task_struct.comm[16]. */ - sprintf(current->comm, "aacraid"); - daemonize(); + daemonize("aacraid"); + allow_signal(SIGKILL); /* * Let the DPC know it has a place to send the AIF's to. */ diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c --- a/drivers/scsi/aic7xxx/aic79xx_osm.c Fri Feb 14 00:27:26 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c Fri Feb 14 00:27:26 2003 @@ -1560,7 +1560,7 @@ hscb = scb->hscb; hscb->control = 0; hscb->scsiid = BUILD_SCSIID(ahd, cmd); - hscb->lun = cmd->lun; + hscb->lun = cmd->device->lun; hscb->cdb_len = 0; hscb->task_management = SIU_TASKMGMT_LUN_RESET; scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE; @@ -2854,8 +2854,7 @@ * Complete thread creation. */ lock_kernel(); - daemonize(); - sprintf(current->comm, "ahd_dv_%d", ahd->unit); + daemonize("ahd_dv_%d", ahd->unit); unlock_kernel(); while (1) { diff -Nru a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c --- a/drivers/scsi/aic7xxx/aic79xx_pci.c Fri Feb 14 00:27:28 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_pci.c Fri Feb 14 00:27:28 2003 @@ -691,7 +691,7 @@ static const char *split_status_strings[] = { - "%s: Received split response in %s.\n" + "%s: Received split response in %s.\n", "%s: Received split completion error message in %s\n", "%s: Receive overrun in %s\n", "%s: Count not complete in %s\n", diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c --- a/drivers/scsi/aic7xxx/aic7xxx_core.c Fri Feb 14 00:27:28 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c Fri Feb 14 00:27:28 2003 @@ -4708,8 +4708,8 @@ #ifdef AHC_DEBUG if (ahc_debug & AHC_SHOW_MISC) { - printf("%s: hardware scb %d bytes; kernel scb %d bytes; " - "ahc_dma %d bytes\n", + printf("%s: hardware scb %Zu bytes; kernel scb %Zu bytes; " + "ahc_dma %Zu bytes\n", ahc_name(ahc), sizeof(struct hardware_scb), sizeof(struct scb), diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c Fri Feb 14 00:27:27 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c Fri Feb 14 00:27:27 2003 @@ -2355,16 +2355,10 @@ #endif /* - * Don't care about any signals. - */ - siginitsetinv(¤t->blocked, 0); - - /* * Complete thread creation. */ lock_kernel(); - daemonize(); - sprintf(current->comm, "ahc_dv_%d", ahc->unit); + daemonize("ahc_dv_%d", ahc->unit); unlock_kernel(); while (1) { diff -Nru a/drivers/scsi/cpqfcTSworker.c b/drivers/scsi/cpqfcTSworker.c --- a/drivers/scsi/cpqfcTSworker.c Fri Feb 14 00:27:29 2003 +++ b/drivers/scsi/cpqfcTSworker.c Fri Feb 14 00:27:29 2003 @@ -165,15 +165,10 @@ ENTER("WorkerThread"); lock_kernel(); - daemonize(); + daemonize("cpqfcTS_wt_%d", HostAdapter->host_no); siginitsetinv(¤t->blocked, SHUTDOWN_SIGS); - /* - * Set the name of this process. - */ - sprintf(current->comm, "cpqfcTS_wt_%d", HostAdapter->host_no); - cpqfcHBAdata->fcQueReady = &fcQueReady; // primary wait point cpqfcHBAdata->TYOBcomplete = &fcTYOBcomplete; cpqfcHBAdata->TachFrozen = &TachFrozen; @@ -448,7 +443,7 @@ LONG x_ID = fcLQ->Qitem[QconsumerNdx].ulBuff[0]; BOOLEAN FrozeTach = FALSE; - if( x_ID > TACH_SEST_LEN ) // (in)sanity check + if ( x_ID >= TACH_SEST_LEN ) // (in)sanity check { // printk( " cpqfcTS ERROR! BOGUS x_ID %Xh", x_ID); break; diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c --- a/drivers/scsi/dpt_i2o.c Fri Feb 14 00:27:29 2003 +++ b/drivers/scsi/dpt_i2o.c Fri Feb 14 00:27:29 2003 @@ -1402,7 +1402,7 @@ printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no); continue; } - if(scsi_id > MAX_ID){ + if (scsi_id >= MAX_ID){ printk(KERN_WARNING"%s: SCSI ID %d out of range \n", pHba->name, bus_no); continue; } @@ -1476,7 +1476,7 @@ if(bus_no >= MAX_CHANNEL) { // Something wrong skip it continue; } - if(scsi_id > MAX_ID){ + if (scsi_id >= MAX_ID) { continue; } if( pHba->channel[bus_no].device[scsi_id] == NULL){ diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c --- a/drivers/scsi/eata.c Fri Feb 14 00:27:29 2003 +++ b/drivers/scsi/eata.c Fri Feb 14 00:27:29 2003 @@ -1193,9 +1193,9 @@ } #endif - spin_unlock(&driver_lock); + spin_unlock_irq(&driver_lock); sh[j] = scsi_register(tpnt, sizeof(struct hostdata)); - spin_lock(&driver_lock); + spin_lock_irq(&driver_lock); if (sh[j] == NULL) { printk("%s: unable to register host, detaching.\n", name); @@ -1450,9 +1450,8 @@ static int eata2x_detect(Scsi_Host_Template *tpnt) { unsigned int j = 0, k; - unsigned long spin_flags; - spin_lock_irqsave(&driver_lock, spin_flags); + spin_lock_irq(&driver_lock); tpnt->proc_name = "eata2x"; @@ -1490,7 +1489,7 @@ } num_boards = j; - spin_unlock_irqrestore(&driver_lock, spin_flags); + spin_unlock_irq(&driver_lock); return j; } diff -Nru a/drivers/scsi/imm.c b/drivers/scsi/imm.c --- a/drivers/scsi/imm.c Fri Feb 14 00:27:30 2003 +++ b/drivers/scsi/imm.c Fri Feb 14 00:27:30 2003 @@ -733,7 +733,7 @@ static inline int imm_send_command(Scsi_Cmnd * cmd) { - int host_no = cmd->host->unique_id; + int host_no = cmd->device->host->unique_id; int k; /* NOTE: IMM uses byte pairs */ @@ -758,7 +758,7 @@ * 0 Told to schedule * 1 Finished data transfer */ - int host_no = cmd->host->unique_id; + int host_no = cmd->device->host->unique_id; unsigned short ppb = IMM_BASE(host_no); unsigned long start_jiffies = jiffies; @@ -845,7 +845,7 @@ int imm_command(Scsi_Cmnd * cmd) { static int first_pass = 1; - int host_no = cmd->host->unique_id; + int host_no = cmd->device->host->unique_id; if (first_pass) { printk("imm: using non-queuing interface\n"); @@ -867,7 +867,7 @@ schedule(); if (cmd->SCp.phase) /* Only disconnect if we have connected */ - imm_disconnect(cmd->host->unique_id); + imm_disconnect(cmd->device->host->unique_id); imm_pb_release(host_no); imm_hosts[host_no].cur_cmd = 0; @@ -883,7 +883,7 @@ { imm_struct *tmp = (imm_struct *) data; Scsi_Cmnd *cmd = tmp->cur_cmd; - struct Scsi_Host *host = cmd->host; + struct Scsi_Host *host = cmd->device->host; unsigned long flags; if (!cmd) { @@ -930,9 +930,9 @@ #endif if (cmd->SCp.phase > 1) - imm_disconnect(cmd->host->unique_id); + imm_disconnect(cmd->device->host->unique_id); if (cmd->SCp.phase > 0) - imm_pb_release(cmd->host->unique_id); + imm_pb_release(cmd->device->host->unique_id); spin_lock_irqsave(host->host_lock, flags); tmp->cur_cmd = 0; @@ -943,7 +943,7 @@ static int imm_engine(imm_struct * tmp, Scsi_Cmnd * cmd) { - int host_no = cmd->host->unique_id; + int host_no = cmd->device->host->unique_id; unsigned short ppb = IMM_BASE(host_no); unsigned char l = 0, h = 0; int retv, x; @@ -972,7 +972,7 @@ /* Phase 2 - We are now talking to the scsi bus */ case 2: - if (!imm_select(host_no, cmd->target)) { + if (!imm_select(host_no, cmd->device->id)) { imm_fail(host_no, DID_NO_CONNECT); return 0; } @@ -1082,7 +1082,7 @@ int imm_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) { - int host_no = cmd->host->unique_id; + int host_no = cmd->device->host->unique_id; if (imm_hosts[host_no].cur_cmd) { printk("IMM: bug in imm_queuecommand\n"); @@ -1125,7 +1125,7 @@ int imm_abort(Scsi_Cmnd * cmd) { - int host_no = cmd->host->unique_id; + int host_no = cmd->device->host->unique_id; /* * There is no method for aborting commands since Iomega * have tied the SCSI_MESSAGE line high in the interface @@ -1157,7 +1157,7 @@ int imm_reset(Scsi_Cmnd * cmd) { - int host_no = cmd->host->unique_id; + int host_no = cmd->device->host->unique_id; if (cmd->SCp.phase) imm_disconnect(host_no); diff -Nru a/drivers/scsi/ips.c b/drivers/scsi/ips.c --- a/drivers/scsi/ips.c Fri Feb 14 00:27:26 2003 +++ b/drivers/scsi/ips.c Fri Feb 14 00:27:26 2003 @@ -195,14 +195,14 @@ * DRIVER_VER */ #define IPS_VERSION_HIGH "5.99" -#define IPS_VERSION_LOW ".00-BETA" +#define IPS_VERSION_LOW ".01-BETA" #if !defined(__i386__) && !defined(__ia64__) #error "This driver has only been tested on the x86/ia64 platforms" #endif -#if LINUX_VERSION_CODE <= LinuxVersionCode(2,5,0) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) #include "sd.h" #define IPS_SG_ADDRESS(sg) ((sg)->address) #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags) @@ -241,6 +241,7 @@ static unsigned int ips_next_controller = 0; static unsigned int ips_num_controllers = 0; static unsigned int ips_released_controllers = 0; +static int ips_hotplug; static int ips_cmd_timeout = 60; static int ips_reset_timeout = 60 * 5; static int ips_force_memio = 1; /* Always use Memory Mapped I/O */ @@ -572,7 +573,7 @@ ips_free(ips_ha[i]); ips_released_controllers++; } - + ips_hotplug = 1; return (ips_num_controllers); } @@ -702,6 +703,7 @@ /* free IRQ */ free_irq(ha->irq, ha); + IPS_REMOVE_HOST(sh); scsi_unregister(sh); ips_released_controllers++; @@ -1136,17 +1138,21 @@ /* */ /****************************************************************************/ static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +ips_biosparam(Disk *disk, kdev_t dev, int geom[]) { + ips_ha_t *ha = (ips_ha_t *) disk->device->host->hostdata; + unsigned long capacity = disk->capacity; +#else ips_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]) { - ips_ha_t *ha; + ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata; +#endif int heads; int sectors; int cylinders; METHOD_TRACE("ips_biosparam", 1); - ha = (ips_ha_t *) sdev->host->hostdata; - if (!ha) /* ?!?! host adater info invalid */ return (0); @@ -1178,7 +1184,7 @@ return (0); } - +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /****************************************************************************/ /* */ /* Routine Name: ips_select_queue_depth */ @@ -1188,7 +1194,7 @@ /* Select queue depths for the devices on the contoller */ /* */ /****************************************************************************/ -/*static void +static void ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) { Scsi_Device *device; ips_ha_t *ha; @@ -1221,8 +1227,8 @@ } } } -*/ +#else /****************************************************************************/ /* */ /* Routine Name: ips_slave_configure */ @@ -1247,6 +1253,7 @@ } return 0; } +#endif /****************************************************************************/ /* */ @@ -3375,8 +3382,8 @@ ips_name, ha->host_num, scb->scsi_cmd->device->channel, - scb->scsi_cmd->channel->id, - scb->scsi_cmd->channel->lun, + scb->scsi_cmd->device->id, + scb->scsi_cmd->device->lun, scb->basic_status, scb->extended_status, scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0, @@ -4223,6 +4230,12 @@ mdata.pdata.pg4.RotationalOffset = 0; mdata.pdata.pg4.MediumRotationRate = 0; break; + case 0x8: + mdata.pdata.pg8.PageCode = 8; + mdata.pdata.pg8.PageLength = sizeof(IPS_SCSI_MODE_PAGE8); + mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength; + /* everything else is left set to 0 */ + break; default: return (0); @@ -6744,7 +6757,7 @@ sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma; sh->use_clustering = sh->hostt->use_clustering; -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) sh->max_sectors = 128; #endif @@ -6753,6 +6766,7 @@ sh->max_channel = ha->nbus - 1; sh->can_queue = ha->max_cmds-1; + IPS_ADD_HOST(sh, NULL); return 0; } @@ -6793,11 +6807,11 @@ return -ENODEV; ips_driver_template.module = THIS_MODULE; ips_order_controllers(); - if( scsi_register_host(&ips_driver_template) ){ + if( IPS_REGISTER_HOSTS(&ips_driver_template) ){ pci_unregister_driver(&ips_pci_driver); return -ENODEV; } - + register_reboot_notifier(&ips_notifier); return 0; } @@ -6810,7 +6824,7 @@ /****************************************************************************/ static void __exit ips_module_exit(void){ - scsi_unregister_host(&ips_driver_template); + IPS_UNREGISTER_HOSTS(&ips_driver_template); pci_unregister_driver(&ips_pci_driver); unregister_reboot_notifier(&ips_notifier); } @@ -6840,6 +6854,12 @@ if (rc == SUCCESS) rc = ips_init_phase2(index); + if(ips_hotplug) + if(ips_register_scsi(index)){ + ips_free(ips_ha[index]); + rc = -1; + } + if (rc == SUCCESS) ips_num_controllers++; @@ -7127,7 +7147,7 @@ } -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,9) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9) MODULE_LICENSE("GPL"); #endif diff -Nru a/drivers/scsi/ips.h b/drivers/scsi/ips.h --- a/drivers/scsi/ips.h Fri Feb 14 00:27:27 2003 +++ b/drivers/scsi/ips.h Fri Feb 14 00:27:27 2003 @@ -64,11 +64,7 @@ /* * Some handy macros */ - #ifndef LinuxVersionCode - #define LinuxVersionCode(x,y,z) (((x)<<16)+((y)<<8)+(z)) - #endif - - #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,20) || defined CONFIG_HIGHIO + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) || defined CONFIG_HIGHIO #define IPS_HIGHIO #define IPS_HIGHMEM_IO .highmem_io = 1, #else @@ -97,14 +93,21 @@ #define IPS_SGLIST_SIZE(ha) (IPS_USE_ENH_SGLIST(ha) ? \ sizeof(IPS_ENH_SG_LIST) : sizeof(IPS_STD_SG_LIST)) - #if LINUX_VERSION_CODE < LinuxVersionCode(2,4,4) + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4) #define pci_set_dma_mask(dev,mask) (1) #define scsi_set_pci_device(sh,dev) (0) #endif - #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) - #define scsi_register_host(x) scsi_register_module(MODULE_SCSI_HA,x) - #define scsi_unregister_host(x) scsi_unregister_module(MODULE_SCSI_HA,x) + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + #define IPS_REGISTER_HOSTS(SHT) scsi_register_module(MODULE_SCSI_HA,SHT) + #define IPS_UNREGISTER_HOSTS(SHT) scsi_unregister_module(MODULE_SCSI_HA,SHT) + #define IPS_ADD_HOST(shost,device) + #define IPS_REMOVE_HOST(shost) + #else + #define IPS_REGISTER_HOSTS(SHT) (!ips_detect(SHT)) + #define IPS_UNREGISTER_HOSTS(SHT) + #define IPS_ADD_HOST(shost,device) scsi_add_host(shost,device) + #define IPS_REMOVE_HOST(shost) scsi_remove_host(shost) #endif #ifndef MDELAY @@ -439,7 +442,7 @@ /* * Scsi_Host Template */ -#if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *); static int ips_biosparam(Disk *disk, kdev_t dev, int geom[]); #define IPS { \ @@ -959,6 +962,20 @@ } IPS_SCSI_MODE_PAGE4; /* + * Sense Data Format - Page 8 + */ +typedef struct { + uint8_t PageCode; + uint8_t PageLength; + uint8_t flags; + uint8_t RetentPrio; + uint16_t DisPrefetchLen; + uint16_t MinPrefetchLen; + uint16_t MaxPrefetchLen; + uint16_t MaxPrefetchCeiling; +} IPS_SCSI_MODE_PAGE8; + +/* * Sense Data Format - Block Descriptor (DASD) */ typedef struct { @@ -985,6 +1002,7 @@ union { IPS_SCSI_MODE_PAGE3 pg3; IPS_SCSI_MODE_PAGE4 pg4; + IPS_SCSI_MODE_PAGE8 pg8; } pdata; } IPS_SCSI_MODE_PAGE_DATA; diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c --- a/drivers/scsi/scsi_error.c Fri Feb 14 00:27:26 2003 +++ b/drivers/scsi/scsi_error.c Fri Feb 14 00:27:26 2003 @@ -1579,24 +1579,14 @@ int rtn; DECLARE_MUTEX_LOCKED(sem); - spin_lock_irq(¤t->sighand->siglock); - sigfillset(¤t->blocked); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - lock_kernel(); /* * Flush resources */ - daemonize(); - - /* - * Set the name of this process. - */ + daemonize("scsi_eh_%d", shost->host_no); - sprintf(current->comm, "scsi_eh_%d", shost->host_no); current->flags |= PF_IOTHREAD; shost->eh_wait = &sem; diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c --- a/drivers/scsi/st.c Fri Feb 14 00:27:29 2003 +++ b/drivers/scsi/st.c Fri Feb 14 00:27:29 2003 @@ -3618,7 +3618,7 @@ static ssize_t st_device_kdev_read(struct device *dev, char *page) { kdev_t kdev; - kdev.value=(int)dev->driver_data; + kdev.value=(unsigned long)dev->driver_data; return sprintf(page, "%x\n",kdev.value); } static DEVICE_ATTR(kdev,S_IRUGO,st_device_kdev_read,NULL); diff -Nru a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c --- a/drivers/scsi/sym53c416.c Fri Feb 14 00:27:27 2003 +++ b/drivers/scsi/sym53c416.c Fri Feb 14 00:27:27 2003 @@ -272,7 +272,7 @@ { i = jiffies + timeout; spin_unlock_irqrestore(&sym53c416_lock, flags); - while(jiffies < i && (inb(base + PIO_INT_REG) & EMPTY) && timeout) + while(time_before(jiffies, i) && (inb(base + PIO_INT_REG) & EMPTY) && timeout) if(inb(base + PIO_INT_REG) & SCI) timeout = 0; spin_lock_irqsave(&sym53c416_lock, flags); @@ -316,7 +316,7 @@ { i = jiffies + timeout; spin_unlock_irqrestore(&sym53c416_lock, flags); - while(jiffies < i && (inb(base + PIO_INT_REG) & FULL) && timeout) + while(time_before(jiffies, i) && (inb(base + PIO_INT_REG) & FULL) && timeout) ; spin_lock_irqsave(&sym53c416_lock, flags); if(inb(base + PIO_INT_REG) & FULL) @@ -552,7 +552,7 @@ outb(0x00, base + DEST_BUS_ID); /* Wait for interrupt to occur */ i = jiffies + 20; - while(i > jiffies && !(inb(base + STATUS_REG) & SCI)) + while(time_before(jiffies, i) && !(inb(base + STATUS_REG) & SCI)) barrier(); if(time_before_eq(i, jiffies)) /* timed out */ return 0; diff -Nru a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c --- a/drivers/scsi/u14-34f.c Fri Feb 14 00:27:27 2003 +++ b/drivers/scsi/u14-34f.c Fri Feb 14 00:27:27 2003 @@ -847,9 +847,9 @@ if (have_old_firmware) tpnt->use_clustering = DISABLE_CLUSTERING; - spin_unlock(&driver_lock); + spin_unlock_irq(&driver_lock); sh[j] = scsi_register(tpnt, sizeof(struct hostdata)); - spin_lock(&driver_lock); + spin_lock_irq(&driver_lock); if (sh[j] == NULL) { printk("%s: unable to register host, detaching.\n", name); diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c --- a/drivers/serial/sunsu.c Fri Feb 14 00:27:27 2003 +++ b/drivers/serial/sunsu.c Fri Feb 14 00:27:27 2003 @@ -527,7 +527,7 @@ } kbd_pt_regs = regs; #ifdef CONFIG_SERIO - serio_interrupt(&up->serio, ch, 0); + serio_interrupt(&up->serio, ch, 0, regs); #endif } else if (up->su_type == SU_PORT_MS) { int ret = suncore_mouse_baud_detection(ch, is_break); @@ -541,7 +541,7 @@ case 0: #ifdef CONFIG_SERIO - serio_interrupt(&up->serio, ch, 0); + serio_interrupt(&up->serio, ch, 0, regs); #endif break; }; diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c --- a/drivers/serial/sunzilog.c Fri Feb 14 00:27:30 2003 +++ b/drivers/serial/sunzilog.c Fri Feb 14 00:27:30 2003 @@ -303,7 +303,7 @@ } kbd_pt_regs = regs; #ifdef CONFIG_SERIO - serio_interrupt(&up->serio, ch, 0); + serio_interrupt(&up->serio, ch, 0, regs); #endif } else if (ZS_IS_MOUSE(up)) { int ret = suncore_mouse_baud_detection(ch, is_break); @@ -317,7 +317,7 @@ case 0: #ifdef CONFIG_SERIO - serio_interrupt(&up->serio, ch, 0); + serio_interrupt(&up->serio, ch, 0, regs); #endif break; }; @@ -488,6 +488,8 @@ return; } + up->flags &= ~SUNZILOG_FLAG_TX_ACTIVE; + if (ZS_REGS_HELD(up)) { __load_zsregs(channel, up->curregs); up->flags &= ~SUNZILOG_FLAG_REGS_HELD; @@ -495,15 +497,11 @@ if (ZS_TX_STOPPED(up)) { up->flags &= ~SUNZILOG_FLAG_TX_STOPPED; - - sbus_writeb(RES_Tx_P, &channel->control); - ZSDELAY(); - ZS_WSYNC(channel); - - return; + goto ack_tx_int; } if (up->port.x_char) { + up->flags |= SUNZILOG_FLAG_TX_ACTIVE; sbus_writeb(up->port.x_char, &channel->data); ZSDELAY(); ZS_WSYNC(channel); @@ -516,9 +514,14 @@ if (up->port.info == NULL) goto ack_tx_int; xmit = &up->port.info->xmit; - if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) + if (uart_circ_empty(xmit)) { + uart_write_wakeup(&up->port); + goto ack_tx_int; + } + if (uart_tx_stopped(&up->port)) goto ack_tx_int; + up->flags |= SUNZILOG_FLAG_TX_ACTIVE; sbus_writeb(xmit->buf[xmit->tail], &channel->data); ZSDELAY(); ZS_WSYNC(channel); @@ -529,9 +532,6 @@ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&up->port); - if (uart_circ_empty(xmit)) - goto ack_tx_int; - return; ack_tx_int: @@ -725,6 +725,9 @@ struct zilog_channel *channel; unsigned long flags; + if (ZS_IS_CONS(up)) + return; + spin_lock_irqsave(&port->lock, flags); channel = ZILOG_CHANNEL_FROM_PORT(port); @@ -1027,7 +1030,7 @@ .owner = THIS_MODULE, .driver_name = "ttyS", #ifdef CONFIG_DEVFS_FS - .dev_name = "ttyS%d", + .dev_name = "tts/%d", #else .dev_name = "ttyS%d", #endif @@ -1481,7 +1484,7 @@ /* * Temporary fix. */ - for (channel = 0; channel < NUM_CHANNELS - 1; channel++) + for (channel = 0; channel < NUM_CHANNELS; channel++) spin_lock_init(&sunzilog_port_table[channel].port.lock); sunzilog_irq_chain = up = &sunzilog_port_table[0]; @@ -1588,6 +1591,7 @@ } else { /* Normal serial TTY. */ up->parity_mask = 0xff; + up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB; up->curregs[R4] = PAR_EVEN | X16CLK | SB1; up->curregs[R3] = RxENAB | Rx8; up->curregs[R5] = TxENAB | Tx8; diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c --- a/drivers/usb/core/hub.c Fri Feb 14 00:27:28 2003 +++ b/drivers/usb/core/hub.c Fri Feb 14 00:27:28 2003 @@ -1083,10 +1083,8 @@ * so get rid of all our resources */ - daemonize(); - - /* Setup a nice name */ - strcpy(current->comm, "khubd"); + daemonize("khubd"); + allow_signal(SIGKILL); /* Send me a signal to get me die (for debugging) */ do { diff -Nru a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig --- a/drivers/usb/input/Kconfig Fri Feb 14 00:27:29 2003 +++ b/drivers/usb/input/Kconfig Fri Feb 14 00:27:29 2003 @@ -49,7 +49,7 @@ If unsure, say N. config HID_PID - bool "PID Devices" + bool "PID Devices (Microsoft Sidewinder Force Feedback 2)" depends on HID_FF help Say Y here if you have a PID-compliant joystick and wish to enable force @@ -67,6 +67,15 @@ Note: if you say N here, this device will still be supported, but without force feedback. +config THRUSTMASTER_FF + bool "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)" + depends on HID_FF && EXPERIMENTAL + help + Say Y here if you have a THRUSTMASTER FireStore Dual Power 2, + and want to enable force feedback support for it. + Note: if you say N here, this device will still be supported, but without + force feedback. + config USB_HIDDEV bool "/dev/hiddev raw HID device support" depends on USB_HID @@ -80,7 +89,6 @@ This driver requires CONFIG_USB_HID. If unsure, say Y. - menu "USB HID Boot Protocol drivers" depends on USB!=n && USB_HID!=y diff -Nru a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile --- a/drivers/usb/input/Makefile Fri Feb 14 00:27:29 2003 +++ b/drivers/usb/input/Makefile Fri Feb 14 00:27:29 2003 @@ -19,6 +19,9 @@ ifeq ($(CONFIG_LOGITECH_FF),y) hid-objs += hid-lgff.o endif +ifeq ($(CONFIG_THRUSTMASTER_FF),y) + hid-objs += hid-tmff.o +endif ifeq ($(CONFIG_HID_FF),y) hid-objs += hid-ff.o endif diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c --- a/drivers/usb/input/aiptek.c Fri Feb 14 00:27:29 2003 +++ b/drivers/usb/input/aiptek.c Fri Feb 14 00:27:29 2003 @@ -155,6 +155,8 @@ dbg("received unknown report #%d", data[0]); } + input_regs(dev, regs); + proximity = data[5] & 0x01; input_report_key(dev, BTN_TOOL_PEN, proximity); @@ -222,13 +224,18 @@ usb_unlink_urb(aiptek->irq); } -/* - * FIXME, either remove this call, or talk the maintainer into - * adding usb_set_report back into the core. - */ -#if 0 +#define USB_REQ_SET_REPORT 0x09 +static int +usb_set_report(struct usb_device *dev, struct usb_host_interface *inter, unsigned char type, + unsigned char id, void *buf, int size) +{ + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (type << 8) + id, inter->desc.bInterfaceNumber, buf, size, HZ); +} + static void -aiptek_command(struct usb_device *dev, unsigned int ifnum, +aiptek_command(struct usb_device *dev, struct usb_host_interface *inter, unsigned char command, unsigned char data) { __u8 buf[3]; @@ -237,17 +244,17 @@ buf[1] = command; buf[2] = data; - if (usb_set_report(dev, ifnum, 3, 2, buf, 3) != 3) { + if (usb_set_report(dev, inter, 3, 2, buf, 3) != 3) { dbg("aiptek_command: 0x%x 0x%x\n", command, data); } } -#endif static int aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev (intf); + struct usb_host_interface *interface = intf->altsetting + 0; struct usb_endpoint_descriptor *endpoint; struct aiptek *aiptek; @@ -269,11 +276,11 @@ return -ENOMEM; } - // Resolution500LPI -// aiptek_command(dev, ifnum, 0x18, 0x04); + /* Resolution500LPI */ + aiptek_command(dev, interface, 0x18, 0x04); - // SwitchToTablet -// aiptek_command(dev, ifnum, 0x10, 0x01); + /* SwitchToTablet */ + aiptek_command(dev, interface, 0x10, 0x01); aiptek->features = aiptek_features + id->driver_info; diff -Nru a/drivers/usb/input/fixp-arith.h b/drivers/usb/input/fixp-arith.h --- a/drivers/usb/input/fixp-arith.h Fri Feb 14 00:27:29 2003 +++ b/drivers/usb/input/fixp-arith.h Fri Feb 14 00:27:29 2003 @@ -38,7 +38,7 @@ #define FRAC_MASK ((1< 123.0 */ -inline fixp_t fixp_new(s16 a) +static inline fixp_t fixp_new(s16 a) { return a< 1.0 0x0000 -> 0.0 */ -inline fixp_t fixp_new16(s16 a) +static inline fixp_t fixp_new16(s16 a) { return ((s32)a)>>(16-FRAC_N); } -inline fixp_t fixp_cos(unsigned int degrees) +static inline fixp_t fixp_cos(unsigned int degrees) { int quadrant = (degrees / 90) & 3; unsigned int i = degrees % 90; @@ -77,12 +77,12 @@ return (quadrant == 1 || quadrant == 2)? -cos_table[i] : cos_table[i]; } -inline fixp_t fixp_sin(unsigned int degrees) +static inline fixp_t fixp_sin(unsigned int degrees) { return -fixp_cos(degrees + 90); } -inline fixp_t fixp_mult(fixp_t a, fixp_t b) +static inline fixp_t fixp_mult(fixp_t a, fixp_t b) { return ((s32)(a*b))>>FRAC_N; } diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c --- a/drivers/usb/input/hid-core.c Fri Feb 14 00:27:28 2003 +++ b/drivers/usb/input/hid-core.c Fri Feb 14 00:27:28 2003 @@ -773,13 +773,13 @@ return -1; } -static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) +static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) { hid_dump_input(usage, value); if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_hid_event(hid, field, usage, value); + hidinput_hid_event(hid, field, usage, value, regs); if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_hid_event(hid, field, usage, value); + hiddev_hid_event(hid, field, usage, value, regs); } /* @@ -788,7 +788,7 @@ * reporting to the layer). */ -static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data) +static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs) { unsigned n; unsigned count = field->report_count; @@ -818,25 +818,25 @@ } else { if (value[n] == field->value[n]) continue; } - hid_process_event(hid, field, &field->usage[n], value[n]); + hid_process_event(hid, field, &field->usage[n], value[n], regs); continue; } if (field->value[n] >= min && field->value[n] <= max && field->usage[field->value[n] - min].hid && search(value, field->value[n], count)) - hid_process_event(hid, field, &field->usage[field->value[n] - min], 0); + hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, regs); if (value[n] >= min && value[n] <= max && field->usage[value[n] - min].hid && search(field->value, value[n], count)) - hid_process_event(hid, field, &field->usage[value[n] - min], 1); + hid_process_event(hid, field, &field->usage[value[n] - min], 1, regs); } memcpy(field->value, value, count * sizeof(__s32)); } -static int hid_input_report(int type, struct urb *urb) +static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs) { struct hid_device *hid = urb->context; struct hid_report_enum *report_enum = hid->report_enum + type; @@ -886,7 +886,7 @@ hiddev_report_event(hid, report); for (n = 0; n < report->maxfield; n++) - hid_input_field(hid, report->field[n], data); + hid_input_field(hid, report->field[n], data, regs); if (hid->claimed & HID_CLAIMED_INPUT) hidinput_report_event(hid, report); @@ -905,7 +905,7 @@ switch (urb->status) { case 0: /* success */ - hid_input_report(HID_INPUT_REPORT, urb); + hid_input_report(HID_INPUT_REPORT, urb, regs); break; case -ECONNRESET: /* unlink */ case -ENOENT: @@ -1130,7 +1130,7 @@ spin_lock_irqsave(&hid->ctrllock, flags); if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) - hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb); + hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs); hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); @@ -1327,6 +1327,9 @@ #define USB_VENDOR_ID_ONTRAK 0x0a07 #define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 +#define USB_VENDOR_ID_TANGTOP 0x0d3d +#define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001 + struct hid_blacklist { __u16 idVendor; __u16 idProduct; @@ -1368,6 +1371,7 @@ { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, { 0, 0 } }; @@ -1533,6 +1537,8 @@ kfree(buf); hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); + if (!hid->urbctrl) + goto fail; usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr, hid->ctrlbuf, 1, hid_ctrl, hid); hid->urbctrl->setup_dma = hid->cr_dma; diff -Nru a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c --- a/drivers/usb/input/hid-ff.c Fri Feb 14 00:27:28 2003 +++ b/drivers/usb/input/hid-ff.c Fri Feb 14 00:27:28 2003 @@ -38,6 +38,7 @@ extern int hid_lgff_init(struct hid_device* hid); extern int hid_lg3d_init(struct hid_device* hid); extern int hid_pid_init(struct hid_device* hid); +extern int hid_tmff_init(struct hid_device* hid); /* * This table contains pointers to initializers. To add support for new @@ -56,6 +57,9 @@ #endif #ifdef CONFIG_HID_PID {0x45e, 0x001b, hid_pid_init}, +#endif +#ifdef CONFIG_THRUSTMASTER_FF + {0x44f, 0xb304, hid_tmff_init}, #endif {0, 0, NULL} /* Terminating entry */ }; diff -Nru a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c --- a/drivers/usb/input/hid-input.c Fri Feb 14 00:27:28 2003 +++ b/drivers/usb/input/hid-input.c Fri Feb 14 00:27:28 2003 @@ -364,8 +364,13 @@ input->absmin[usage->code] = a; input->absmax[usage->code] = b; - input->absfuzz[usage->code] = (b - a) >> 8; - input->absflat[usage->code] = (b - a) >> 4; + input->absfuzz[usage->code] = 0; + input->absflat[usage->code] = 0; + + if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK) { + input->absfuzz[usage->code] = (b - a) >> 8; + input->absflat[usage->code] = (b - a) >> 4; + } } if (usage->hat_min != usage->hat_max) { @@ -380,10 +385,12 @@ } } -void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) +void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) { struct input_dev *input = &hid->input; int *quirks = &hid->quirks; + + input_regs(input, regs); if (usage->hat_min != usage->hat_max) { value = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1; diff -Nru a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/usb/input/hid-tmff.c Fri Feb 14 00:27:30 2003 @@ -0,0 +1,461 @@ +/* + * Force feedback support for various HID compliant devices by ThrustMaster: + * ThrustMaster FireStorm Dual Power 2 + * and possibly others whose device ids haven't been added. + * + * Modified to support ThrustMaster devices by Zinx Verituse + * on 2003-01-25 from the Logitech force feedback driver, + * which is by Johann Deneux. + * + * Copyright (c) 2003 Zinx Verituse + * Copyright (c) 2002 Johann Deneux + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#undef DEBUG +#include + +#include + +#include "hid.h" +#include "fixp-arith.h" + +/* Usages for thrustmaster devices I know about */ +#define THRUSTMASTER_USAGE_RUMBLE_LR (HID_UP_GENDESK | 0xbb) +#define DELAY_CALC(t,delay) ((t) + (delay)*HZ/1000) + +/* Effect status */ +#define EFFECT_STARTED 0 /* Effect is going to play after some time */ +#define EFFECT_PLAYING 1 /* Effect is playing */ +#define EFFECT_USED 2 + +/* For tmff_device::flags */ +#define DEVICE_CLOSING 0 /* The driver is being unitialised */ + +/* Check that the current process can access an effect */ +#define CHECK_OWNERSHIP(effect) (current->pid == 0 \ + || effect.owner == current->pid) + +#define TMFF_CHECK_ID(id) ((id) >= 0 && (id) < TMFF_EFFECTS) + +#define TMFF_CHECK_OWNERSHIP(i, l) \ + (test_bit(EFFECT_USED, l->effects[i].flags) \ + && CHECK_OWNERSHIP(l->effects[i])) + +#define TMFF_EFFECTS 8 + +struct tmff_effect { + pid_t owner; + + struct ff_effect effect; + + unsigned long flags[1]; + unsigned int count; /* Number of times left to play */ + + unsigned long play_at; /* When the effect starts to play */ + unsigned long stop_at; /* When the effect ends */ +}; + +struct tmff_device { + struct hid_device *hid; + + struct hid_report *report; + + struct hid_field *rumble; + + unsigned int effects_playing; + struct tmff_effect effects[TMFF_EFFECTS]; + spinlock_t lock; /* device-level lock. Having locks on + a per-effect basis could be nice, but + isn't really necessary */ + + unsigned long flags[1]; /* Contains various information about the + state of the driver for this device */ + + struct timer_list timer; +}; + +/* Callbacks */ +static void hid_tmff_exit(struct hid_device *hid); +static int hid_tmff_event(struct hid_device *hid, struct input_dev *input, + unsigned int type, unsigned int code, int value); +static int hid_tmff_flush(struct input_dev *input, struct file *file); +static int hid_tmff_upload_effect(struct input_dev *input, + struct ff_effect *effect); +static int hid_tmff_erase(struct input_dev *input, int id); + +/* Local functions */ +static void hid_tmff_recalculate_timer(struct tmff_device *tmff); +static void hid_tmff_timer(unsigned long timer_data); + +int hid_tmff_init(struct hid_device *hid) +{ + struct tmff_device *private; + struct list_head *pos; + + private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL); + if (!private) return -ENOMEM; + + memset(private, 0, sizeof(struct tmff_device)); + hid->ff_private = private; + + /* Find the report to use */ + __list_for_each(pos, &hid->report_enum[HID_OUTPUT_REPORT].report_list) { + struct hid_report *report = (struct hid_report *)pos; + int fieldnum; + + for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) { + struct hid_field *field = report->field[fieldnum]; + + if (field->maxusage <= 0) + continue; + + switch (field->usage[0].hid) { + case THRUSTMASTER_USAGE_RUMBLE_LR: + if (field->report_count < 2) { + warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR with report_count < 2"); + continue; + } + + if (field->logical_maximum == field->logical_minimum) { + warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR with logical_maximum == logical_minimum"); + continue; + } + + if (private->report && private->report != report) { + warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR in other report"); + continue; + } + + if (private->rumble && private->rumble != field) { + warn("ignoring duplicate THRUSTMASTER_USAGE_RUMBLE_LR"); + continue; + } + + private->report = report; + private->rumble = field; + + set_bit(FF_RUMBLE, hid->input.ffbit); + break; + + default: + warn("ignoring unknown output usage %08x", field->usage[0].hid); + continue; + } + + /* Fallthrough to here only when a valid usage is found */ + hid->input.upload_effect = hid_tmff_upload_effect; + hid->input.flush = hid_tmff_flush; + + set_bit(EV_FF, hid->input.evbit); + hid->input.ff_effects_max = TMFF_EFFECTS; + } + } + + private->hid = hid; + + spin_lock_init(&private->lock); + init_timer(&private->timer); + private->timer.data = (unsigned long)private; + private->timer.function = hid_tmff_timer; + + /* Event and exit callbacks */ + hid->ff_exit = hid_tmff_exit; + hid->ff_event = hid_tmff_event; + + info("Force feedback for ThrustMaster rumble pad devices by Zinx Verituse "); + + return 0; +} + +static void hid_tmff_exit(struct hid_device *hid) +{ + struct tmff_device *tmff = hid->ff_private; + unsigned long flags; + + spin_lock_irqsave(&tmff->lock, flags); + + set_bit(DEVICE_CLOSING, tmff->flags); + del_timer_sync(&tmff->timer); + + spin_unlock_irqrestore(&tmff->lock, flags); + + kfree(tmff); +} + +static int hid_tmff_event(struct hid_device *hid, struct input_dev *input, + unsigned int type, unsigned int code, int value) +{ + struct tmff_device *tmff = hid->ff_private; + struct tmff_effect *effect = &tmff->effects[code]; + unsigned long flags; + + if (type != EV_FF) + return -EINVAL; + if (!TMFF_CHECK_ID(code)) + return -EINVAL; + if (!TMFF_CHECK_OWNERSHIP(code, tmff)) + return -EACCES; + if (value < 0) + return -EINVAL; + + spin_lock_irqsave(&tmff->lock, flags); + + if (value > 0) { + set_bit(EFFECT_STARTED, effect->flags); + clear_bit(EFFECT_PLAYING, effect->flags); + effect->count = value; + effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay); + } else { + clear_bit(EFFECT_STARTED, effect->flags); + clear_bit(EFFECT_PLAYING, effect->flags); + } + + hid_tmff_recalculate_timer(tmff); + + spin_unlock_irqrestore(&tmff->lock, flags); + + return 0; + +} + +/* Erase all effects this process owns */ + +static int hid_tmff_flush(struct input_dev *dev, struct file *file) +{ + struct hid_device *hid = dev->private; + struct tmff_device *tmff = hid->ff_private; + int i; + + for (i=0; iff_effects_max; ++i) + + /* NOTE: no need to lock here. The only times EFFECT_USED is + modified is when effects are uploaded or when an effect is + erased. But a process cannot close its dev/input/eventX fd + and perform ioctls on the same fd all at the same time */ + + if (current->pid == tmff->effects[i].owner + && test_bit(EFFECT_USED, tmff->effects[i].flags)) + if (hid_tmff_erase(dev, i)) + warn("erase effect %d failed", i); + + + return 0; +} + +static int hid_tmff_erase(struct input_dev *dev, int id) +{ + struct hid_device *hid = dev->private; + struct tmff_device *tmff = hid->ff_private; + unsigned long flags; + + if (!TMFF_CHECK_ID(id)) + return -EINVAL; + if (!TMFF_CHECK_OWNERSHIP(id, tmff)) + return -EACCES; + + spin_lock_irqsave(&tmff->lock, flags); + + tmff->effects[id].flags[0] = 0; + hid_tmff_recalculate_timer(tmff); + + spin_unlock_irqrestore(&tmff->lock, flags); + + return 0; +} + +static int hid_tmff_upload_effect(struct input_dev *input, + struct ff_effect *effect) +{ + struct hid_device *hid = input->private; + struct tmff_device *tmff = hid->ff_private; + int id; + unsigned long flags; + + if (!test_bit(effect->type, input->ffbit)) + return -EINVAL; + if (effect->id != -1 && !TMFF_CHECK_ID(effect->id)) + return -EINVAL; + + spin_lock_irqsave(&tmff->lock, flags); + + if (effect->id == -1) { + /* Find a free effect */ + for (id = 0; id < TMFF_EFFECTS && test_bit(EFFECT_USED, tmff->effects[id].flags); ++id); + + if (id >= TMFF_EFFECTS) { + spin_unlock_irqrestore(&tmff->lock, flags); + return -ENOSPC; + } + + effect->id = id; + tmff->effects[id].owner = current->pid; + tmff->effects[id].flags[0] = 0; + set_bit(EFFECT_USED, tmff->effects[id].flags); + + } else { + /* Re-uploading an owned effect, to change parameters */ + id = effect->id; + clear_bit(EFFECT_PLAYING, tmff->effects[id].flags); + } + + tmff->effects[id].effect = *effect; + + hid_tmff_recalculate_timer(tmff); + + spin_unlock_irqrestore(&tmff->lock, flags); + return 0; +} + +/* Start the timer for the next start/stop/delay */ +/* Always call this while tmff->lock is locked */ + +static void hid_tmff_recalculate_timer(struct tmff_device *tmff) +{ + int i; + int events = 0; + unsigned long next_time; + + next_time = 0; /* Shut up compiler's incorrect warning */ + + /* Find the next change in an effect's status */ + for (i = 0; i < TMFF_EFFECTS; ++i) { + struct tmff_effect *effect = &tmff->effects[i]; + unsigned long play_time; + + if (!test_bit(EFFECT_STARTED, effect->flags)) + continue; + + effect->stop_at = DELAY_CALC(effect->play_at, effect->effect.replay.length); + + if (!test_bit(EFFECT_PLAYING, effect->flags)) + play_time = effect->play_at; + else + play_time = effect->stop_at; + + events++; + + if (time_after(jiffies, play_time)) + play_time = jiffies; + + if (events == 1) + next_time = play_time; + else { + if (time_after(next_time, play_time)) + next_time = play_time; + } + } + + if (!events && tmff->effects_playing) { + /* Treat all effects turning off as an event */ + events = 1; + next_time = jiffies; + } + + if (!events) { + /* No events, no time, no need for a timer. */ + del_timer_sync(&tmff->timer); + return; + } + + mod_timer(&tmff->timer, next_time); +} + +/* Changes values from 0 to 0xffff into values from minimum to maximum */ +static inline int hid_tmff_scale(unsigned int in, int minimum, int maximum) +{ + int ret; + + ret = (in * (maximum - minimum) / 0xffff) + minimum; + if (ret < minimum) + return minimum; + if (ret > maximum) + return maximum; + return ret; +} + +static void hid_tmff_timer(unsigned long timer_data) +{ + struct tmff_device *tmff = (struct tmff_device *) timer_data; + struct hid_device *hid = tmff->hid; + unsigned long flags; + int left = 0, right = 0; /* Rumbling */ + int i; + + spin_lock_irqsave(&tmff->lock, flags); + + tmff->effects_playing = 0; + + for (i = 0; i < TMFF_EFFECTS; ++i) { + struct tmff_effect *effect = &tmff->effects[i]; + + if (!test_bit(EFFECT_STARTED, effect->flags)) + continue; + + if (!time_after(jiffies, effect->play_at)) + continue; + + if (time_after(jiffies, effect->stop_at)) { + + dbg("Finished playing once %d", i); + clear_bit(EFFECT_PLAYING, effect->flags); + + if (--effect->count <= 0) { + dbg("Stopped %d", i); + clear_bit(EFFECT_STARTED, effect->flags); + continue; + } else { + dbg("Start again %d", i); + effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay); + continue; + } + } + + ++tmff->effects_playing; + + set_bit(EFFECT_PLAYING, effect->flags); + + switch (effect->effect.type) { + case FF_RUMBLE: + right += effect->effect.u.rumble.strong_magnitude; + left += effect->effect.u.rumble.weak_magnitude; + break; + default: + BUG(); + break; + } + } + + left = hid_tmff_scale(left, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum); + right = hid_tmff_scale(right, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum); + + if (left != tmff->rumble->value[0] || right != tmff->rumble->value[1]) { + tmff->rumble->value[0] = left; + tmff->rumble->value[1] = right; + dbg("(left,right)=(%08x, %08x)", left, right); + hid_submit_report(hid, tmff->report, USB_DIR_OUT); + } + + if (!test_bit(DEVICE_CLOSING, tmff->flags)) + hid_tmff_recalculate_timer(tmff); + + spin_unlock_irqrestore(&tmff->lock, flags); +} diff -Nru a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h --- a/drivers/usb/input/hid.h Fri Feb 14 00:27:26 2003 +++ b/drivers/usb/input/hid.h Fri Feb 14 00:27:26 2003 @@ -206,7 +206,7 @@ #define HID_QUIRK_IGNORE 0x04 #define HID_QUIRK_NOGET 0x08 #define HID_QUIRK_HIDDEV 0x10 -#define HID_QUIRK_BADPAD 0x12 +#define HID_QUIRK_BADPAD 0x20 /* * This is the global enviroment of the parser. This information is @@ -420,13 +420,13 @@ /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ /* We ignore a few input applications that are not widely used */ #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || ( a == 0x00010080) || ( a == 0x000c0001)) -extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); +extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32, struct pt_regs *regs); extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); extern int hidinput_connect(struct hid_device *); extern void hidinput_disconnect(struct hid_device *); #else #define IS_INPUT_APPLICATION(a) (0) -static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { } +static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) { } static inline void hidinput_report_event(struct hid_device *hid, struct hid_report *report) { } static inline int hidinput_connect(struct hid_device *hid) { return -ENODEV; } static inline void hidinput_disconnect(struct hid_device *hid) { } diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c --- a/drivers/usb/input/hiddev.c Fri Feb 14 00:27:28 2003 +++ b/drivers/usb/input/hiddev.c Fri Feb 14 00:27:28 2003 @@ -180,7 +180,7 @@ * the interrupt pipe */ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) + struct hid_usage *usage, __s32 value, struct pt_regs *regs) { unsigned type = field->report_type; struct hiddev_usage_ref uref; diff -Nru a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c --- a/drivers/usb/input/powermate.c Fri Feb 14 00:27:28 2003 +++ b/drivers/usb/input/powermate.c Fri Feb 14 00:27:28 2003 @@ -1,9 +1,9 @@ /* * A driver for the Griffin Technology, Inc. "PowerMate" USB controller dial. * - * v1.0, (c)2002 William R Sowerbutts + * v1.1, (c)2002 William R Sowerbutts * - * This device is a stainless steel knob which connects over USB. It can measure + * This device is a anodised aluminium knob which connects over USB. It can measure * clockwise and anticlockwise rotation. The dial also acts as a pushbutton with * a spring for automatic release. The base contains a pair of LEDs which illuminate * the translucent base. It rotates without limit and reports its relative rotation @@ -15,13 +15,17 @@ * speeds of up to 7 clicks either clockwise or anticlockwise between pollings from * the host. If it counts more than 7 clicks before it is polled, it will wrap back * to zero and start counting again. This was at quite high speed, however, almost - * certainly faster than the human hand could turn it. + * certainly faster than the human hand could turn it. Griffin say that it loses a + * pulse or two on a direction change; the granularity is so fine that I never + * noticed this in practice. * * The device's microcontroller can be programmed to set the LED to either a constant * intensity, or to a rhythmic pulsing. Several patterns and speeds are available. * * Griffin were very happy to provide documentation and free hardware for development. * + * Some userspace tools are available on the web: http://sowerbutts.com/powermate/ + * */ #include @@ -96,6 +100,7 @@ } /* handle updates to device state */ + input_regs(&pm->input, regs); input_report_key(&pm->input, BTN_0, pm->data[0] & 0x01); input_report_rel(&pm->input, REL_DIAL, pm->data[1]); input_sync(&pm->input); @@ -115,11 +120,7 @@ if (pm->config->status == -EINPROGRESS) return; /* an update is already in progress; it'll issue this update when it completes */ - if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS){ - pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS ); - pm->configcr->wIndex = cpu_to_le16( pm->static_brightness ); - pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS; - }else if (pm->requires_update & UPDATE_PULSE_ASLEEP){ + if (pm->requires_update & UPDATE_PULSE_ASLEEP){ pm->configcr->wValue = cpu_to_le16( SET_PULSE_ASLEEP ); pm->configcr->wIndex = cpu_to_le16( pm->pulse_asleep ? 1 : 0 ); pm->requires_update &= ~UPDATE_PULSE_ASLEEP; @@ -159,6 +160,10 @@ pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE ); pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op ); pm->requires_update &= ~UPDATE_PULSE_MODE; + }else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS){ + pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS ); + pm->configcr->wIndex = cpu_to_le16( pm->static_brightness ); + pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS; }else{ printk(KERN_ERR "powermate: unknown update required"); pm->requires_update = 0; /* fudge the bug */ @@ -219,11 +224,11 @@ } if (pulse_asleep != pm->pulse_asleep){ pm->pulse_asleep = pulse_asleep; - pm->requires_update |= UPDATE_PULSE_ASLEEP; + pm->requires_update |= (UPDATE_PULSE_ASLEEP | UPDATE_STATIC_BRIGHTNESS); } if (pulse_awake != pm->pulse_awake){ pm->pulse_awake = pulse_awake; - pm->requires_update |= UPDATE_PULSE_AWAKE; + pm->requires_update |= (UPDATE_PULSE_AWAKE | UPDATE_STATIC_BRIGHTNESS); } if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table){ pm->pulse_speed = pulse_speed; diff -Nru a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c --- a/drivers/usb/input/usbkbd.c Fri Feb 14 00:27:30 2003 +++ b/drivers/usb/input/usbkbd.c Fri Feb 14 00:27:30 2003 @@ -99,6 +99,8 @@ goto resubmit; } + input_regs(&kbd->dev, regs); + for (i = 0; i < 8; i++) input_report_key(&kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1); diff -Nru a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c --- a/drivers/usb/input/usbmouse.c Fri Feb 14 00:27:30 2003 +++ b/drivers/usb/input/usbmouse.c Fri Feb 14 00:27:30 2003 @@ -76,6 +76,7 @@ goto resubmit; } + input_regs(dev, regs); input_report_key(dev, BTN_LEFT, data[0] & 0x01); input_report_key(dev, BTN_RIGHT, data[0] & 0x02); diff -Nru a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c --- a/drivers/usb/input/wacom.c Fri Feb 14 00:27:26 2003 +++ b/drivers/usb/input/wacom.c Fri Feb 14 00:27:26 2003 @@ -102,6 +102,17 @@ char phys[32]; }; +#define USB_REQ_SET_REPORT 0x09 +static int usb_set_report(struct usb_interface *intf, unsigned char type, + unsigned char id, void *buf, int size) +{ + return usb_control_msg(interface_to_usbdev(intf), + usb_sndctrlpipe(interface_to_usbdev(intf), 0), + USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, + buf, size, HZ); +} + static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) { struct wacom *wacom = urb->context; @@ -129,6 +140,8 @@ dbg("received unknown report #%d", data[0]); prox = data[1] & 0x40; + + input_regs(dev, regs); input_report_key(dev, BTN_TOOL_PEN, prox); @@ -179,6 +192,7 @@ goto exit; } + input_regs(dev, regs); input_report_key(dev, BTN_TOOL_PEN, 1); input_report_abs(dev, ABS_X, data[2] << 8 | data[1]); input_report_abs(dev, ABS_Y, data[4] << 8 | data[3]); @@ -223,6 +237,8 @@ x = data[2] | ((__u32)data[3] << 8); y = data[4] | ((__u32)data[5] << 8); + input_regs(dev, regs); + switch ((data[1] >> 5) & 3) { case 0: /* Pen */ @@ -294,6 +310,8 @@ if (data[0] != 2) dbg("received unknown report #%d", data[0]); + input_regs(dev, regs); + /* tool number */ idx = data[1] & 0x01; @@ -481,6 +499,7 @@ { struct usb_device *dev = interface_to_usbdev(intf); struct usb_endpoint_descriptor *endpoint; + char rep_data[2] = {0x02, 0x02}; struct wacom *wacom; char path[64]; @@ -575,11 +594,9 @@ input_register_device(&wacom->dev); -#if 0 /* Missing usb_set_report() */ usb_set_report(intf, 3, 2, rep_data, 2); usb_set_report(intf, 3, 5, rep_data, 0); usb_set_report(intf, 3, 6, rep_data, 0); -#endif printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path); diff -Nru a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c --- a/drivers/usb/input/xpad.c Fri Feb 14 00:27:28 2003 +++ b/drivers/usb/input/xpad.c Fri Feb 14 00:27:28 2003 @@ -124,9 +124,11 @@ * http://euc.jp/periphs/xbox-controller.ja.html */ -static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) +static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs) { struct input_dev *dev = &xpad->dev; + + input_regs(dev, regs); /* left stick */ input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12])); @@ -183,7 +185,7 @@ goto exit; } - xpad_process_packet(xpad, 0, xpad->idata); + xpad_process_packet(xpad, 0, xpad->idata, regs); exit: retval = usb_submit_urb (urb, GFP_ATOMIC); diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c --- a/drivers/usb/storage/usb.c Fri Feb 14 00:27:27 2003 +++ b/drivers/usb/storage/usb.c Fri Feb 14 00:27:27 2003 @@ -298,18 +298,9 @@ * This thread doesn't need any user-level access, * so get rid of all our resources.. */ - daemonize(); + daemonize("usb-storage"); - /* avoid getting signals */ - spin_lock_irq(¤t->sighand->siglock); - flush_signals(current); current->flags |= PF_IOTHREAD; - sigfillset(¤t->blocked); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - /* set our name for identification purposes */ - sprintf(current->comm, "usb-storage"); unlock_kernel(); diff -Nru a/fs/afs/cmservice.c b/fs/afs/cmservice.c --- a/fs/afs/cmservice.c Fri Feb 14 00:27:28 2003 +++ b/fs/afs/cmservice.c Fri Feb 14 00:27:28 2003 @@ -120,17 +120,9 @@ int die; printk("kAFS: Started kafscmd %d\n",current->pid); - strcpy(current->comm,"kafscmd"); - - daemonize(); + daemonize("kafscmd"); complete(&kafscmd_alive); - - /* only certain signals are of interest */ - spin_lock_irq(¤t->sighand->siglock); - siginitsetinv(¤t->blocked,0); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); /* loop around looking for things to attend to */ do { diff -Nru a/fs/afs/internal.h b/fs/afs/internal.h --- a/fs/afs/internal.h Fri Feb 14 00:27:28 2003 +++ b/fs/afs/internal.h Fri Feb 14 00:27:28 2003 @@ -47,7 +47,7 @@ siginfo_t sinfo; spin_lock_irq(¤t->sighand->siglock); - dequeue_signal(¤t->blocked,&sinfo); + dequeue_signal(current,¤t->blocked,&sinfo); spin_unlock_irq(¤t->sighand->siglock); } } diff -Nru a/fs/afs/kafsasyncd.c b/fs/afs/kafsasyncd.c --- a/fs/afs/kafsasyncd.c Fri Feb 14 00:27:30 2003 +++ b/fs/afs/kafsasyncd.c Fri Feb 14 00:27:30 2003 @@ -94,17 +94,10 @@ kafsasyncd_task = current; printk("kAFS: Started kafsasyncd %d\n",current->pid); - strcpy(current->comm,"kafsasyncd"); - daemonize(); + daemonize("kafsasyncd"); complete(&kafsasyncd_alive); - - /* only certain signals are of interest */ - spin_lock_irq(¤t->sighand->siglock); - siginitsetinv(¤t->blocked,0); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); /* loop around looking for things to attend to */ do { diff -Nru a/fs/afs/kafstimod.c b/fs/afs/kafstimod.c --- a/fs/afs/kafstimod.c Fri Feb 14 00:27:28 2003 +++ b/fs/afs/kafstimod.c Fri Feb 14 00:27:28 2003 @@ -71,17 +71,10 @@ afs_timer_t *timer; printk("kAFS: Started kafstimod %d\n",current->pid); - strcpy(current->comm,"kafstimod"); - daemonize(); + daemonize("kafstimod"); complete(&kafstimod_alive); - - /* only certain signals are of interest */ - spin_lock_irq(¤t->sighand->siglock); - siginitsetinv(¤t->blocked,0); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); /* loop around looking for things to attend to */ loop: diff -Nru a/fs/buffer.c b/fs/buffer.c --- a/fs/buffer.c Fri Feb 14 00:27:28 2003 +++ b/fs/buffer.c Fri Feb 14 00:27:28 2003 @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -2619,6 +2618,24 @@ } /* + * For a data-integrity writeout, we need to wait upon any in-progress I/O + * and then start new I/O and then wait upon it. + */ +void sync_dirty_buffer(struct buffer_head *bh) +{ + WARN_ON(atomic_read(&bh->b_count) < 1); + lock_buffer(bh); + if (test_clear_buffer_dirty(bh)) { + get_bh(bh); + bh->b_end_io = end_buffer_io_sync; + submit_bh(WRITE, bh); + wait_on_buffer(bh); + } else { + unlock_buffer(bh); + } +} + +/* * Sanity checks for try_to_free_buffers. */ static void check_ttfb_buffer(struct page *page, struct buffer_head *bh) @@ -2773,7 +2790,6 @@ * Buffer-head allocation */ static kmem_cache_t *bh_cachep; -static mempool_t *bh_mempool; /* * Once the number of bh's in the machine exceeds this level, we start @@ -2807,7 +2823,7 @@ struct buffer_head *alloc_buffer_head(void) { - struct buffer_head *ret = mempool_alloc(bh_mempool, GFP_NOFS); + struct buffer_head *ret = kmem_cache_alloc(bh_cachep, GFP_NOFS); if (ret) { preempt_disable(); __get_cpu_var(bh_accounting).nr++; @@ -2821,7 +2837,7 @@ void free_buffer_head(struct buffer_head *bh) { BUG_ON(!list_empty(&bh->b_assoc_buffers)); - mempool_free(bh, bh_mempool); + kmem_cache_free(bh_cachep, bh); preempt_disable(); __get_cpu_var(bh_accounting).nr--; recalc_bh_state(); @@ -2829,7 +2845,8 @@ } EXPORT_SYMBOL(free_buffer_head); -static void init_buffer_head(void *data, kmem_cache_t *cachep, unsigned long flags) +static void +init_buffer_head(void *data, kmem_cache_t *cachep, unsigned long flags) { if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) { @@ -2840,19 +2857,6 @@ } } -static void *bh_mempool_alloc(int gfp_mask, void *pool_data) -{ - return kmem_cache_alloc(bh_cachep, gfp_mask); -} - -static void bh_mempool_free(void *element, void *pool_data) -{ - return kmem_cache_free(bh_cachep, element); -} - -#define NR_RESERVED (10*MAX_BUF_PER_PAGE) -#define MAX_UNUSED_BUFFERS NR_RESERVED+20 - static void buffer_init_cpu(int cpu) { struct bh_accounting *bha = &per_cpu(bh_accounting, cpu); @@ -2889,8 +2893,6 @@ bh_cachep = kmem_cache_create("buffer_head", sizeof(struct buffer_head), 0, 0, init_buffer_head, NULL); - bh_mempool = mempool_create(MAX_UNUSED_BUFFERS, bh_mempool_alloc, - bh_mempool_free, NULL); for (i = 0; i < ARRAY_SIZE(bh_wait_queue_heads); i++) init_waitqueue_head(&bh_wait_queue_heads[i].wqh); diff -Nru a/fs/cifs/connect.c b/fs/cifs/connect.c --- a/fs/cifs/connect.c Fri Feb 14 00:27:30 2003 +++ b/fs/cifs/connect.c Fri Feb 14 00:27:30 2003 @@ -95,7 +95,8 @@ struct mid_q_entry *mid_entry; char *temp; - daemonize(); + daemonize("cifsd"); + allow_signal(SIGKILL); server->tsk = current; /* save process info to wake at shutdown */ cFYI(1, ("\nDemultiplex PID: %d", current->pid)); diff -Nru a/fs/devfs/base.c b/fs/devfs/base.c --- a/fs/devfs/base.c Fri Feb 14 00:27:27 2003 +++ b/fs/devfs/base.c Fri Feb 14 00:27:27 2003 @@ -1169,7 +1169,7 @@ *leaf_pos = (name[namelen] == '/') ? (namelen + 1) : 0; for (; namelen > 0; name += next_pos, namelen -= next_pos) { - struct devfs_entry *de, *old; + struct devfs_entry *de, *old = NULL; if ( ( de = _devfs_descend (dir, name, namelen, &next_pos) ) == NULL ) { diff -Nru a/fs/eventpoll.c b/fs/eventpoll.c --- a/fs/eventpoll.c Fri Feb 14 00:27:28 2003 +++ b/fs/eventpoll.c Fri Feb 14 00:27:28 2003 @@ -261,7 +261,7 @@ struct epoll_event *events); static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, int maxevents); static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents, - int timeout); + long timeout); static int eventpollfs_delete_dentry(struct dentry *dentry); static struct inode *ep_eventpoll_inode(void); static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type, @@ -446,7 +446,7 @@ * file descriptors inside the epoll interface. It is the kernel part of * the userspace epoll_create(2). */ -asmlinkage int sys_epoll_create(int size) +asmlinkage long sys_epoll_create(int size) { int error, fd; unsigned int hashbits; @@ -492,7 +492,7 @@ * file that enable the insertion/removal/change of file descriptors inside * the interest set. It rapresents the kernel part of the user spcae epoll_ctl(2). */ -asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) +asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) { int error; struct file *file, *tfile; @@ -596,8 +596,8 @@ * Implement the event wait interface for the eventpoll file. It is the kernel * part of the user space epoll_wait(2). */ -asmlinkage int sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents, - int timeout) +asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents, + int timeout) { int error; struct file *file; @@ -1420,7 +1420,7 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents, - int timeout) + long timeout) { int res, eavail; unsigned long flags; @@ -1428,10 +1428,12 @@ wait_queue_t wait; /* - * Calculate the timeout by checking for the "infinite" value ( -1 ). - * The passed timeout is in milliseconds, that why (t * HZ) / 1000. + * Calculate the timeout by checking for the "infinite" value ( -1 ) + * and the overflow condition. The passed timeout is in milliseconds, + * that why (t * HZ) / 1000. */ - jtimeout = timeout == -1 ? MAX_SCHEDULE_TIMEOUT: (timeout * HZ) / 1000; + jtimeout = timeout == -1 || timeout > (MAX_SCHEDULE_TIMEOUT - 1000) / HZ ? + MAX_SCHEDULE_TIMEOUT: (timeout * HZ + 999) / 1000; retry: write_lock_irqsave(&ep->lock, flags); diff -Nru a/fs/exec.c b/fs/exec.c --- a/fs/exec.c Fri Feb 14 00:27:27 2003 +++ b/fs/exec.c Fri Feb 14 00:27:27 2003 @@ -596,6 +596,7 @@ newsig->group_exit_code = 0; newsig->group_exit_task = NULL; newsig->group_stop_count = 0; + newsig->curr_target = NULL; init_sigpending(&newsig->shared_pending); } diff -Nru a/fs/ext2/balloc.c b/fs/ext2/balloc.c --- a/fs/ext2/balloc.c Fri Feb 14 00:27:28 2003 +++ b/fs/ext2/balloc.c Fri Feb 14 00:27:28 2003 @@ -233,10 +233,8 @@ } mark_buffer_dirty(bitmap_bh); - if (sb->s_flags & MS_SYNCHRONOUS) { - ll_rw_block(WRITE, 1, &bitmap_bh); - wait_on_buffer(bitmap_bh); - } + if (sb->s_flags & MS_SYNCHRONOUS) + sync_dirty_buffer(bitmap_bh); group_release_blocks(desc, bh2, group_freed); freed += group_freed; @@ -466,10 +464,8 @@ write_unlock(&EXT2_I(inode)->i_meta_lock); mark_buffer_dirty(bitmap_bh); - if (sb->s_flags & MS_SYNCHRONOUS) { - ll_rw_block(WRITE, 1, &bitmap_bh); - wait_on_buffer(bitmap_bh); - } + if (sb->s_flags & MS_SYNCHRONOUS) + sync_dirty_buffer(bitmap_bh); ext2_debug ("allocating block %d. ", block); diff -Nru a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c --- a/fs/ext2/ialloc.c Fri Feb 14 00:27:28 2003 +++ b/fs/ext2/ialloc.c Fri Feb 14 00:27:28 2003 @@ -146,10 +146,8 @@ mark_buffer_dirty(EXT2_SB(sb)->s_sbh); } mark_buffer_dirty(bitmap_bh); - if (sb->s_flags & MS_SYNCHRONOUS) { - ll_rw_block(WRITE, 1, &bitmap_bh); - wait_on_buffer(bitmap_bh); - } + if (sb->s_flags & MS_SYNCHRONOUS) + sync_dirty_buffer(bitmap_bh); sb->s_dirt = 1; error_return: brelse(bitmap_bh); @@ -485,10 +483,8 @@ ext2_set_bit(i, bitmap_bh->b_data); mark_buffer_dirty(bitmap_bh); - if (sb->s_flags & MS_SYNCHRONOUS) { - ll_rw_block(WRITE, 1, &bitmap_bh); - wait_on_buffer(bitmap_bh); - } + if (sb->s_flags & MS_SYNCHRONOUS) + sync_dirty_buffer(bitmap_bh); brelse(bitmap_bh); ino = group * EXT2_INODES_PER_GROUP(sb) + i + 1; diff -Nru a/fs/ext2/inode.c b/fs/ext2/inode.c --- a/fs/ext2/inode.c Fri Feb 14 00:27:27 2003 +++ b/fs/ext2/inode.c Fri Feb 14 00:27:27 2003 @@ -443,10 +443,8 @@ * But we now rely upon generic_osync_inode() * and b_inode_buffers. But not for directories. */ - if (S_ISDIR(inode->i_mode) && IS_DIRSYNC(inode)) { - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); - } + if (S_ISDIR(inode->i_mode) && IS_DIRSYNC(inode)) + sync_dirty_buffer(bh); parent = nr; } if (n == num) @@ -1208,8 +1206,7 @@ raw_inode->i_block[n] = ei->i_data[n]; mark_buffer_dirty(bh); if (do_sync) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); + sync_dirty_buffer(bh); if (buffer_req(bh) && !buffer_uptodate(bh)) { printk ("IO error syncing ext2 inode [%s:%08lx]\n", sb->s_id, (unsigned long) ino); diff -Nru a/fs/ext2/super.c b/fs/ext2/super.c --- a/fs/ext2/super.c Fri Feb 14 00:27:29 2003 +++ b/fs/ext2/super.c Fri Feb 14 00:27:29 2003 @@ -842,8 +842,7 @@ { es->s_wtime = cpu_to_le32(get_seconds()); mark_buffer_dirty(EXT2_SB(sb)->s_sbh); - ll_rw_block(WRITE, 1, &EXT2_SB(sb)->s_sbh); - wait_on_buffer(EXT2_SB(sb)->s_sbh); + sync_dirty_buffer(EXT2_SB(sb)->s_sbh); sb->s_dirt = 0; } diff -Nru a/fs/ext2/xattr.c b/fs/ext2/xattr.c --- a/fs/ext2/xattr.c Fri Feb 14 00:27:29 2003 +++ b/fs/ext2/xattr.c Fri Feb 14 00:27:29 2003 @@ -774,8 +774,7 @@ } mark_buffer_dirty(new_bh); if (IS_SYNC(inode)) { - ll_rw_block(WRITE, 1, &new_bh); - wait_on_buffer(new_bh); + sync_dirty_buffer(new_bh); error = -EIO; if (buffer_req(new_bh) && !buffer_uptodate(new_bh)) goto cleanup; @@ -865,10 +864,8 @@ HDR(bh)->h_refcount = cpu_to_le32( le32_to_cpu(HDR(bh)->h_refcount) - 1); mark_buffer_dirty(bh); - if (IS_SYNC(inode)) { - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); - } + if (IS_SYNC(inode)) + sync_dirty_buffer(bh); DQUOT_FREE_BLOCK(inode, 1); } EXT2_I(inode)->i_file_acl = 0; diff -Nru a/fs/ext3/acl.c b/fs/ext3/acl.c --- a/fs/ext3/acl.c Fri Feb 14 00:27:27 2003 +++ b/fs/ext3/acl.c Fri Feb 14 00:27:27 2003 @@ -231,7 +231,7 @@ return (int)PTR_ERR(value); } - error = ext3_xattr_set(handle, inode, name_index, "", value, size, 0); + error = ext3_xattr_set_handle(handle, inode, name_index, "", value, size, 0); if (value) kfree(value); diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c --- a/fs/ext3/inode.c Fri Feb 14 00:27:29 2003 +++ b/fs/ext3/inode.c Fri Feb 14 00:27:29 2003 @@ -1317,10 +1317,7 @@ goto out_fail; needed = ext3_writepage_trans_blocks(inode); - if (wbc->for_reclaim) - handle = ext3_journal_try_start(inode, needed); - else - handle = ext3_journal_start(inode, needed); + handle = ext3_journal_start(inode, needed); if (IS_ERR(handle)) { ret = PTR_ERR(handle); diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c --- a/fs/ext3/super.c Fri Feb 14 00:27:30 2003 +++ b/fs/ext3/super.c Fri Feb 14 00:27:30 2003 @@ -1343,9 +1343,7 @@ * superblock lock. */ EXT3_SB(sb)->s_mount_state |= EXT3_ORPHAN_FS; - unlock_super(sb); /* akpm: sigh */ ext3_orphan_cleanup(sb, es); - lock_super(sb); EXT3_SB(sb)->s_mount_state &= ~EXT3_ORPHAN_FS; if (needs_recovery) printk (KERN_INFO "EXT3-fs: recovery complete.\n"); @@ -1627,10 +1625,8 @@ es->s_wtime = cpu_to_le32(get_seconds()); BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "marking dirty"); mark_buffer_dirty(EXT3_SB(sb)->s_sbh); - if (sync) { - ll_rw_block(WRITE, 1, &EXT3_SB(sb)->s_sbh); - wait_on_buffer(EXT3_SB(sb)->s_sbh); - } + if (sync) + sync_dirty_buffer(EXT3_SB(sb)->s_sbh); } diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c --- a/fs/ext3/xattr.c Fri Feb 14 00:27:28 2003 +++ b/fs/ext3/xattr.c Fri Feb 14 00:27:28 2003 @@ -88,8 +88,9 @@ # define ea_bdebug(f...) #endif -static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *, - struct ext3_xattr_header *); +static int ext3_xattr_set_handle2(handle_t *, struct inode *, + struct buffer_head *, + struct ext3_xattr_header *); static int ext3_xattr_cache_insert(struct buffer_head *); static struct buffer_head *ext3_xattr_cache_find(struct inode *, @@ -459,7 +460,7 @@ } /* - * ext3_xattr_set() + * ext3_xattr_set_handle() * * Create, replace or remove an extended attribute for this inode. Buffer * is NULL to remove an existing extended attribute, and non-NULL to @@ -471,8 +472,9 @@ * Returns 0, or a negative error number on failure. */ int -ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, - const char *name, const void *value, size_t value_len, int flags) +ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, + const char *name, const void *value, size_t value_len, + int flags) { struct super_block *sb = inode->i_sb; struct buffer_head *bh = NULL; @@ -673,7 +675,8 @@ /* Remove this attribute. */ if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) { /* This block is now empty. */ - error = ext3_xattr_set2(handle, inode, bh,NULL); + error = ext3_xattr_set_handle2(handle, inode, + bh, NULL); goto cleanup; } else { /* Remove the old name. */ @@ -701,7 +704,7 @@ } ext3_xattr_rehash(header, here); - error = ext3_xattr_set2(handle, inode, bh, header); + error = ext3_xattr_set_handle2(handle, inode, bh, header); cleanup: brelse(bh); @@ -713,11 +716,12 @@ } /* - * Second half of ext3_xattr_set(): Update the file system. + * Second half of ext3_xattr_set_handle(): Update the file system. */ static int -ext3_xattr_set2(handle_t *handle, struct inode *inode, - struct buffer_head *old_bh, struct ext3_xattr_header *header) +ext3_xattr_set_handle2(handle_t *handle, struct inode *inode, + struct buffer_head *old_bh, + struct ext3_xattr_header *header) { struct super_block *sb = inode->i_sb; struct buffer_head *new_bh = NULL; @@ -827,6 +831,34 @@ cleanup: if (old_bh != new_bh) brelse(new_bh); + + return error; +} + +/* + * ext3_xattr_set() + * + * Like ext3_xattr_set_handle, but start from an inode. This extended + * attribute modification is a filesystem transaction by itself. + * + * Returns 0, or a negative error number on failure. + */ +int +ext3_xattr_set(struct inode *inode, int name_index, const char *name, + const void *value, size_t value_len, int flags) +{ + handle_t *handle; + int error; + + lock_kernel(); + handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS); + if (IS_ERR(handle)) + error = PTR_ERR(handle); + else + error = ext3_xattr_set_handle(handle, inode, name_index, name, + value, value_len, flags); + ext3_journal_stop(handle, inode); + unlock_kernel(); return error; } diff -Nru a/fs/ext3/xattr.h b/fs/ext3/xattr.h --- a/fs/ext3/xattr.h Fri Feb 14 00:27:30 2003 +++ b/fs/ext3/xattr.h Fri Feb 14 00:27:30 2003 @@ -73,7 +73,8 @@ extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t); extern int ext3_xattr_list(struct inode *, char *, size_t); -extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int); +extern int ext3_xattr_set(struct inode *, int, const char *, const void *, size_t, int); +extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int); extern void ext3_xattr_delete_inode(handle_t *, struct inode *); extern void ext3_xattr_put_super(struct super_block *); @@ -101,7 +102,14 @@ } static inline int -ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, +ext3_xattr_set(struct inode *inode, int name_index, const char *name, + const void *value, size_t size, int flags) +{ + return -EOPNOTSUPP; +} + +static inline int +ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, const char *name, const void *value, size_t size, int flags) { return -EOPNOTSUPP; diff -Nru a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c --- a/fs/ext3/xattr_user.c Fri Feb 14 00:27:27 2003 +++ b/fs/ext3/xattr_user.c Fri Feb 14 00:27:27 2003 @@ -61,7 +61,6 @@ ext3_xattr_user_set(struct inode *inode, const char *name, const void *value, size_t size, int flags) { - handle_t *handle; int error; if (strcmp(name, "") == 0) @@ -79,16 +78,9 @@ if (error) return error; - lock_kernel(); - handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS); - if (IS_ERR(handle)) - return PTR_ERR(handle); - error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name, - value, size, flags); - ext3_journal_stop(handle, inode); - unlock_kernel(); + return ext3_xattr_set(inode, EXT3_XATTR_INDEX_USER, name, + value, size, flags); - return error; } struct ext3_xattr_handler ext3_xattr_user_handler = { diff -Nru a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c --- a/fs/hugetlbfs/inode.c Fri Feb 14 00:27:30 2003 +++ b/fs/hugetlbfs/inode.c Fri Feb 14 00:27:30 2003 @@ -45,6 +45,7 @@ { struct inode *inode =file->f_dentry->d_inode; struct address_space *mapping = inode->i_mapping; + loff_t len; int ret; if (!capable(CAP_IPC_LOCK)) @@ -65,6 +66,10 @@ vma->vm_flags |= VM_HUGETLB | VM_RESERVED; vma->vm_ops = &hugetlb_vm_ops; ret = hugetlb_prefault(mapping, vma); + len = (loff_t)(vma->vm_end - vma->vm_start) + + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); + if (ret == 0 && inode->i_size < len) + inode->i_size = len; up(&inode->i_sem); return ret; } @@ -211,7 +216,7 @@ list_add(&inode->i_list, &inode_unused); } inodes_stat.nr_unused++; - if (!super_block | (super_block->s_flags & MS_ACTIVE)) { + if (!super_block || (super_block->s_flags & MS_ACTIVE)) { spin_unlock(&inode_lock); return; } diff -Nru a/fs/jbd/commit.c b/fs/jbd/commit.c --- a/fs/jbd/commit.c Fri Feb 14 00:27:30 2003 +++ b/fs/jbd/commit.c Fri Feb 14 00:27:30 2003 @@ -562,8 +562,7 @@ { struct buffer_head *bh = jh2bh(descriptor); set_buffer_uptodate(bh); - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); + sync_dirty_buffer(bh); __brelse(bh); /* One for getblk() */ journal_unlock_journal_head(descriptor); } diff -Nru a/fs/jbd/journal.c b/fs/jbd/journal.c --- a/fs/jbd/journal.c Fri Feb 14 00:27:27 2003 +++ b/fs/jbd/journal.c Fri Feb 14 00:27:27 2003 @@ -38,7 +38,6 @@ #include EXPORT_SYMBOL(journal_start); -EXPORT_SYMBOL(journal_try_start); EXPORT_SYMBOL(journal_restart); EXPORT_SYMBOL(journal_extend); EXPORT_SYMBOL(journal_stop); @@ -203,14 +202,9 @@ current_journal = journal; - lock_kernel(); - daemonize(); - spin_lock_irq(¤t->sighand->siglock); - sigfillset(¤t->blocked); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + daemonize("kjournald"); - sprintf(current->comm, "kjournald"); + lock_kernel(); /* Set up an interval timer which can be used to trigger a commit wakeup after the commit interval expires */ @@ -960,9 +954,10 @@ BUFFER_TRACE(bh, "marking dirty"); mark_buffer_dirty(bh); - ll_rw_block(WRITE, 1, &bh); if (wait) - wait_on_buffer(bh); + sync_dirty_buffer(bh); + else + ll_rw_block(WRITE, 1, &bh); /* If we have just flushed the log (by marking s_start==0), then * any future commit will have to be careful to update the @@ -1296,8 +1291,7 @@ bh = journal->j_sb_buffer; BUFFER_TRACE(bh, "marking dirty"); mark_buffer_dirty(bh); - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); + sync_dirty_buffer(bh); return 0; } diff -Nru a/fs/jbd/recovery.c b/fs/jbd/recovery.c --- a/fs/jbd/recovery.c Fri Feb 14 00:27:29 2003 +++ b/fs/jbd/recovery.c Fri Feb 14 00:27:29 2003 @@ -212,16 +212,14 @@ * * The primary function for recovering the log contents when mounting a * journaled device. - */ -int journal_recover(journal_t *journal) -{ -/* + * * Recovery is done in three passes. In the first pass, we look for the * end of the log. In the second, we assemble the list of revoke * blocks. In the third and final pass, we replay any un-revoked blocks * in the log. */ - +int journal_recover(journal_t *journal) +{ int err; journal_superblock_t * sb; @@ -273,15 +271,13 @@ * journal structures in memory to ignore it (presumably because the * caller has evidence that it is out of date). * This function does'nt appear to be exorted.. - */ -int journal_skip_recovery(journal_t *journal) -{ -/* + * * We perform one pass over the journal to allow us to tell the user how * much recovery information is being erased, and to let us initialise * the journal transaction sequence numbers to the next unused ID. */ - +int journal_skip_recovery(journal_t *journal) +{ int err; journal_superblock_t * sb; diff -Nru a/fs/jbd/transaction.c b/fs/jbd/transaction.c --- a/fs/jbd/transaction.c Fri Feb 14 00:27:27 2003 +++ b/fs/jbd/transaction.c Fri Feb 14 00:27:27 2003 @@ -266,113 +266,6 @@ return handle; } -/* - * Return zero on success - */ -static int try_start_this_handle(journal_t *journal, handle_t *handle) -{ - transaction_t *transaction; - int needed; - int nblocks = handle->h_buffer_credits; - int ret = 0; - - jbd_debug(3, "New handle %p maybe going live.\n", handle); - - lock_journal(journal); - - if (is_journal_aborted(journal) || - (journal->j_errno != 0 && !(journal->j_flags & JFS_ACK_ERR))) { - ret = -EROFS; - goto fail_unlock; - } - - if (journal->j_barrier_count) - goto fail_unlock; - - if (!journal->j_running_transaction && get_transaction(journal, 1) == 0) - goto fail_unlock; - - transaction = journal->j_running_transaction; - if (transaction->t_state == T_LOCKED) - goto fail_unlock; - - needed = transaction->t_outstanding_credits + nblocks; - /* We could run log_start_commit here */ - if (needed > journal->j_max_transaction_buffers) - goto fail_unlock; - - needed = journal->j_max_transaction_buffers; - if (journal->j_committing_transaction) - needed += journal->j_committing_transaction-> - t_outstanding_credits; - - if (log_space_left(journal) < needed) - goto fail_unlock; - - handle->h_transaction = transaction; - transaction->t_outstanding_credits += nblocks; - transaction->t_updates++; - jbd_debug(4, "Handle %p given %d credits (total %d, free %d)\n", - handle, nblocks, transaction->t_outstanding_credits, - log_space_left(journal)); - unlock_journal(journal); - return 0; - -fail_unlock: - unlock_journal(journal); - if (ret >= 0) - ret = -1; - return ret; -} - -/** - * handle_t *journal_try_start() - Don't block, but try and get a handle - * @journal: Journal to start transaction on. - * @nblocks: number of block buffer we might modify - * - * Try to start a handle, but non-blockingly. If we weren't able - * to, return an ERR_PTR value. - */ -handle_t *journal_try_start(journal_t *journal, int nblocks) -{ - handle_t *handle = journal_current_handle(); - int err; - - if (!journal) - return ERR_PTR(-EROFS); - - if (handle) { - jbd_debug(4, "h_ref %d -> %d\n", - handle->h_ref, - handle->h_ref + 1); - J_ASSERT(handle->h_transaction->t_journal == journal); - if (is_handle_aborted(handle)) - return ERR_PTR(-EIO); - handle->h_ref++; - return handle; - } else { - jbd_debug(4, "no current transaction\n"); - } - - if (is_journal_aborted(journal)) - return ERR_PTR(-EIO); - - handle = new_handle(nblocks); - if (!handle) - return ERR_PTR(-ENOMEM); - - current->journal_info = handle; - - err = try_start_this_handle(journal, handle); - if (err < 0) { - kfree(handle); - current->journal_info = NULL; - return ERR_PTR(err); - } - - return handle; -} - /** * int journal_extend() - extend buffer credits. * @handle: handle to 'extend' @@ -969,22 +862,23 @@ } /** - * int journal_dirty_data() - mark a buffer as containing dirty data which needs to be flushed before we can commit the current transaction. + * int journal_dirty_data() - mark a buffer as containing dirty data which + * needs to be flushed before we can commit the + * current transaction. * @handle: transaction * @bh: bufferhead to mark * * The buffer is placed on the transaction's data list and is marked as * belonging to the transaction. * - * Returns error number or 0 on success. - */ -int journal_dirty_data (handle_t *handle, struct buffer_head *bh) -{ -/* + * Returns error number or 0 on success. + * * journal_dirty_data() can be called via page_launder->ext3_writepage * by kswapd. So it cannot block. Happily, there's nothing here * which needs lock_journal if `async' is set. */ +int journal_dirty_data (handle_t *handle, struct buffer_head *bh) +{ journal_t *journal = handle->h_transaction->t_journal; int need_brelse = 0; struct journal_head *jh; @@ -1079,8 +973,7 @@ atomic_inc(&bh->b_count); spin_unlock(&journal_datalist_lock); need_brelse = 1; - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); + sync_dirty_buffer(bh); spin_lock(&journal_datalist_lock); /* The buffer may become locked again at any time if it is redirtied */ @@ -1130,23 +1023,22 @@ * @handle: transaction to add buffer to. * @bh: buffer to mark * - * mark dirty metadata which needs to be journaled as part of the current transaction. + * mark dirty metadata which needs to be journaled as part of the current + * transaction. * * The buffer is placed on the transaction's metadata list and is marked * as belonging to the transaction. * * Returns error number or 0 on success. - */ -int journal_dirty_metadata (handle_t *handle, struct buffer_head *bh) -{ -/* + * * Special care needs to be taken if the buffer already belongs to the * current committing transaction (in which case we should have frozen * data present for that commit). In that case, we don't relink the * buffer: that only gets done when the old transaction finally * completes its commit. - * */ +int journal_dirty_metadata (handle_t *handle, struct buffer_head *bh) +{ transaction_t *transaction = handle->h_transaction; journal_t *journal = transaction->t_journal; struct journal_head *jh = bh2jh(bh); @@ -1361,8 +1253,7 @@ } atomic_inc(&bh->b_count); spin_unlock(&journal_datalist_lock); - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer(bh); + sync_dirty_buffer(bh); __brelse(bh); goto out; } @@ -1728,13 +1619,6 @@ * to be called. We do this if the page is releasable by try_to_free_buffers(). * We also do it if the page has locked or dirty buffers and the caller wants * us to perform sync or async writeout. - */ -int journal_try_to_free_buffers(journal_t *journal, - struct page *page, int unused_gfp_mask) -{ -/* - * journal_try_to_free_buffers(). Try to remove all this page's buffers - * from the journal. * * This complicates JBD locking somewhat. We aren't protected by the * BKL here. We wish to remove the buffer from its committing or @@ -1754,6 +1638,9 @@ * cannot happen because we never reallocate freed data as metadata * while the data is part of a transaction. Yes? */ +int journal_try_to_free_buffers(journal_t *journal, + struct page *page, int unused_gfp_mask) +{ struct buffer_head *head; struct buffer_head *bh; int ret = 0; diff -Nru a/fs/jffs/intrep.c b/fs/jffs/intrep.c --- a/fs/jffs/intrep.c Fri Feb 14 00:27:28 2003 +++ b/fs/jffs/intrep.c Fri Feb 14 00:27:28 2003 @@ -3378,7 +3378,7 @@ unsigned long signr = 0; spin_lock_irq(¤t->sighand->siglock); - signr = dequeue_signal(¤t->blocked, &info); + signr = dequeue_signal(current, ¤t->blocked, &info); spin_unlock_irq(¤t->sighand->siglock); switch(signr) { diff -Nru a/fs/jffs2/background.c b/fs/jffs2/background.c --- a/fs/jffs2/background.c Fri Feb 14 00:27:26 2003 +++ b/fs/jffs2/background.c Fri Feb 14 00:27:26 2003 @@ -82,13 +82,11 @@ { struct jffs2_sb_info *c = _c; - daemonize(); + daemonize("jffs2_gcd_mtd%d", c->mtd->index); c->gc_task = current; up(&c->gc_thread_start); - sprintf(current->comm, "jffs2_gcd_mtd%d", c->mtd->index); - set_user_nice(current, 10); for (;;) { @@ -116,7 +114,7 @@ unsigned long signr; spin_lock_irq(¤t_sig_lock); - signr = dequeue_signal(¤t->blocked, &info); + signr = dequeue_signal(current, ¤t->blocked, &info); spin_unlock_irq(¤t_sig_lock); switch(signr) { diff -Nru a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c --- a/fs/jfs/jfs_imap.c Fri Feb 14 00:27:27 2003 +++ b/fs/jfs/jfs_imap.c Fri Feb 14 00:27:27 2003 @@ -2980,8 +2980,7 @@ j_sb->s_flag |= JFS_BAD_SAIT; mark_buffer_dirty(bh); - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); + sync_dirty_buffer(bh); brelse(bh); return; } diff -Nru a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c --- a/fs/jfs/jfs_logmgr.c Fri Feb 14 00:27:28 2003 +++ b/fs/jfs/jfs_logmgr.c Fri Feb 14 00:27:28 2003 @@ -2132,17 +2132,7 @@ { struct lbuf *bp; - lock_kernel(); - - daemonize(); - strcpy(current->comm, "jfsIO"); - - unlock_kernel(); - - spin_lock_irq(¤t->sighand->siglock); - sigfillset(¤t->blocked); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + daemonize("jfsIO"); complete(&jfsIOwait); diff -Nru a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c --- a/fs/jfs/jfs_mount.c Fri Feb 14 00:27:27 2003 +++ b/fs/jfs/jfs_mount.c Fri Feb 14 00:27:27 2003 @@ -449,8 +449,7 @@ } mark_buffer_dirty(bh); - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); + sync_dirty_buffer(bh); brelse(bh); return 0; diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c --- a/fs/jfs/jfs_txnmgr.c Fri Feb 14 00:27:28 2003 +++ b/fs/jfs/jfs_txnmgr.c Fri Feb 14 00:27:28 2003 @@ -2771,20 +2771,10 @@ struct tblock *tblk; unsigned long flags; - lock_kernel(); - - daemonize(); - strcpy(current->comm, "jfsCommit"); - - unlock_kernel(); + daemonize("jfsCommit"); jfsCommitTask = current; - spin_lock_irq(¤t->sighand->siglock); - sigfillset(¤t->blocked); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - LAZY_LOCK_INIT(); TxAnchor.unlock_queue = TxAnchor.unlock_tail = 0; @@ -2978,17 +2968,7 @@ int rc; tid_t tid; - lock_kernel(); - - daemonize(); - strcpy(current->comm, "jfsSync"); - - unlock_kernel(); - - spin_lock_irq(¤t->sighand->siglock); - sigfillset(¤t->blocked); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + daemonize("jfsSync"); complete(&jfsIOwait); diff -Nru a/fs/jfs/namei.c b/fs/jfs/namei.c --- a/fs/jfs/namei.c Fri Feb 14 00:27:29 2003 +++ b/fs/jfs/namei.c Fri Feb 14 00:27:29 2003 @@ -972,10 +972,8 @@ #if 0 set_buffer_uptodate(bp); mark_buffer_dirty(bp, 1); - if (IS_SYNC(dip)) { - ll_rw_block(WRITE, 1, &bp); - wait_on_buffer(bp); - } + if (IS_SYNC(dip)) + sync_dirty_buffer(bp); brelse(bp); #endif /* 0 */ ssize -= copy_size; diff -Nru a/fs/jfs/resize.c b/fs/jfs/resize.c --- a/fs/jfs/resize.c Fri Feb 14 00:27:29 2003 +++ b/fs/jfs/resize.c Fri Feb 14 00:27:29 2003 @@ -243,8 +243,7 @@ /* synchronously update superblock */ mark_buffer_dirty(bh); - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); + sync_dirty_buffer(bh); brelse(bh); /* @@ -512,15 +511,13 @@ memcpy(j_sb2, j_sb, sizeof (struct jfs_superblock)); mark_buffer_dirty(bh); - ll_rw_block(WRITE, 1, &bh2); - wait_on_buffer(bh2); + sync_dirty_buffer(bh2); brelse(bh2); } /* write primary superblock */ mark_buffer_dirty(bh); - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); + sync_dirty_buffer(bh); brelse(bh); goto resume; diff -Nru a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c --- a/fs/lockd/clntlock.c Fri Feb 14 00:27:30 2003 +++ b/fs/lockd/clntlock.c Fri Feb 14 00:27:30 2003 @@ -201,10 +201,8 @@ struct file_lock *fl; struct inode *inode; - daemonize(); - snprintf(current->comm, sizeof(current->comm), - "%s-reclaim", - host->h_name); + daemonize("%s-reclaim", host->h_name); + allow_signal(SIGKILL); /* This one ensures that our parent doesn't terminate while the * reclaim is in progress */ diff -Nru a/fs/lockd/svc.c b/fs/lockd/svc.c --- a/fs/lockd/svc.c Fri Feb 14 00:27:29 2003 +++ b/fs/lockd/svc.c Fri Feb 14 00:27:29 2003 @@ -97,14 +97,10 @@ nlmsvc_pid = current->pid; up(&lockd_start); - daemonize(); - sprintf(current->comm, "lockd"); + daemonize("lockd"); - /* Process request with signals blocked. */ - spin_lock_irq(¤t->sighand->siglock); - siginitsetinv(¤t->blocked, sigmask(SIGKILL)); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + /* Process request with signals blocked, but allow SIGKILL. */ + allow_signal(SIGKILL); /* kick rpciod */ rpciod_up(); @@ -126,9 +122,7 @@ { long timeout = MAX_SCHEDULE_TIMEOUT; if (signalled()) { - spin_lock_irq(¤t->sighand->siglock); flush_signals(current); - spin_unlock_irq(¤t->sighand->siglock); if (nlmsvc_ops) { nlmsvc_invalidate_all(); grace_period_expire = set_grace_period(); diff -Nru a/fs/minix/inode.c b/fs/minix/inode.c --- a/fs/minix/inode.c Fri Feb 14 00:27:28 2003 +++ b/fs/minix/inode.c Fri Feb 14 00:27:28 2003 @@ -517,8 +517,7 @@ bh = minix_update_inode(inode); if (bh && buffer_dirty(bh)) { - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); + sync_dirty_buffer(bh); if (buffer_req(bh) && !buffer_uptodate(bh)) { printk ("IO error syncing minix inode [%s:%08lx]\n", diff -Nru a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c --- a/fs/ncpfs/sock.c Fri Feb 14 00:27:27 2003 +++ b/fs/ncpfs/sock.c Fri Feb 14 00:27:27 2003 @@ -757,9 +757,9 @@ What if we've blocked it ourselves? What about alarms? Why, in fact, are we mucking with the sigmask at all? -- r~ */ - if (current->sig->action[SIGINT - 1].sa.sa_handler == SIG_DFL) + if (current->sighand->action[SIGINT - 1].sa.sa_handler == SIG_DFL) mask |= sigmask(SIGINT); - if (current->sig->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL) + if (current->sighand->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL) mask |= sigmask(SIGQUIT); } siginitsetinv(¤t->blocked, mask); diff -Nru a/fs/nfs/inode.c b/fs/nfs/inode.c --- a/fs/nfs/inode.c Fri Feb 14 00:27:29 2003 +++ b/fs/nfs/inode.c Fri Feb 14 00:27:29 2003 @@ -93,6 +93,7 @@ .nrvers = sizeof(nfs_version) / sizeof(nfs_version[0]), .version = nfs_version, .stats = &nfs_rpcstat, + .pipe_dir_name = "/nfs", }; static inline unsigned long diff -Nru a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c --- a/fs/nfs/nfs3proc.c Fri Feb 14 00:27:28 2003 +++ b/fs/nfs/nfs3proc.c Fri Feb 14 00:27:28 2003 @@ -651,7 +651,7 @@ default: return -EINVAL; } - dprintk("NFS call mknod %s %x\n", name->name, rdev); + dprintk("NFS call mknod %s %x\n", name->name, (unsigned)rdev); dir_attr.valid = 0; fattr->valid = 0; status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0); diff -Nru a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c --- a/fs/nfs/nfs3xdr.c Fri Feb 14 00:27:30 2003 +++ b/fs/nfs/nfs3xdr.c Fri Feb 14 00:27:30 2003 @@ -146,7 +146,7 @@ static u32 * xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr) { - unsigned int type; + unsigned int type, major, minor; int fmode; type = ntohl(*p++); @@ -160,9 +160,12 @@ fattr->gid = ntohl(*p++); p = xdr_decode_hyper(p, &fattr->size); p = xdr_decode_hyper(p, &fattr->du.nfs3.used); + /* Turn remote device info into Linux-specific dev_t */ - fattr->rdev = ntohl(*p++) << MINORBITS; - fattr->rdev |= ntohl(*p++) & MINORMASK; + major = ntohl(*p++); + minor = ntohl(*p++); + fattr->rdev = MKDEV(major, minor); + p = xdr_decode_hyper(p, &fattr->fsid_u.nfs3); p = xdr_decode_hyper(p, &fattr->fileid); p = xdr_decode_time3(p, &fattr->atime); @@ -412,8 +415,8 @@ *p++ = htonl(args->type); p = xdr_encode_sattr(p, args->sattr); if (args->type == NF3CHR || args->type == NF3BLK) { - *p++ = htonl(args->rdev >> MINORBITS); - *p++ = htonl(args->rdev & MINORMASK); + *p++ = htonl(MAJOR(args->rdev)); + *p++ = htonl(MINOR(args->rdev)); } req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); diff -Nru a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c --- a/fs/nfs/nfs4xdr.c Fri Feb 14 00:27:30 2003 +++ b/fs/nfs/nfs4xdr.c Fri Feb 14 00:27:30 2003 @@ -1385,13 +1385,14 @@ dprintk("read_attrs: gid=%d\n", (int)nfp->gid); } if (bmval1 & FATTR4_WORD1_RAWDEV) { - READ_BUF(8); - len += 8; - READ32(dummy32); - nfp->rdev = (dummy32 << MINORBITS); - READ32(dummy32); - nfp->rdev |= (dummy32 & MINORMASK); - dprintk("read_attrs: rdev=%d\n", nfp->rdev); + uint32_t major, minor; + + READ_BUF(8); + len += 8; + READ32(major); + READ32(minor); + nfp->rdev = MKDEV(major, minor); + dprintk("read_attrs: rdev=0x%x\n", nfp->rdev); } if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) { READ_BUF(8); diff -Nru a/fs/nfsd/export.c b/fs/nfsd/export.c --- a/fs/nfsd/export.c Fri Feb 14 00:27:28 2003 +++ b/fs/nfsd/export.c Fri Feb 14 00:27:28 2003 @@ -606,7 +606,8 @@ dprintk("exp_export called for %s:%s (%x/%ld fl %x).\n", nxp->ex_client, nxp->ex_path, - nxp->ex_dev, (long) nxp->ex_ino, nxp->ex_flags); + (unsigned)nxp->ex_dev, (long)nxp->ex_ino, + nxp->ex_flags); /* Try to lock the export table for update */ exp_writelock(); @@ -760,8 +761,8 @@ expkey_put(&key->h, &svc_expkey_cache); } else dprintk("nfsd: no export %x/%lx for %s\n", - nxp->ex_dev, (unsigned long) nxp->ex_ino, - nxp->ex_client); + (unsigned)nxp->ex_dev, + (unsigned long) nxp->ex_ino, nxp->ex_client); auth_domain_put(dom); cache_flush(); } else diff -Nru a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c --- a/fs/nfsd/nfssvc.c Fri Feb 14 00:27:26 2003 +++ b/fs/nfsd/nfssvc.c Fri Feb 14 00:27:26 2003 @@ -173,8 +173,7 @@ /* Lock module and set up kernel thread */ MOD_INC_USE_COUNT; lock_kernel(); - daemonize(); - sprintf(current->comm, "nfsd"); + daemonize("nfsd"); current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; siginitsetinv(&shutdown_mask, SHUTDOWN_SIGS); diff -Nru a/fs/ntfs/super.c b/fs/ntfs/super.c --- a/fs/ntfs/super.c Fri Feb 14 00:27:29 2003 +++ b/fs/ntfs/super.c Fri Feb 14 00:27:29 2003 @@ -505,8 +505,7 @@ memcpy(bh_primary->b_data, bh_backup->b_data, sb->s_blocksize); mark_buffer_dirty(bh_primary); - ll_rw_block(WRITE, 1, &bh_primary); - wait_on_buffer(bh_primary); + sync_dirty_buffer(bh_primary); if (buffer_uptodate(bh_primary)) { brelse(bh_backup); return bh_primary; diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c --- a/fs/partitions/check.c Fri Feb 14 00:27:30 2003 +++ b/fs/partitions/check.c Fri Feb 14 00:27:30 2003 @@ -297,7 +297,7 @@ struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj); int part = p - disk->part + 1; dev_t base = MKDEV(disk->major, disk->first_minor); - return sprintf(page, "%04x\n",base + part); + return sprintf(page, "%04x\n", (unsigned)(base + part)); } static ssize_t part_start_read(struct hd_struct * p, char *page) { diff -Nru a/fs/proc/array.c b/fs/proc/array.c --- a/fs/proc/array.c Fri Feb 14 00:27:28 2003 +++ b/fs/proc/array.c Fri Feb 14 00:27:28 2003 @@ -211,6 +211,9 @@ buffer += sprintf(buffer, "SigPnd:\t"); buffer = render_sigset_t(&p->pending.signal, buffer); *buffer++ = '\n'; + buffer += sprintf(buffer, "ShdPnd:\t"); + buffer = render_sigset_t(&p->signal->shared_pending.signal, buffer); + *buffer++ = '\n'; buffer += sprintf(buffer, "SigBlk:\t"); buffer = render_sigset_t(&p->blocked, buffer); *buffer++ = '\n'; diff -Nru a/fs/proc/generic.c b/fs/proc/generic.c --- a/fs/proc/generic.c Fri Feb 14 00:27:30 2003 +++ b/fs/proc/generic.c Fri Feb 14 00:27:30 2003 @@ -65,43 +65,108 @@ start = NULL; if (dp->get_info) { - /* - * Handle backwards compatibility with the old net - * routines. - */ + /* Handle old net routines */ n = dp->get_info(page, &start, *ppos, count); if (n < count) eof = 1; } else if (dp->read_proc) { + /* + * How to be a proc read function + * ------------------------------ + * Prototype: + * int f(char *buffer, char **start, off_t offset, + * int count, int *peof, void *dat) + * + * Assume that the buffer is "count" bytes in size. + * + * If you know you have supplied all the data you + * have, set *peof. + * + * You have three ways to return data: + * 0) Leave *start = NULL. (This is the default.) + * Put the data of the requested offset at that + * offset within the buffer. Return the number (n) + * of bytes there are from the beginning of the + * buffer up to the last byte of data. If the + * number of supplied bytes (= n - offset) is + * greater than zero and you didn't signal eof + * and the reader is prepared to take more data + * you will be called again with the requested + * offset advanced by the number of bytes + * absorbed. This interface is useful for files + * no larger than the buffer. + * 1) Set *start = an unsigned long value less than + * the buffer address but greater than zero. + * Put the data of the requested offset at the + * beginning of the buffer. Return the number of + * bytes of data placed there. If this number is + * greater than zero and you didn't signal eof + * and the reader is prepared to take more data + * you will be called again with the requested + * offset advanced by *start. This interface is + * useful when you have a large file consisting + * of a series of blocks which you want to count + * and return as wholes. + * (Hack by Paul.Russell@rustcorp.com.au) + * 2) Set *start = an address within the buffer. + * Put the data of the requested offset at *start. + * Return the number of bytes of data placed there. + * If this number is greater than zero and you + * didn't signal eof and the reader is prepared to + * take more data you will be called again with the + * requested offset advanced by the number of bytes + * absorbed. + */ n = dp->read_proc(page, &start, *ppos, count, &eof, dp->data); } else break; - if (!start) { - /* - * For proc files that are less than 4k - */ - start = page + *ppos; + if (n == 0) /* end of file */ + break; + if (n < 0) { /* error */ + if (retval == 0) + retval = n; + break; + } + + if (start == NULL) { + if (n > PAGE_SIZE) { + printk(KERN_ERR + "proc_file_read: Apparent buffer overflow!\n"); + n = PAGE_SIZE; + } + if (n > count) + n = count; n -= *ppos; if (n <= 0) break; + start = page + *ppos; + } else if (start < page) { + if (n > PAGE_SIZE) { + printk(KERN_ERR + "proc_file_read: Apparent buffer overflow!\n"); + n = PAGE_SIZE; + } + if (n > count) { + /* + * Don't reduce n because doing so might + * cut off part of a data block. + */ + printk(KERN_WARNING + "proc_file_read: Read count exceeded\n"); + } + } else /* start >= page */ { + unsigned long startoff = (unsigned long)(start - page); + if (n > (PAGE_SIZE - startoff)) { + printk(KERN_ERR + "proc_file_read: Apparent buffer overflow!\n"); + n = PAGE_SIZE - startoff; + } if (n > count) n = count; } - if (n == 0) - break; /* End of file */ - if (n < 0) { - if (retval == 0) - retval = n; - break; - } - /* This is a hack to allow mangling of file pos independent - * of actual bytes read. Simply place the data at page, - * return the bytes, and set `start' to the desired offset - * as an unsigned int. - Paul.Russell@rustcorp.com.au - */ n -= copy_to_user(buf, start < page ? page : start, n); if (n == 0) { if (retval == 0) @@ -109,7 +174,7 @@ break; } - *ppos += start < page ? (long)start : n; /* Move down the file */ + *ppos += start < page ? (unsigned long)start : n; nbytes -= n; buf += n; retval += n; diff -Nru a/fs/qnx4/inode.c b/fs/qnx4/inode.c --- a/fs/qnx4/inode.c Fri Feb 14 00:27:29 2003 +++ b/fs/qnx4/inode.c Fri Feb 14 00:27:30 2003 @@ -44,8 +44,7 @@ bh = qnx4_update_inode(inode); if (bh && buffer_dirty(bh)) { - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); + sync_dirty_buffer(bh); if (buffer_req(bh) && !buffer_uptodate(bh)) { printk ("IO error syncing qnx4 inode [%s:%08lx]\n", diff -Nru a/fs/reiserfs/hashes.c b/fs/reiserfs/hashes.c --- a/fs/reiserfs/hashes.c Fri Feb 14 00:27:29 2003 +++ b/fs/reiserfs/hashes.c Fri Feb 14 00:27:29 2003 @@ -18,6 +18,7 @@ // r5_hash // +#include #include #include diff -Nru a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c --- a/fs/reiserfs/journal.c Fri Feb 14 00:27:28 2003 +++ b/fs/reiserfs/journal.c Fri Feb 14 00:27:28 2003 @@ -735,8 +735,7 @@ } mark_buffer_dirty(jl->j_commit_bh) ; - ll_rw_block(WRITE, 1, &(jl->j_commit_bh)) ; - wait_on_buffer(jl->j_commit_bh) ; + sync_dirty_buffer(jl->j_commit_bh) ; if (!buffer_uptodate(jl->j_commit_bh)) { reiserfs_panic(s, "journal-615: buffer write failed\n") ; } @@ -828,8 +827,7 @@ jh->j_first_unflushed_offset = cpu_to_le32(offset) ; jh->j_mount_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_mount_id) ; set_buffer_dirty(SB_JOURNAL(p_s_sb)->j_header_bh) ; - ll_rw_block(WRITE, 1, &(SB_JOURNAL(p_s_sb)->j_header_bh)) ; - wait_on_buffer((SB_JOURNAL(p_s_sb)->j_header_bh)) ; + sync_dirty_buffer(SB_JOURNAL(p_s_sb)->j_header_bh) ; if (!buffer_uptodate(SB_JOURNAL(p_s_sb)->j_header_bh)) { printk( "reiserfs: journal-837: IO error during journal replay\n" ); return -EIO ; diff -Nru a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c --- a/fs/reiserfs/resize.c Fri Feb 14 00:27:27 2003 +++ b/fs/reiserfs/resize.c Fri Feb 14 00:27:27 2003 @@ -120,8 +120,7 @@ mark_buffer_dirty(bitmap[i].bh) ; set_buffer_uptodate(bitmap[i].bh); - ll_rw_block(WRITE, 1, &bitmap[i].bh); - wait_on_buffer(bitmap[i].bh); + sync_dirty_buffer(bitmap[i].bh); // update bitmap_info stuff bitmap[i].first_zero_hint=1; bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; diff -Nru a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c --- a/fs/smbfs/smbiod.c Fri Feb 14 00:27:29 2003 +++ b/fs/smbfs/smbiod.c Fri Feb 14 00:27:29 2003 @@ -283,14 +283,9 @@ static int smbiod(void *unused) { MOD_INC_USE_COUNT; - daemonize(); + daemonize("smbiod"); - spin_lock_irq(¤t->sighand->siglock); - siginitsetinv(¤t->blocked, sigmask(SIGKILL)); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - strcpy(current->comm, "smbiod"); + allow_signal(SIGKILL); VERBOSE("SMB Kernel thread starting (%d) ...\n", current->pid); diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c --- a/fs/sysfs/inode.c Fri Feb 14 00:27:29 2003 +++ b/fs/sysfs/inode.c Fri Feb 14 00:27:29 2003 @@ -210,7 +210,7 @@ struct kobject * kobj = file->f_dentry->d_parent->d_fsdata; struct sysfs_ops * ops = buffer->ops; int ret = 0; - size_t count; + ssize_t count; if (!buffer->page) buffer->page = (char *) __get_free_page(GFP_KERNEL); diff -Nru a/fs/sysv/inode.c b/fs/sysv/inode.c --- a/fs/sysv/inode.c Fri Feb 14 00:27:26 2003 +++ b/fs/sysv/inode.c Fri Feb 14 00:27:26 2003 @@ -265,8 +265,7 @@ bh = sysv_update_inode(inode); if (bh && buffer_dirty(bh)) { - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); + sync_dirty_buffer(bh); if (buffer_req(bh) && !buffer_uptodate(bh)) { printk ("IO error syncing sysv inode [%s:%08lx]\n", inode->i_sb->s_id, inode->i_ino); diff -Nru a/fs/sysv/itree.c b/fs/sysv/itree.c --- a/fs/sysv/itree.c Fri Feb 14 00:27:27 2003 +++ b/fs/sysv/itree.c Fri Feb 14 00:27:27 2003 @@ -15,10 +15,8 @@ static inline void dirty_indirect(struct buffer_head *bh, struct inode *inode) { mark_buffer_dirty_inode(bh, inode); - if (IS_SYNC(inode)) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } + if (IS_SYNC(inode)) + sync_dirty_buffer(bh); } static int block_to_path(struct inode *inode, long block, int offsets[DEPTH]) diff -Nru a/fs/udf/inode.c b/fs/udf/inode.c --- a/fs/udf/inode.c Fri Feb 14 00:27:30 2003 +++ b/fs/udf/inode.c Fri Feb 14 00:27:30 2003 @@ -1520,8 +1520,7 @@ mark_buffer_dirty(bh); if (do_sync) { - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); + sync_dirty_buffer(bh); if (buffer_req(bh) && !buffer_uptodate(bh)) { printk("IO error syncing udf inode [%s:%08lx]\n", diff -Nru a/fs/ufs/balloc.c b/fs/ufs/balloc.c --- a/fs/ufs/balloc.c Fri Feb 14 00:27:29 2003 +++ b/fs/ufs/balloc.c Fri Feb 14 00:27:29 2003 @@ -114,6 +114,7 @@ ubh_mark_buffer_dirty (USPI_UBH); ubh_mark_buffer_dirty (UCPI_UBH); if (sb->s_flags & MS_SYNCHRONOUS) { + ubh_wait_on_buffer (UCPI_UBH); ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **)&ucpi); ubh_wait_on_buffer (UCPI_UBH); } @@ -199,6 +200,7 @@ ubh_mark_buffer_dirty (USPI_UBH); ubh_mark_buffer_dirty (UCPI_UBH); if (sb->s_flags & MS_SYNCHRONOUS) { + ubh_wait_on_buffer (UCPI_UBH); ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **)&ucpi); ubh_wait_on_buffer (UCPI_UBH); } @@ -228,10 +230,8 @@ memset (bh->b_data, 0, sb->s_blocksize); \ set_buffer_uptodate(bh); \ mark_buffer_dirty (bh); \ - if (IS_SYNC(inode)) { \ - ll_rw_block (WRITE, 1, &bh); \ - wait_on_buffer (bh); \ - } \ + if (IS_SYNC(inode)) \ + sync_dirty_buffer(bh); \ brelse (bh); \ } @@ -364,10 +364,8 @@ clear_buffer_dirty(bh); bh->b_blocknr = result + i; mark_buffer_dirty (bh); - if (IS_SYNC(inode)) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } + if (IS_SYNC(inode)) + sync_dirty_buffer(bh); brelse (bh); } else @@ -459,6 +457,7 @@ ubh_mark_buffer_dirty (USPI_UBH); ubh_mark_buffer_dirty (UCPI_UBH); if (sb->s_flags & MS_SYNCHRONOUS) { + ubh_wait_on_buffer (UCPI_UBH); ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **)&ucpi); ubh_wait_on_buffer (UCPI_UBH); } @@ -584,6 +583,7 @@ ubh_mark_buffer_dirty (USPI_UBH); ubh_mark_buffer_dirty (UCPI_UBH); if (sb->s_flags & MS_SYNCHRONOUS) { + ubh_wait_on_buffer (UCPI_UBH); ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **)&ucpi); ubh_wait_on_buffer (UCPI_UBH); } diff -Nru a/fs/ufs/dir.c b/fs/ufs/dir.c --- a/fs/ufs/dir.c Fri Feb 14 00:27:29 2003 +++ b/fs/ufs/dir.c Fri Feb 14 00:27:29 2003 @@ -356,10 +356,8 @@ dir->i_version++; de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino); mark_buffer_dirty(bh); - if (IS_DIRSYNC(dir)) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer(bh); - } + if (IS_DIRSYNC(dir)) + sync_dirty_buffer(bh); brelse (bh); } @@ -457,10 +455,8 @@ de->d_ino = cpu_to_fs32(sb, inode->i_ino); ufs_set_de_type(sb, de, inode->i_mode); mark_buffer_dirty(bh); - if (IS_DIRSYNC(dir)) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } + if (IS_DIRSYNC(dir)) + sync_dirty_buffer(bh); brelse (bh); dir->i_mtime = dir->i_ctime = CURRENT_TIME; dir->i_version++; @@ -508,10 +504,8 @@ inode->i_ctime = inode->i_mtime = CURRENT_TIME; mark_inode_dirty(inode); mark_buffer_dirty(bh); - if (IS_DIRSYNC(inode)) { - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); - } + if (IS_DIRSYNC(inode)) + sync_dirty_buffer(bh); brelse(bh); UFSD(("EXIT\n")) return 0; diff -Nru a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c --- a/fs/ufs/ialloc.c Fri Feb 14 00:27:30 2003 +++ b/fs/ufs/ialloc.c Fri Feb 14 00:27:30 2003 @@ -124,6 +124,7 @@ ubh_mark_buffer_dirty (USPI_UBH); ubh_mark_buffer_dirty (UCPI_UBH); if (sb->s_flags & MS_SYNCHRONOUS) { + ubh_wait_on_buffer (UCPI_UBH); ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **) &ucpi); ubh_wait_on_buffer (UCPI_UBH); } @@ -248,6 +249,7 @@ ubh_mark_buffer_dirty (USPI_UBH); ubh_mark_buffer_dirty (UCPI_UBH); if (sb->s_flags & MS_SYNCHRONOUS) { + ubh_wait_on_buffer (UCPI_UBH); ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **) &ucpi); ubh_wait_on_buffer (UCPI_UBH); } diff -Nru a/fs/ufs/inode.c b/fs/ufs/inode.c --- a/fs/ufs/inode.c Fri Feb 14 00:27:27 2003 +++ b/fs/ufs/inode.c Fri Feb 14 00:27:27 2003 @@ -298,10 +298,8 @@ } mark_buffer_dirty(bh); - if (IS_SYNC(inode)) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } + if (IS_SYNC(inode)) + sync_dirty_buffer(bh); inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); out: @@ -635,10 +633,8 @@ memset (ufs_inode, 0, sizeof(struct ufs_inode)); mark_buffer_dirty(bh); - if (do_sync) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } + if (do_sync) + sync_dirty_buffer(bh); brelse (bh); UFSD(("EXIT\n")) diff -Nru a/fs/ufs/truncate.c b/fs/ufs/truncate.c --- a/fs/ufs/truncate.c Fri Feb 14 00:27:28 2003 +++ b/fs/ufs/truncate.c Fri Feb 14 00:27:28 2003 @@ -284,6 +284,7 @@ } } if (IS_SYNC(inode) && ind_ubh && ubh_buffer_dirty(ind_ubh)) { + ubh_wait_on_buffer (ind_ubh); ubh_ll_rw_block (WRITE, 1, &ind_ubh); ubh_wait_on_buffer (ind_ubh); } @@ -351,6 +352,7 @@ } } if (IS_SYNC(inode) && dind_bh && ubh_buffer_dirty(dind_bh)) { + ubh_wait_on_buffer (dind_bh); ubh_ll_rw_block (WRITE, 1, &dind_bh); ubh_wait_on_buffer (dind_bh); } @@ -415,6 +417,7 @@ } } if (IS_SYNC(inode) && tind_bh && ubh_buffer_dirty(tind_bh)) { + ubh_wait_on_buffer (tind_bh); ubh_ll_rw_block (WRITE, 1, &tind_bh); ubh_wait_on_buffer (tind_bh); } diff -Nru a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c --- a/fs/xfs/pagebuf/page_buf.c Fri Feb 14 00:27:26 2003 +++ b/fs/xfs/pagebuf/page_buf.c Fri Feb 14 00:27:26 2003 @@ -1578,15 +1578,8 @@ TIMER_INITIALIZER((timeout_fn)pagebuf_daemon_wakeup, 0, 0); /* Set up the thread */ - daemonize(); + daemonize("pagebufd"); - /* Avoid signals */ - spin_lock_irq(¤t->sighand->siglock); - sigfillset(¤t->blocked); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - strcpy(current->comm, "pagebufd"); current->flags |= PF_MEMALLOC; INIT_LIST_HEAD(&tmp); diff -Nru a/include/acpi/acpi.h b/include/acpi/acpi.h --- a/include/acpi/acpi.h Fri Feb 14 00:27:28 2003 +++ b/include/acpi/acpi.h Fri Feb 14 00:27:28 2003 @@ -30,21 +30,21 @@ * We put them here because we don't want to duplicate them * in the rest of the source code again and again. */ -#include "acconfig.h" /* Configuration constants */ -#include "platform/acenv.h" /* Target environment specific items */ -#include "actypes.h" /* Fundamental common data types */ -#include "acexcep.h" /* ACPI exception codes */ -#include "acmacros.h" /* C macros */ -#include "actbl.h" /* ACPI table definitions */ -#include "aclocal.h" /* Internal data types */ -#include "acoutput.h" /* Error output and Debug macros */ -#include "acpiosxf.h" /* Interfaces to the ACPI-to-OS layer*/ -#include "acpixf.h" /* ACPI core subsystem external interfaces */ -#include "acobject.h" /* ACPI internal object */ -#include "acstruct.h" /* Common structures */ -#include "acglobal.h" /* All global variables */ -#include "achware.h" /* Hardware defines and interfaces */ -#include "acutils.h" /* Utility interfaces */ +#include /* Configuration constants */ +#include /* Target environment specific items */ +#include /* Fundamental common data types */ +#include /* ACPI exception codes */ +#include /* C macros */ +#include /* ACPI table definitions */ +#include /* Internal data types */ +#include /* Error output and Debug macros */ +#include /* Interfaces to the ACPI-to-OS layer*/ +#include /* ACPI core subsystem external interfaces */ +#include /* ACPI internal object */ +#include /* Common structures */ +#include /* All global variables */ +#include /* Hardware defines and interfaces */ +#include /* Utility interfaces */ #endif /* __ACPI_H__ */ diff -Nru a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h --- a/include/acpi/acpi_drivers.h Fri Feb 14 00:27:29 2003 +++ b/include/acpi/acpi_drivers.h Fri Feb 14 00:27:29 2003 @@ -27,7 +27,7 @@ #define __ACPI_DRIVERS_H__ #include -#include "acpi_bus.h" +#include #define ACPI_MAX_STRING 80 diff -Nru a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h --- a/include/acpi/acpiosxf.h Fri Feb 14 00:27:26 2003 +++ b/include/acpi/acpiosxf.h Fri Feb 14 00:27:26 2003 @@ -29,8 +29,8 @@ #ifndef __ACPIOSXF_H__ #define __ACPIOSXF_H__ -#include "platform/acenv.h" -#include "actypes.h" +#include +#include /* Priorities for acpi_os_queue_for_execution */ diff -Nru a/include/acpi/acpixf.h b/include/acpi/acpixf.h --- a/include/acpi/acpixf.h Fri Feb 14 00:27:26 2003 +++ b/include/acpi/acpixf.h Fri Feb 14 00:27:26 2003 @@ -27,8 +27,8 @@ #ifndef __ACXFACE_H__ #define __ACXFACE_H__ -#include "actypes.h" -#include "actbl.h" +#include +#include /* diff -Nru a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h --- a/include/acpi/platform/acenv.h Fri Feb 14 00:27:27 2003 +++ b/include/acpi/platform/acenv.h Fri Feb 14 00:27:27 2003 @@ -97,8 +97,8 @@ /*! [Begin] no source code translation */ -#if defined(_LINUX) -#include "aclinux.h" +#if defined(__linux__) +#include #elif defined(_AED_EFI) #include "acefi.h" diff -Nru a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h --- a/include/acpi/platform/aclinux.h Fri Feb 14 00:27:29 2003 +++ b/include/acpi/platform/aclinux.h Fri Feb 14 00:27:29 2003 @@ -28,6 +28,7 @@ #define ACPI_OS_NAME "Linux" #define ACPI_USE_SYSTEM_CLIBRARY +#define ACPI_USE_DO_WHILE_0 #ifdef __KERNEL__ diff -Nru a/include/asm-alpha/signal.h b/include/asm-alpha/signal.h --- a/include/asm-alpha/signal.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-alpha/signal.h Fri Feb 14 00:27:28 2003 @@ -186,6 +186,7 @@ #ifdef __KERNEL__ #include +#define ptrace_signal_deliver(regs, cookie) do { } while (0) #define HAVE_ARCH_SYS_PAUSE #endif diff -Nru a/include/asm-cris/signal.h b/include/asm-cris/signal.h --- a/include/asm-cris/signal.h Fri Feb 14 00:27:29 2003 +++ b/include/asm-cris/signal.h Fri Feb 14 00:27:29 2003 @@ -181,6 +181,7 @@ /* here we could define asm-optimized sigaddset, sigdelset etc. operations. * if we don't, generic ones are used from linux/signal.h */ +#define ptrace_signal_deliver(regs, cookie) do { } while (0) #endif /* __KERNEL__ */ diff -Nru a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h --- a/include/asm-i386/fixmap.h Fri Feb 14 00:27:26 2003 +++ b/include/asm-i386/fixmap.h Fri Feb 14 00:27:26 2003 @@ -60,7 +60,7 @@ #ifdef CONFIG_X86_F00F_BUG FIX_F00F_IDT, /* Virtual mapping for IDT */ #endif -#ifdef CONFIG_X86_CYCLONE +#ifdef CONFIG_X86_SUMMIT FIX_CYCLONE_TIMER, /*cyclone timer register*/ #endif #ifdef CONFIG_HIGHMEM diff -Nru a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h --- a/include/asm-i386/mach-summit/mach_apic.h Fri Feb 14 00:27:29 2003 +++ b/include/asm-i386/mach-summit/mach_apic.h Fri Feb 14 00:27:29 2003 @@ -3,7 +3,7 @@ extern int x86_summit; -#define esr_disable (1) +#define esr_disable (x86_summit ? 1 : 0) #define no_balance_irq (0) #define XAPIC_DEST_CPUS_MASK 0x0Fu @@ -15,14 +15,14 @@ #define APIC_DFR_VALUE (x86_summit ? APIC_DFR_CLUSTER : APIC_DFR_FLAT) #define TARGET_CPUS (x86_summit ? XAPIC_DEST_CPUS_MASK : cpu_online_map) -#define INT_DELIVERY_MODE dest_Fixed +#define INT_DELIVERY_MODE (x86_summit ? dest_Fixed : dest_LowestPrio) #define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ #define APIC_BROADCAST_ID (x86_summit ? 0xFF : 0x0F) -#define check_apicid_used(bitmap, apicid) (0) +#define check_apicid_used(bitmap, apicid) (x86_summit ? 0 : (bitmap & (1 << apicid))) /* we don't use the phys_cpu_present_map to indicate apicid presence */ -#define check_apicid_present(bit) (1) +#define check_apicid_present(bit) (x86_summit ? 1 : (phys_cpu_present_map & (1 << bit))) extern u8 bios_cpu_apicid[]; @@ -106,7 +106,10 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) { - return (1); + if (x86_summit) + return (1); + else + return test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map); } #endif /* __ASM_MACH_APIC_H */ diff -Nru a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-i386/mach-summit/mach_mpparse.h --- a/include/asm-i386/mach-summit/mach_mpparse.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-i386/mach-summit/mach_mpparse.h Fri Feb 14 00:27:28 2003 @@ -1,6 +1,8 @@ #ifndef __ASM_MACH_MPPARSE_H #define __ASM_MACH_MPPARSE_H +extern int use_cyclone; + static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, struct mpc_config_translation *translation) { @@ -17,14 +19,18 @@ { if (!strncmp(oem, "IBM ENSW", 8) && (!strncmp(productid, "VIGIL SMP", 9) - || !strncmp(productid, "RUTHLESS SMP", 12))) + || !strncmp(productid, "RUTHLESS SMP", 12))){ x86_summit = 1; + use_cyclone = 1; /*enable cyclone-timer*/ + } } /* Hook from generic ACPI tables.c */ static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id) { - if (!strncmp(oem_id, "IBM", 3) && !strncmp(oem_table_id, "SERVIGIL", 8)) + if (!strncmp(oem_id, "IBM", 3) && !strncmp(oem_table_id, "SERVIGIL", 8)){ x86_summit = 1; + use_cyclone = 1; /*enable cyclone-timer*/ + } } #endif /* __ASM_MACH_MPPARSE_H */ diff -Nru a/include/asm-i386/module.h b/include/asm-i386/module.h --- a/include/asm-i386/module.h Fri Feb 14 00:27:27 2003 +++ b/include/asm-i386/module.h Fri Feb 14 00:27:27 2003 @@ -46,6 +46,8 @@ #define MODULE_PROC_FAMILY "WINCHIP3D " #elif CONFIG_MCYRIXIII #define MODULE_PROC_FAMILY "CYRIXIII " +#elif CONFIG_MVIAC3_2 +#define MODULE_PROC_FAMILY "VIAC3-2 " #else #error unknown processor family #endif diff -Nru a/include/asm-i386/msr.h b/include/asm-i386/msr.h --- a/include/asm-i386/msr.h Fri Feb 14 00:27:26 2003 +++ b/include/asm-i386/msr.h Fri Feb 14 00:27:26 2003 @@ -93,6 +93,90 @@ #define MSR_IA32_MC0_ADDR 0x402 #define MSR_IA32_MC0_MISC 0x403 +/* Pentium IV performance counter MSRs */ +#define MSR_P4_BPU_PERFCTR0 0x300 +#define MSR_P4_BPU_PERFCTR1 0x301 +#define MSR_P4_BPU_PERFCTR2 0x302 +#define MSR_P4_BPU_PERFCTR3 0x303 +#define MSR_P4_MS_PERFCTR0 0x304 +#define MSR_P4_MS_PERFCTR1 0x305 +#define MSR_P4_MS_PERFCTR2 0x306 +#define MSR_P4_MS_PERFCTR3 0x307 +#define MSR_P4_FLAME_PERFCTR0 0x308 +#define MSR_P4_FLAME_PERFCTR1 0x309 +#define MSR_P4_FLAME_PERFCTR2 0x30a +#define MSR_P4_FLAME_PERFCTR3 0x30b +#define MSR_P4_IQ_PERFCTR0 0x30c +#define MSR_P4_IQ_PERFCTR1 0x30d +#define MSR_P4_IQ_PERFCTR2 0x30e +#define MSR_P4_IQ_PERFCTR3 0x30f +#define MSR_P4_IQ_PERFCTR4 0x310 +#define MSR_P4_IQ_PERFCTR5 0x311 +#define MSR_P4_BPU_CCCR0 0x360 +#define MSR_P4_BPU_CCCR1 0x361 +#define MSR_P4_BPU_CCCR2 0x362 +#define MSR_P4_BPU_CCCR3 0x363 +#define MSR_P4_MS_CCCR0 0x364 +#define MSR_P4_MS_CCCR1 0x365 +#define MSR_P4_MS_CCCR2 0x366 +#define MSR_P4_MS_CCCR3 0x367 +#define MSR_P4_FLAME_CCCR0 0x368 +#define MSR_P4_FLAME_CCCR1 0x369 +#define MSR_P4_FLAME_CCCR2 0x36a +#define MSR_P4_FLAME_CCCR3 0x36b +#define MSR_P4_IQ_CCCR0 0x36c +#define MSR_P4_IQ_CCCR1 0x36d +#define MSR_P4_IQ_CCCR2 0x36e +#define MSR_P4_IQ_CCCR3 0x36f +#define MSR_P4_IQ_CCCR4 0x370 +#define MSR_P4_IQ_CCCR5 0x371 +#define MSR_P4_ALF_ESCR0 0x3ca +#define MSR_P4_ALF_ESCR1 0x3cb +#define MSR_P4_BPU_ESCR0 0x3b2 +#define MSR_P4_BPU_ESCR1 0x3b3 +#define MSR_P4_BSU_ESCR0 0x3a0 +#define MSR_P4_BSU_ESCR1 0x3a1 +#define MSR_P4_CRU_ESCR0 0x3b8 +#define MSR_P4_CRU_ESCR1 0x3b9 +#define MSR_P4_CRU_ESCR2 0x3cc +#define MSR_P4_CRU_ESCR3 0x3cd +#define MSR_P4_CRU_ESCR4 0x3e0 +#define MSR_P4_CRU_ESCR5 0x3e1 +#define MSR_P4_DAC_ESCR0 0x3a8 +#define MSR_P4_DAC_ESCR1 0x3a9 +#define MSR_P4_FIRM_ESCR0 0x3a4 +#define MSR_P4_FIRM_ESCR1 0x3a5 +#define MSR_P4_FLAME_ESCR0 0x3a6 +#define MSR_P4_FLAME_ESCR1 0x3a7 +#define MSR_P4_FSB_ESCR0 0x3a2 +#define MSR_P4_FSB_ESCR1 0x3a3 +#define MSR_P4_IQ_ESCR0 0x3ba +#define MSR_P4_IQ_ESCR1 0x3bb +#define MSR_P4_IS_ESCR0 0x3b4 +#define MSR_P4_IS_ESCR1 0x3b5 +#define MSR_P4_ITLB_ESCR0 0x3b6 +#define MSR_P4_ITLB_ESCR1 0x3b7 +#define MSR_P4_IX_ESCR0 0x3c8 +#define MSR_P4_IX_ESCR1 0x3c9 +#define MSR_P4_MOB_ESCR0 0x3aa +#define MSR_P4_MOB_ESCR1 0x3ab +#define MSR_P4_MS_ESCR0 0x3c0 +#define MSR_P4_MS_ESCR1 0x3c1 +#define MSR_P4_PMH_ESCR0 0x3ac +#define MSR_P4_PMH_ESCR1 0x3ad +#define MSR_P4_RAT_ESCR0 0x3bc +#define MSR_P4_RAT_ESCR1 0x3bd +#define MSR_P4_SAAT_ESCR0 0x3ae +#define MSR_P4_SAAT_ESCR1 0x3af +#define MSR_P4_SSU_ESCR0 0x3be +#define MSR_P4_SSU_ESCR1 0x3bf /* guess: not defined in manual */ +#define MSR_P4_TBPU_ESCR0 0x3c2 +#define MSR_P4_TBPU_ESCR1 0x3c3 +#define MSR_P4_TC_ESCR0 0x3c4 +#define MSR_P4_TC_ESCR1 0x3c5 +#define MSR_P4_U2L_ESCR0 0x3b0 +#define MSR_P4_U2L_ESCR1 0x3b1 + /* AMD Defined MSRs */ #define MSR_K6_EFER 0xC0000080 #define MSR_K6_STAR 0xC0000081 diff -Nru a/include/asm-i386/signal.h b/include/asm-i386/signal.h --- a/include/asm-i386/signal.h Fri Feb 14 00:27:27 2003 +++ b/include/asm-i386/signal.h Fri Feb 14 00:27:27 2003 @@ -217,6 +217,7 @@ struct pt_regs; extern int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset)); +#define ptrace_signal_deliver(regs, cookie) do { } while (0) #endif /* __KERNEL__ */ diff -Nru a/include/asm-ia64/signal.h b/include/asm-ia64/signal.h --- a/include/asm-ia64/signal.h Fri Feb 14 00:27:27 2003 +++ b/include/asm-ia64/signal.h Fri Feb 14 00:27:27 2003 @@ -166,6 +166,7 @@ # include +#define ptrace_signal_deliver(regs, cookie) do { } while (0) #define HAVE_ARCH_SYS_PAUSE #endif /* __KERNEL__ */ diff -Nru a/include/asm-m68knommu/signal.h b/include/asm-m68knommu/signal.h --- a/include/asm-m68knommu/signal.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-m68knommu/signal.h Fri Feb 14 00:27:28 2003 @@ -176,6 +176,8 @@ #include #undef __HAVE_ARCH_SIG_BITOPS +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + #endif /* __KERNEL__ */ #endif /* _M68KNOMMU_SIGNAL_H */ diff -Nru a/include/asm-mips/signal.h b/include/asm-mips/signal.h --- a/include/asm-mips/signal.h Fri Feb 14 00:27:27 2003 +++ b/include/asm-mips/signal.h Fri Feb 14 00:27:27 2003 @@ -169,6 +169,8 @@ #define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */ #define BRK_MULOVF 1023 /* Multiply overflow */ +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + #endif /* defined (__KERNEL__) */ #endif /* _ASM_SIGNAL_H */ diff -Nru a/include/asm-mips64/signal.h b/include/asm-mips64/signal.h --- a/include/asm-mips64/signal.h Fri Feb 14 00:27:29 2003 +++ b/include/asm-mips64/signal.h Fri Feb 14 00:27:29 2003 @@ -168,6 +168,9 @@ #define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */ #define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */ #define BRK_MULOVF 1023 /* Multiply overflow */ + +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + #endif /* defined (__KERNEL__) || defined (__USE_MISC) */ #endif /* !defined (_ASM_SIGNAL_H) */ diff -Nru a/include/asm-ppc/signal.h b/include/asm-ppc/signal.h --- a/include/asm-ppc/signal.h Fri Feb 14 00:27:27 2003 +++ b/include/asm-ppc/signal.h Fri Feb 14 00:27:27 2003 @@ -150,6 +150,7 @@ #ifdef __KERNEL__ #include +#define ptrace_signal_deliver(regs, cookie) do { } while (0) #endif /* __KERNEL__ */ #endif diff -Nru a/include/asm-ppc64/signal.h b/include/asm-ppc64/signal.h --- a/include/asm-ppc64/signal.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-ppc64/signal.h Fri Feb 14 00:27:28 2003 @@ -143,4 +143,6 @@ size_t ss_size; } stack_t; +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + #endif /* _ASMPPC64_SIGNAL_H */ diff -Nru a/include/asm-s390/signal.h b/include/asm-s390/signal.h --- a/include/asm-s390/signal.h Fri Feb 14 00:27:29 2003 +++ b/include/asm-s390/signal.h Fri Feb 14 00:27:29 2003 @@ -175,6 +175,8 @@ #define sa_handler _u._sa_handler #define sa_sigaction _u._sa_sigaction +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + #endif /* __KERNEL__ */ typedef struct sigaltstack { diff -Nru a/include/asm-s390x/signal.h b/include/asm-s390x/signal.h --- a/include/asm-s390x/signal.h Fri Feb 14 00:27:29 2003 +++ b/include/asm-s390x/signal.h Fri Feb 14 00:27:29 2003 @@ -175,6 +175,8 @@ #define sa_handler _u._sa_handler #define sa_sigaction _u._sa_sigaction +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + #endif /* __KERNEL__ */ typedef struct sigaltstack { diff -Nru a/include/asm-sh/signal.h b/include/asm-sh/signal.h --- a/include/asm-sh/signal.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-sh/signal.h Fri Feb 14 00:27:28 2003 @@ -165,6 +165,8 @@ #ifdef __KERNEL__ #include +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + #endif /* __KERNEL__ */ #endif /* __ASM_SH_SIGNAL_H */ diff -Nru a/include/asm-sparc/cacheflush.h b/include/asm-sparc/cacheflush.h --- a/include/asm-sparc/cacheflush.h Fri Feb 14 00:27:27 2003 +++ b/include/asm-sparc/cacheflush.h Fri Feb 14 00:27:27 2003 @@ -62,8 +62,9 @@ #define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr) #define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr) -extern void flush_page_to_ram(struct page *page); +extern void sparc_flush_page_to_ram(struct page *page); -#define flush_dcache_page(page) do { } while (0) +#define flush_page_to_ram(page) do { } while (0) +#define flush_dcache_page(page) sparc_flush_page_to_ram(page) #endif /* _SPARC_CACHEFLUSH_H */ diff -Nru a/include/asm-sparc/page.h b/include/asm-sparc/page.h --- a/include/asm-sparc/page.h Fri Feb 14 00:27:27 2003 +++ b/include/asm-sparc/page.h Fri Feb 14 00:27:27 2003 @@ -31,8 +31,14 @@ #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) #define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) -#define clear_user_page(addr, vaddr, page) clear_page(addr) -#define copy_user_page(to, from, vaddr, page) copy_page(to, from) +#define clear_user_page(addr, vaddr, page) \ + do { clear_page(addr); \ + sparc_flush_page_to_ram(page); \ + } while (0) +#define copy_user_page(to, from, vaddr, page) \ + do { copy_page(to, from); \ + sparc_flush_page_to_ram(page); \ + } while (0) /* The following structure is used to hold the physical * memory configuration of the machine. This is filled in diff -Nru a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h --- a/include/asm-sparc/signal.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-sparc/signal.h Fri Feb 14 00:27:28 2003 @@ -216,7 +216,32 @@ size_t ss_size; } stack_t; -#define HAVE_ARCH_GET_SIGNAL_TO_DELIVER +struct sparc_deliver_cookie { + int restart_syscall; + unsigned long orig_i0; +}; + +#define ptrace_signal_deliver(REGS, COOKIE) \ +do { struct sparc_deliver_cookie *cp = (COOKIE); \ + if (cp->restart_syscall && \ + (regs->u_regs[UREG_I0] == ERESTARTNOHAND || \ + regs->u_regs[UREG_I0] == ERESTARTSYS || \ + regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { \ + /* replay the system call when we are done */ \ + regs->u_regs[UREG_I0] = cp->orig_i0; \ + regs->pc -= 4; \ + regs->npc -= 4; \ + cp->restart_syscall = 0; \ + } \ + if (cp->restart_syscall && \ + regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { \ + regs->u_regs[UREG_G1] = __NR_restart_syscall; \ + regs->pc -= 4; \ + regs->npc -= 4; \ + cp->restart_syscall = 0; \ + } \ +} while (0) + #endif /* !(__ASSEMBLY__) */ diff -Nru a/include/asm-sparc/system.h b/include/asm-sparc/system.h --- a/include/asm-sparc/system.h Fri Feb 14 00:27:29 2003 +++ b/include/asm-sparc/system.h Fri Feb 14 00:27:29 2003 @@ -62,8 +62,6 @@ return serial_console ? 0 : 1; } -extern struct pt_regs *kbd_pt_regs; - /* When a context switch happens we must flush all user windows so that * the windows of the current process are flushed onto its stack. This * way the windows are all clean for the next process and the stack diff -Nru a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h --- a/include/asm-sparc64/signal.h Fri Feb 14 00:27:27 2003 +++ b/include/asm-sparc64/signal.h Fri Feb 14 00:27:27 2003 @@ -245,7 +245,32 @@ compat_size_t ss_size; } stack_t32; -#define HAVE_ARCH_GET_SIGNAL_TO_DELIVER +struct signal_deliver_cookie { + int restart_syscall; + unsigned long orig_i0; +}; + +#define ptrace_signal_deliver(REGS, COOKIE) \ +do { struct signal_deliver_cookie *cp = (COOKIE); \ + if (cp->restart_syscall && \ + (regs->u_regs[UREG_I0] == ERESTARTNOHAND || \ + regs->u_regs[UREG_I0] == ERESTARTSYS || \ + regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { \ + /* replay the system call when we are done */ \ + regs->u_regs[UREG_I0] = cp->orig_i0; \ + regs->tpc -= 4; \ + regs->tnpc -= 4; \ + cp->restart_syscall = 0; \ + } \ + if (cp->restart_syscall && \ + regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { \ + regs->u_regs[UREG_G1] = __NR_restart_syscall; \ + regs->tpc -= 4; \ + regs->tnpc -= 4; \ + cp->restart_syscall = 0; \ + } \ +} while (0) + #define HAVE_ARCH_SYS_PAUSE #endif diff -Nru a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h --- a/include/asm-sparc64/system.h Fri Feb 14 00:27:26 2003 +++ b/include/asm-sparc64/system.h Fri Feb 14 00:27:26 2003 @@ -131,8 +131,6 @@ return serial_console ? 0 : 1; } -extern struct pt_regs *kbd_pt_regs; - extern void synchronize_user_stack(void); extern void __flushw_user(void); diff -Nru a/include/asm-v850/signal.h b/include/asm-v850/signal.h --- a/include/asm-v850/signal.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-v850/signal.h Fri Feb 14 00:27:28 2003 @@ -188,6 +188,8 @@ #include #undef __HAVE_ARCH_SIG_BITOPS +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + #endif /* __KERNEL__ */ #endif /* __V850_SIGNAL_H__ */ diff -Nru a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h --- a/include/asm-x86_64/acpi.h Fri Feb 14 00:27:29 2003 +++ b/include/asm-x86_64/acpi.h Fri Feb 14 00:27:29 2003 @@ -48,8 +48,8 @@ #define ACPI_ASM_MACROS #define BREAKPOINT3 -#define ACPI_DISABLE_IRQS() __cli() -#define ACPI_ENABLE_IRQS() __sti() +#define ACPI_DISABLE_IRQS() local_irq_disable() +#define ACPI_ENABLE_IRQS() local_irq_enable() #define ACPI_FLUSH_CPU_CACHE() wbinvd() /* @@ -141,6 +141,10 @@ #define boot_cpu_physical_apicid boot_cpu_id extern int acpi_disabled; + +#define dmi_broken (0) +#define BROKEN_ACPI_Sx 0x0001 +#define BROKEN_INIT_AFTER_S1 0x0002 #endif /*__KERNEL__*/ diff -Nru a/include/asm-x86_64/current.h b/include/asm-x86_64/current.h --- a/include/asm-x86_64/current.h Fri Feb 14 00:27:26 2003 +++ b/include/asm-x86_64/current.h Fri Feb 14 00:27:26 2003 @@ -12,15 +12,6 @@ return t; } - -#define stack_current() \ -({ \ - struct thread_info *ti; \ - __asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (~8191UL)); \ - ti->task; \ -}) - - #define current get_current() #else diff -Nru a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h --- a/include/asm-x86_64/desc.h Fri Feb 14 00:27:30 2003 +++ b/include/asm-x86_64/desc.h Fri Feb 14 00:27:30 2003 @@ -135,6 +135,14 @@ DESC_LDT, size); } +static inline void set_seg_base(unsigned cpu, int entry, void *base) +{ + struct desc_struct *d = &cpu_gdt_table[cpu][entry]; + d->base0 = PTR_LOW(base); + d->base1 = PTR_MIDDLE(base); + d->base2 = PTR_HIGH(base); +} + #define LDT_entry_a(info) \ ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) #define LDT_entry_b(info) \ diff -Nru a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h --- a/include/asm-x86_64/dma-mapping.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-x86_64/dma-mapping.h Fri Feb 14 00:27:28 2003 @@ -1,5 +1,5 @@ -#ifndef _ASM_X8664_DMA_MAPPING_H -#define _ASM_X8664_DMA_MAPPING_H +#ifndef _X8664_DMA_MAPPING_H +#define _X8664_DMA_MAPPING_H 1 #include diff -Nru a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h --- a/include/asm-x86_64/e820.h Fri Feb 14 00:27:27 2003 +++ b/include/asm-x86_64/e820.h Fri Feb 14 00:27:27 2003 @@ -47,7 +47,7 @@ int type); extern void setup_memory_region(void); extern void contig_e820_setup(void); -extern void e820_end_of_ram(void); +extern unsigned long e820_end_of_ram(void); extern void e820_reserve_resources(void); extern void e820_print_map(char *who); extern int e820_mapped(unsigned long start, unsigned long end, int type); diff -Nru a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h --- a/include/asm-x86_64/i387.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-x86_64/i387.h Fri Feb 14 00:27:28 2003 @@ -39,16 +39,10 @@ #define kernel_fpu_end() stts() #define unlazy_fpu(tsk) do { \ - if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) \ + if ((tsk)->thread_info->flags & TIF_USEDFPU) \ save_init_fpu(tsk); \ } while (0) -#define unlazy_current_fpu() do { \ - if (test_thread_flag(TIF_USEDFPU)) \ - save_init_fpu(tsk); \ -} while (0) - - #define clear_fpu(tsk) do { \ if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \ asm volatile("fwait"); \ @@ -134,7 +128,7 @@ { asm volatile( "fxsave %0 ; fnclex" : "=m" (tsk->thread.i387.fxsave)); - clear_tsk_thread_flag(tsk, TIF_USEDFPU); + tsk->thread_info->flags &= ~TIF_USEDFPU; stts(); } diff -Nru a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h --- a/include/asm-x86_64/ia32.h Fri Feb 14 00:27:30 2003 +++ b/include/asm-x86_64/ia32.h Fri Feb 14 00:27:30 2003 @@ -26,28 +26,18 @@ #include /* signal.h */ -#define _IA32_NSIG 64 -#define _IA32_NSIG_BPW 32 -#define _IA32_NSIG_WORDS (_IA32_NSIG / _IA32_NSIG_BPW) - -typedef struct { - unsigned int sig[_IA32_NSIG_WORDS]; -} sigset32_t; - struct sigaction32 { unsigned int sa_handler; /* Really a pointer, but need to deal with 32 bits */ unsigned int sa_flags; unsigned int sa_restorer; /* Another 32 bit pointer */ - sigset32_t sa_mask; /* A 32 bit mask */ + compat_sigset_t sa_mask; /* A 32 bit mask */ }; -typedef unsigned int old_sigset32_t; /* at least 32 bits */ - struct old_sigaction32 { unsigned int sa_handler; /* Really a pointer, but need to deal with 32 bits */ - old_sigset32_t sa_mask; /* A 32 bit mask */ + compat_old_sigset_t sa_mask; /* A 32 bit mask */ unsigned int sa_flags; unsigned int sa_restorer; /* Another 32 bit pointer */ }; @@ -63,7 +53,7 @@ unsigned int uc_link; stack_ia32_t uc_stack; struct sigcontext_ia32 uc_mcontext; - sigset32_t uc_sigmask; /* mask last for extensibility */ + compat_sigset_t uc_sigmask; /* mask last for extensibility */ }; /* This matches struct stat64 in glibc2.2, hence the absolutely diff -Nru a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h --- a/include/asm-x86_64/io.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-x86_64/io.h Fri Feb 14 00:27:28 2003 @@ -1,6 +1,8 @@ #ifndef _ASM_IO_H #define _ASM_IO_H +#include + /* * This file contains the definitions for the x86 IO instructions * inb/inw/inl/outb/outw/outl and the "string versions" of the same @@ -135,7 +137,12 @@ /* * Change "struct page" to physical address. */ +#ifdef CONFIG_DISCONTIGMEM +#include +#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) +#else #define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) +#endif extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); diff -Nru a/include/asm-x86_64/mmsegment.h b/include/asm-x86_64/mmsegment.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-x86_64/mmsegment.h Fri Feb 14 00:27:30 2003 @@ -0,0 +1,8 @@ +#ifndef _ASM_MMSEGMENT_H +#define _ASM_MMSEGMENT_H 1 + +typedef struct { + unsigned long seg; +} mm_segment_t; + +#endif diff -Nru a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-x86_64/mmzone.h Fri Feb 14 00:27:30 2003 @@ -0,0 +1,79 @@ +/* K8 NUMA support */ +/* Copyright 2002,2003 by Andi Kleen, SuSE Labs */ +/* 2.5 Version losely based on the NUMAQ Code by Pat Gaughen. */ +#ifndef _ASM_X86_64_MMZONE_H +#define _ASM_X86_64_MMZONE_H 1 + +#include + +#ifdef CONFIG_DISCONTIGMEM + +#define VIRTUAL_BUG_ON(x) + +#include +#include + +#define MAXNODE 8 +#define NODEMAPSIZE 0xff + +/* Simple perfect hash to map physical addresses to node numbers */ +extern int memnode_shift; +extern u8 memnodemap[NODEMAPSIZE]; +extern int maxnode; + +extern struct pglist_data *node_data[]; + +/* kern_addr_valid below hardcodes the same algorithm*/ +static inline __attribute__((pure)) int phys_to_nid(unsigned long addr) +{ + int nid; + VIRTUAL_BUG_ON((addr >> memnode_shift) >= NODEMAPSIZE); + nid = memnodemap[addr >> memnode_shift]; + VIRTUAL_BUG_ON(nid > maxnode); + return nid; +} + +#define kvaddr_to_nid(kaddr) phys_to_nid(__pa(kaddr)) +#define NODE_DATA(nid) (node_data[nid]) + +#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map) + +#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map) +#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) +#define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \ + NODE_DATA(nid)->node_size) +#define node_size(nid) (NODE_DATA(nid)->node_size) + +#define local_mapnr(kvaddr) \ + ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) ) +#define kern_addr_valid(kvaddr) ({ \ + int ok = 0; \ + unsigned long index = __pa(kvaddr) >> memnode_shift; \ + if (index <= NODEMAPSIZE) { \ + unsigned nodeid = memnodemap[index]; \ + unsigned long pfn = __pa(kvaddr) >> PAGE_SHIFT; \ + unsigned long start_pfn = node_start_pfn(nodeid); \ + ok = (nodeid != 0xff) && \ + (pfn >= start_pfn) && \ + (pfn < start_pfn + node_size(nodeid)); \ + } \ + ok; \ +}) + +/* AK: this currently doesn't deal with invalid addresses. We'll see + if the 2.5 kernel doesn't pass them + (2.4 used to). */ +#define pfn_to_page(pfn) ({ \ + int nid = phys_to_nid(((unsigned long)(pfn)) << PAGE_SHIFT); \ + ((pfn) - node_start_pfn(nid)) + node_mem_map(nid); \ +}) + +#define page_to_pfn(page) \ + (long)(((page) - page_zone(page)->zone_mem_map) + page_zone(page)->zone_start_pfn) + +/* AK: !DISCONTIGMEM just forces it to 1. Can't we too? */ +#define pfn_valid(pfn) ((pfn) < num_physpages) + + +#endif +#endif diff -Nru a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h --- a/include/asm-x86_64/mpspec.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-x86_64/mpspec.h Fri Feb 14 00:27:28 2003 @@ -185,7 +185,6 @@ extern int mp_current_pci_id; extern unsigned long mp_lapic_addr; extern int pic_mode; -extern int using_apic_timer; #ifdef CONFIG_ACPI_BOOT extern void mp_register_lapic (u8 id, u8 enabled); @@ -198,6 +197,8 @@ extern void mp_parse_prt (void); #endif /*CONFIG_X86_IO_APIC*/ #endif + +extern int using_apic_timer; #endif diff -Nru a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h --- a/include/asm-x86_64/msr.h Fri Feb 14 00:27:30 2003 +++ b/include/asm-x86_64/msr.h Fri Feb 14 00:27:30 2003 @@ -67,6 +67,61 @@ : "=a" (low), "=d" (high) \ : "c" (counter)) +extern inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx) +{ + __asm__("cpuid" + : "=a" (*eax), + "=b" (*ebx), + "=c" (*ecx), + "=d" (*edx) + : "0" (op)); +} + +/* + * CPUID functions returning a single datum + */ +extern inline unsigned int cpuid_eax(unsigned int op) +{ + unsigned int eax; + + __asm__("cpuid" + : "=a" (eax) + : "0" (op) + : "bx", "cx", "dx"); + return eax; +} +extern inline unsigned int cpuid_ebx(unsigned int op) +{ + unsigned int eax, ebx; + + __asm__("cpuid" + : "=a" (eax), "=b" (ebx) + : "0" (op) + : "cx", "dx" ); + return ebx; +} +extern inline unsigned int cpuid_ecx(unsigned int op) +{ + unsigned int eax, ecx; + + __asm__("cpuid" + : "=a" (eax), "=c" (ecx) + : "0" (op) + : "bx", "dx" ); + return ecx; +} +extern inline unsigned int cpuid_edx(unsigned int op) +{ + unsigned int eax, edx; + + __asm__("cpuid" + : "=a" (eax), "=d" (edx) + : "0" (op) + : "bx", "cx"); + return edx; +} + + #endif /* AMD/K8 specific MSRs */ diff -Nru a/include/asm-x86_64/numa.h b/include/asm-x86_64/numa.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-x86_64/numa.h Fri Feb 14 00:27:30 2003 @@ -0,0 +1,22 @@ +#ifndef _ASM_X8664_NUMA_H +#define _ASM_X8664_NUMA_H 1 + +#define MAXNODE 8 +#define NODEMASK 0xff + +struct node { + u64 start,end; +}; + +#define for_all_nodes(x) for ((x) = 0; (x) <= maxnode; (x)++) \ + if ((1UL << (x)) & nodes_present) + +#define early_for_all_nodes(n) \ + for (n=0; n + +#ifdef CONFIG_DISCONTIGMEM +#define MAX_NUMNODES 8 /* APIC limit currently */ +#else +#define MAX_NUMNODES 1 +#endif + +#endif diff -Nru a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h --- a/include/asm-x86_64/page.h Fri Feb 14 00:27:26 2003 +++ b/include/asm-x86_64/page.h Fri Feb 14 00:27:26 2003 @@ -1,6 +1,8 @@ #ifndef _X86_64_PAGE_H #define _X86_64_PAGE_H +#include + /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 12 #ifdef __ASSEMBLY__ @@ -10,7 +12,13 @@ #endif #define PAGE_MASK (~(PAGE_SIZE-1)) #define PHYSICAL_PAGE_MASK (~(PAGE_SIZE-1) & (__PHYSICAL_MASK << PAGE_SHIFT)) -#define THREAD_SIZE (2*PAGE_SIZE) + +#define THREAD_ORDER 1 +#ifdef __ASSEMBLY__ +#define THREAD_SIZE (1 << (PAGE_SHIFT + THREAD_ORDER)) +#else +#define THREAD_SIZE (1UL << (PAGE_SHIFT + THREAD_ORDER)) +#endif #define CURRENT_MASK (~(THREAD_SIZE-1)) #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1)) @@ -58,7 +66,7 @@ /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -/* See Documentation/x86_64/mm.txt for a description of the layout. */ +/* See Documentation/x86_64/mm.txt for a description of the memory map. */ #define __START_KERNEL 0xffffffff80100000 #define __START_KERNEL_map 0xffffffff80000000 #define __PAGE_OFFSET 0x0000010000000000 @@ -100,10 +108,13 @@ __pa(v); }) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) +#ifndef CONFIG_DISCONTIGMEM #define pfn_to_page(pfn) (mem_map + (pfn)) #define page_to_pfn(page) ((unsigned long)((page) - mem_map)) -#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) #define pfn_valid(pfn) ((pfn) < max_mapnr) +#endif + +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) diff -Nru a/include/asm-x86_64/pda.h b/include/asm-x86_64/pda.h --- a/include/asm-x86_64/pda.h Fri Feb 14 00:27:27 2003 +++ b/include/asm-x86_64/pda.h Fri Feb 14 00:27:27 2003 @@ -55,7 +55,10 @@ } \ } while (0) - +/* + * AK: PDA read accesses should be neither volatile nor have an memory clobber. + * Unfortunately removing them causes all hell to break lose currently. + */ #define pda_from_op(op,field) ({ \ typedef typeof_field(struct x8664_pda, field) T__; T__ ret__; \ switch (sizeof_field(struct x8664_pda, field)) { \ diff -Nru a/include/asm-x86_64/pgalloc.h b/include/asm-x86_64/pgalloc.h --- a/include/asm-x86_64/pgalloc.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-x86_64/pgalloc.h Fri Feb 14 00:27:28 2003 @@ -14,8 +14,7 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte) { - set_pmd(pmd, __pmd(_PAGE_TABLE | - ((u64)(pte - mem_map) << PAGE_SHIFT))); + set_pmd(pmd, __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT))); } extern __inline__ pmd_t *get_pmd(void) @@ -76,6 +75,6 @@ } #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) -#define __pmd_free_tlb(tlb,x) do { } while (0) +#define __pmd_free_tlb(tlb,x) pmd_free(x) #endif /* _X86_64_PGALLOC_H */ diff -Nru a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h --- a/include/asm-x86_64/pgtable.h Fri Feb 14 00:27:29 2003 +++ b/include/asm-x86_64/pgtable.h Fri Feb 14 00:27:29 2003 @@ -103,6 +103,8 @@ #define ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte, 0)) #define pte_same(a, b) ((a).pte == (b).pte) +#define PML4_SIZE (1UL << PML4_SHIFT) +#define PML4_MASK (~(PML4_SIZE-1)) #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) #define PGDIR_SIZE (1UL << PGDIR_SHIFT) @@ -317,7 +319,8 @@ /* PMD - Level 2 access */ #define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PTE_MASK)) -#define pmd_page(pmd) (mem_map + ((pmd_val(pmd) & PTE_MASK)>>PAGE_SHIFT)) +#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) + #define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) #define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \ __pmd_offset(address)) @@ -372,7 +375,9 @@ #endif /* !__ASSEMBLY__ */ +#ifndef CONFIG_DISCONTIGMEM #define kern_addr_valid(addr) (1) +#endif #define io_remap_page_range remap_page_range diff -Nru a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h --- a/include/asm-x86_64/processor.h Fri Feb 14 00:27:30 2003 +++ b/include/asm-x86_64/processor.h Fri Feb 14 00:27:30 2003 @@ -17,6 +17,7 @@ #include #include #include +#include #define TF_MASK 0x00000100 #define IF_MASK 0x00000200 @@ -110,64 +111,6 @@ #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ /* - * Generic CPUID function - * FIXME: This really belongs to msr.h - */ -extern inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx) -{ - __asm__("cpuid" - : "=a" (*eax), - "=b" (*ebx), - "=c" (*ecx), - "=d" (*edx) - : "0" (op)); -} - -/* - * CPUID functions returning a single datum - */ -extern inline unsigned int cpuid_eax(unsigned int op) -{ - unsigned int eax; - - __asm__("cpuid" - : "=a" (eax) - : "0" (op) - : "bx", "cx", "dx"); - return eax; -} -extern inline unsigned int cpuid_ebx(unsigned int op) -{ - unsigned int eax, ebx; - - __asm__("cpuid" - : "=a" (eax), "=b" (ebx) - : "0" (op) - : "cx", "dx" ); - return ebx; -} -extern inline unsigned int cpuid_ecx(unsigned int op) -{ - unsigned int eax, ecx; - - __asm__("cpuid" - : "=a" (eax), "=c" (ecx) - : "0" (op) - : "bx", "dx" ); - return ecx; -} -extern inline unsigned int cpuid_edx(unsigned int op) -{ - unsigned int eax, edx; - - __asm__("cpuid" - : "=a" (eax), "=d" (edx) - : "0" (op) - : "bx", "cx"); - return edx; -} - -/* * Intel CPU features in CR4 */ #define X86_CR4_VME 0x0001 /* enable vm86 extensions */ @@ -210,36 +153,6 @@ :"ax"); } -#if 0 -/* - * Cyrix CPU configuration register indexes - */ -#define CX86_CCR0 0xc0 -#define CX86_CCR1 0xc1 -#define CX86_CCR2 0xc2 -#define CX86_CCR3 0xc3 -#define CX86_CCR4 0xe8 -#define CX86_CCR5 0xe9 -#define CX86_CCR6 0xea -#define CX86_CCR7 0xeb -#define CX86_DIR0 0xfe -#define CX86_DIR1 0xff -#define CX86_ARR_BASE 0xc4 -#define CX86_RCR_BASE 0xdc - -/* - * Cyrix CPU indexed register access macros - */ - -#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); }) - -#define setCx86(reg, data) do { \ - outb((reg), 0x22); \ - outb((data), 0x23); \ -} while (0) - -#endif - /* * Bus types */ @@ -286,10 +199,6 @@ struct i387_fxsave_struct fxsave; }; -typedef struct { - unsigned long seg; -} mm_segment_t; - struct tss_struct { u32 reserved1; u64 rsp0; @@ -302,7 +211,7 @@ u16 reserved5; u16 io_map_base; u32 io_bitmap[IO_BITMAP_SIZE]; -} __attribute__((packed)); +} __attribute__((packed)) ____cacheline_aligned; struct thread_struct { unsigned long rsp0; @@ -336,6 +245,7 @@ #define NMI_STACK 3 #define N_EXCEPTION_STACKS 3 /* hw limit: 7 */ #define EXCEPTION_STKSZ 1024 +#define EXCEPTION_STK_ORDER 0 #define start_thread(regs,new_rip,new_rsp) do { \ asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0)); \ @@ -378,6 +288,13 @@ __asm__ __volatile__("rep;nop": : :"memory"); } +/* Stop speculative execution */ +extern inline void sync_core(void) +{ + int tmp; + asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory"); +} + #define cpu_has_fpu 1 #define ARCH_HAS_PREFETCH @@ -389,7 +306,6 @@ #define spin_lock_prefetch(x) prefetchw(x) #define cpu_relax() rep_nop() - /* * NSC/Cyrix CPU configuration register indexes */ @@ -416,5 +332,12 @@ outb((reg), 0x22); \ outb((data), 0x23); \ } while (0) + +#define stack_current() \ +({ \ + struct thread_info *ti; \ + asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK)); \ + ti->task; \ +}) #endif /* __ASM_X86_64_PROCESSOR_H */ diff -Nru a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h --- a/include/asm-x86_64/proto.h Fri Feb 14 00:27:30 2003 +++ b/include/asm-x86_64/proto.h Fri Feb 14 00:27:30 2003 @@ -25,6 +25,8 @@ extern void do_softirq_thunk(void); +extern int numa_setup(char *opt); + extern int setup_early_printk(char *); extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2))); @@ -36,18 +38,27 @@ extern void reserve_bootmem_generic(unsigned long phys, unsigned len); extern void free_bootmem_generic(unsigned long phys, unsigned len); -extern unsigned long start_pfn, end_pfn, end_pfn_map; +extern unsigned long end_pfn_map; extern void show_stack(unsigned long * rsp); extern void exception_table_check(void); -extern int acpi_boot_init(char *); +extern void acpi_reserve_bootmem(void); + +extern void swap_low_mappings(void); extern int map_syscall32(struct mm_struct *mm, unsigned long address); extern char *syscall32_page; +void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end); + +extern unsigned long max_mapnr; +extern unsigned long end_pfn; +extern unsigned long table_start, table_end; + struct thread_struct; +struct user_desc; int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info); int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info); diff -Nru a/include/asm-x86_64/segment.h b/include/asm-x86_64/segment.h --- a/include/asm-x86_64/segment.h Fri Feb 14 00:27:30 2003 +++ b/include/asm-x86_64/segment.h Fri Feb 14 00:27:30 2003 @@ -19,13 +19,15 @@ #define __USER_DS 0x2b /* 5*8+3 */ #define __USER_CS 0x33 /* 6*8+3 */ #define __USER32_DS __USER_DS +#define __KERNEL16_CS (GDT_ENTRY_KERNELCS16 * 8) #define GDT_ENTRY_TLS 1 #define GDT_ENTRY_TSS 8 /* needs two entries */ #define GDT_ENTRY_LDT 10 #define GDT_ENTRY_TLS_MIN 11 #define GDT_ENTRY_TLS_MAX 13 -#define GDT_ENTRY_LONGBASE 14 +/* 14 free */ +#define GDT_ENTRY_KERNELCS16 15 #define GDT_ENTRY_TLS_ENTRIES 3 diff -Nru a/include/asm-x86_64/signal.h b/include/asm-x86_64/signal.h --- a/include/asm-x86_64/signal.h Fri Feb 14 00:27:26 2003 +++ b/include/asm-x86_64/signal.h Fri Feb 14 00:27:26 2003 @@ -200,6 +200,9 @@ } #endif #endif + +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + #endif /* __KERNEL__ */ #endif diff -Nru a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h --- a/include/asm-x86_64/smp.h Fri Feb 14 00:27:26 2003 +++ b/include/asm-x86_64/smp.h Fri Feb 14 00:27:26 2003 @@ -44,7 +44,9 @@ extern void smp_send_reschedule_all(void); extern void smp_invalidate_rcv(void); /* Process an NMI */ extern void (*mtrr_hook) (void); -extern void zap_low_mappings (void); +extern void zap_low_mappings(void); + +#define SMP_TRAMPOLINE_BASE 0x6000 /* * On x86 all CPUs are mapped 1:1 to the APIC space. @@ -55,38 +57,26 @@ extern volatile unsigned long cpu_callout_map; #define cpu_possible(cpu) (cpu_callout_map & (1<<(cpu))) +#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) -extern inline int cpu_logical_map(int cpu) -{ - return cpu; -} -extern inline int cpu_number_map(int cpu) -{ - return cpu; -} +#define for_each_cpu(cpu, mask) \ + for(mask = cpu_online_map; \ + cpu = __ffs(mask), mask != 0; \ + mask &= ~(1UL<> (cpu+1); - if (!left) return -1; - return ffz(~left) + cpu; } -extern inline int find_first_cpu(void) +extern inline unsigned int num_online_cpus(void) { - return ffz(~cpu_online_map); + return hweight32(cpu_online_map); } -/* RED-PEN different from i386 */ -#define for_each_cpu(i) \ - for((i) = find_first_cpu(); (i)>=0; (i)=find_next_cpu(i)) - static inline int num_booting_cpus(void) { return hweight32(cpu_callout_map); @@ -94,28 +84,25 @@ extern volatile unsigned long cpu_callout_map; -/* - * Some lowlevel functions might want to know about - * the real APIC ID <-> CPU # mapping. - */ -extern volatile int x86_apicid_to_cpu[NR_CPUS]; -extern volatile int x86_cpu_to_apicid[NR_CPUS]; - -/* - * This function is needed by all SMP systems. It must _always_ be valid - * from the initial startup. We map APIC_BASE very early in page_setup(), - * so this is correct in the x86 case. - */ - #define smp_processor_id() read_pda(cpunumber) - extern __inline int hard_smp_processor_id(void) { /* we don't want to mark this access volatile - bad code generation */ return GET_APIC_ID(*(unsigned int *)(APIC_BASE+APIC_ID)); } +extern int disable_apic; +extern int slow_smp_processor_id(void); + +extern inline int safe_smp_processor_id(void) +{ + if (disable_apic) + return slow_smp_processor_id(); + else + return hard_smp_processor_id(); +} + #define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) #endif /* !ASSEMBLY */ @@ -128,6 +115,7 @@ #ifndef CONFIG_SMP #define stack_smp_processor_id() 0 +#define safe_smp_processor_id() 0 #define for_each_cpu(x) (x)=0; #define cpu_logical_map(x) (x) #else @@ -135,7 +123,7 @@ #define stack_smp_processor_id() \ ({ \ struct thread_info *ti; \ - __asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (~8191UL)); \ + __asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK)); \ ti->cpu; \ }) #endif diff -Nru a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h --- a/include/asm-x86_64/spinlock.h Fri Feb 14 00:27:30 2003 +++ b/include/asm-x86_64/spinlock.h Fri Feb 14 00:27:30 2003 @@ -15,7 +15,7 @@ typedef struct { volatile unsigned int lock; -#if CONFIG_DEBUG_SPINLOCK +#ifdef CONFIG_DEBUG_SPINLOCK unsigned magic; #endif } spinlock_t; @@ -56,13 +56,56 @@ /* * This works. Despite all the confusion. + * (except on PPro SMP or if we are using OOSTORE) + * (PPro errata 66, 92) */ + +#if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE) + #define spin_unlock_string \ - "movb $1,%0" + "movb $1,%0" \ + :"=m" (lock->lock) : : "memory" + + +static inline void _raw_spin_unlock(spinlock_t *lock) +{ +#ifdef CONFIG_DEBUG_SPINLOCK + if (lock->magic != SPINLOCK_MAGIC) + BUG(); + if (!spin_is_locked(lock)) + BUG(); +#endif + __asm__ __volatile__( + spin_unlock_string + ); +} + +#else + +#define spin_unlock_string \ + "xchgb %b0, %1" \ + :"=q" (oldval), "=m" (lock->lock) \ + :"0" (oldval) : "memory" + +static inline void _raw_spin_unlock(spinlock_t *lock) +{ + char oldval = 1; +#ifdef CONFIG_DEBUG_SPINLOCK + if (lock->magic != SPINLOCK_MAGIC) + BUG(); + if (!spin_is_locked(lock)) + BUG(); +#endif + __asm__ __volatile__( + spin_unlock_string + ); +} + +#endif static inline int _raw_spin_trylock(spinlock_t *lock) { - signed char oldval; + char oldval; __asm__ __volatile__( "xchgb %b0,%1" :"=q" (oldval), "=m" (lock->lock) @@ -85,18 +128,6 @@ :"=m" (lock->lock) : : "memory"); } -static inline void _raw_spin_unlock(spinlock_t *lock) -{ -#ifdef CONFIG_DEBUG_SPINLOCK - if (lock->magic != SPINLOCK_MAGIC) - BUG(); - if (!spin_is_locked(lock)) - BUG(); -#endif - __asm__ __volatile__( - spin_unlock_string - :"=m" (lock->lock) : : "memory"); -} /* * Read-write spinlocks, allowing multiple readers @@ -127,6 +158,8 @@ #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0) +#define rwlock_is_locked(x) ((x)->lock != RW_LOCK_BIAS) + /* * On x86, we implement read-write locks as a 32-bit counter * with the high bit (sign) being the "contended" bit. @@ -136,9 +169,9 @@ * Changed to use the same technique as rw semaphores. See * semaphore.h for details. -ben */ -/* the spinlock helpers are in arch/x86_64/kernel/semaphore.S */ +/* the spinlock helpers are in arch/i386/kernel/semaphore.c */ -extern inline void _raw_read_lock(rwlock_t *rw) +static inline void _raw_read_lock(rwlock_t *rw) { #ifdef CONFIG_DEBUG_SPINLOCK if (rw->magic != RWLOCK_MAGIC) @@ -167,7 +200,5 @@ atomic_add(RW_LOCK_BIAS, count); return 0; } - -#define rwlock_is_locked(x) ((x)->lock != RW_LOCK_BIAS) #endif /* __ASM_SPINLOCK_H */ diff -Nru a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h --- a/include/asm-x86_64/system.h Fri Feb 14 00:27:29 2003 +++ b/include/asm-x86_64/system.h Fri Feb 14 00:27:29 2003 @@ -83,7 +83,7 @@ #define loadsegment(seg,value) \ asm volatile("\n" \ "1:\t" \ - "movl %0,%%" #seg "\n" \ + "movl %k0,%%" #seg "\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ "3:\t" \ @@ -94,7 +94,7 @@ ".align 8\n\t" \ ".quad 1b,3b\n" \ ".previous" \ - : :"r" ((int)(value))) + : :"r" (value)) #define set_debug(value,register) \ __asm__("movq %0,%%db" #register \ @@ -117,6 +117,13 @@ static inline void write_cr0(unsigned long val) { asm volatile("movq %0,%%cr0" :: "r" (val)); +} + +static inline unsigned long read_cr3(void) +{ + unsigned long cr3; + asm("movq %%cr3,%0" : "=r" (cr3)); + return cr3; } static inline unsigned long read_cr4(void) diff -Nru a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h --- a/include/asm-x86_64/thread_info.h Fri Feb 14 00:27:29 2003 +++ b/include/asm-x86_64/thread_info.h Fri Feb 14 00:27:29 2003 @@ -9,11 +9,8 @@ #ifdef __KERNEL__ -#ifndef __ASSEMBLY__ -#include -#include -#include -#endif +#include +#include /* * low level task data that entry.S needs immediate access to @@ -21,6 +18,10 @@ * - this struct shares the supervisor stack pages */ #ifndef __ASSEMBLY__ +struct task_struct; +struct exec_domain; +#include + struct thread_info { struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ @@ -31,7 +32,6 @@ mm_segment_t addr_limit; struct restart_block restart_block; }; - #endif /* @@ -55,27 +55,17 @@ #define init_thread_info (init_thread_union.thread_info) #define init_stack (init_thread_union.stack) -/* how to get the thread information struct from C */ - -#define THREAD_SIZE (2*PAGE_SIZE) - static inline struct thread_info *current_thread_info(void) { struct thread_info *ti; - ti = (void *)read_pda(kernelstack) + PDA_STACKOFFSET - THREAD_SIZE; - return ti; -} - -static inline struct thread_info *stack_thread_info(void) -{ - struct thread_info *ti; - __asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (~8191UL)); + asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK)); return ti; } /* thread information allocation */ -#define alloc_thread_info() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) -#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) +#define alloc_thread_info() \ + ((struct thread_info *) __get_free_pages(GFP_KERNEL,THREAD_ORDER)) +#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER) #define get_thread_info(ti) get_task_struct((ti)->task) #define put_thread_info(ti) put_task_struct((ti)->task) @@ -84,7 +74,7 @@ /* how to get the thread information struct from ASM */ /* only works on the process stack. otherwise get it via the PDA. */ #define GET_THREAD_INFO(reg) \ - movq $-8192, reg; \ + movq $CURRENT_MASK, reg; \ andq %rsp, reg #endif diff -Nru a/include/asm-x86_64/timex.h b/include/asm-x86_64/timex.h --- a/include/asm-x86_64/timex.h Fri Feb 14 00:27:28 2003 +++ b/include/asm-x86_64/timex.h Fri Feb 14 00:27:28 2003 @@ -1,7 +1,7 @@ /* - * linux/include/asm-x8664/timex.h + * linux/include/asm-x86_64/timex.h * - * x8664 architecture timex specifications + * x86-64 architecture timex specifications */ #ifndef _ASMx8664_TIMEX_H #define _ASMx8664_TIMEX_H @@ -16,20 +16,6 @@ (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \ << (SHIFT_SCALE-SHIFT_HZ)) / HZ) -/* - * Standard way to access the cycle counter on i586+ CPUs. - * Currently only used on SMP. - * - * If you really have a SMP machine with i486 chips or older, - * compile for that, and this will just always return zero. - * That's ok, it just means that the nicer scheduling heuristics - * won't work for you. - * - * We only use the low 32 bits, and we'd simply better make sure - * that we reschedule before that wraps. Scheduling at least every - * four billion cycles just basically sounds like a good idea, - * regardless of how fast the machine is. - */ typedef unsigned long long cycles_t; extern cycles_t cacheflush_time; diff -Nru a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h --- a/include/asm-x86_64/topology.h Fri Feb 14 00:27:29 2003 +++ b/include/asm-x86_64/topology.h Fri Feb 14 00:27:29 2003 @@ -1,6 +1,26 @@ #ifndef _ASM_X86_64_TOPOLOGY_H #define _ASM_X86_64_TOPOLOGY_H +#include + +#ifdef CONFIG_DISCONTIGMEM + +/* Map the K8 CPU local memory controllers to a simple 1:1 CPU:NODE topology */ + +extern int fake_node; +extern unsigned long cpu_online_map; + +#define cpu_to_node(cpu) (fake_node ? 0 : (cpu)) +#define memblk_to_node(memblk) (fake_node ? 0 : (memblk)) +#define parent_node(node) (node) +#define node_to_first_cpu(node) (fake_node ? 0 : (node)) +#define node_to_cpu_mask(node) (fake_node ? cpu_online_map : (1UL << (node))) +#define node_to_memblk(node) (node) + +#define NODE_BALANCE_RATE 30 /* CHECKME */ + +#endif + #include -#endif /* _ASM_X86_64_TOPOLOGY_H */ +#endif diff -Nru a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h --- a/include/asm-x86_64/unistd.h Fri Feb 14 00:27:29 2003 +++ b/include/asm-x86_64/unistd.h Fri Feb 14 00:27:29 2003 @@ -500,8 +500,10 @@ __SYSCALL(__NR_restart_syscall, sys_restart_syscall) #define __NR_semtimedop 220 __SYSCALL(__NR_semtimedop, sys_semtimedop) +#define __NR_fadvise64 221 +__SYSCALL(__NR_fadvise64, sys_fadvise64) -#define __NR_syscall_max __NR_semtimedop +#define __NR_syscall_max __NR_fadvise64 #ifndef __NO_STUBS /* user-visible error numbers are in the range -1 - -4095 */ diff -Nru a/include/asm-x86_64/vsyscall.h b/include/asm-x86_64/vsyscall.h --- a/include/asm-x86_64/vsyscall.h Fri Feb 14 00:27:30 2003 +++ b/include/asm-x86_64/vsyscall.h Fri Feb 14 00:27:30 2003 @@ -2,6 +2,7 @@ #define _ASM_X86_64_VSYSCALL_H_ #include +#include enum vsyscall_num { __NR_vgettimeofday, @@ -19,8 +20,10 @@ #define __section_wall_jiffies __attribute__ ((unused, __section__ (".wall_jiffies"), aligned(16))) #define __section_jiffies __attribute__ ((unused, __section__ (".jiffies"), aligned(16))) #define __section_sys_tz __attribute__ ((unused, __section__ (".sys_tz"), aligned(16))) +#define __section_sysctl_vsyscall __attribute__ ((unused, __section__ (".sysctl_vsyscall"), aligned(16))) #define __section_xtime __attribute__ ((unused, __section__ (".xtime"), aligned(16))) -#define __section_vxtime_sequence __attribute__ ((unused, __section__ (".vxtime_sequence"), aligned(16))) +#define __section_xtime_lock __attribute__ ((unused, __section__ (".xtime_lock"), aligned(L1_CACHE_BYTES))) + struct hpet_data { long address; /* base address */ @@ -36,21 +39,21 @@ #define hpet_writel(d,a) writel(d, fix_to_virt(FIX_HPET_BASE) + a) /* vsyscall space (readonly) */ -extern long __vxtime_sequence[2]; extern struct hpet_data __hpet; extern struct timespec __xtime; extern volatile unsigned long __jiffies; extern unsigned long __wall_jiffies; extern struct timezone __sys_tz; +extern seqlock_t __xtime_lock; /* kernel space (writeable) */ -extern long vxtime_sequence[2]; extern struct hpet_data hpet; extern unsigned long wall_jiffies; extern struct timezone sys_tz; +extern int sysctl_vsyscall; +extern seqlock_t xtime_lock; -#define vxtime_lock() do { vxtime_sequence[0]++; wmb(); } while(0) -#define vxtime_unlock() do { wmb(); vxtime_sequence[1]++; } while (0) +#define ARCH_HAVE_XTIME_LOCK 1 #endif /* __KERNEL__ */ diff -Nru a/include/linux/agp_backend.h b/include/linux/agp_backend.h --- a/include/linux/agp_backend.h Fri Feb 14 00:27:29 2003 +++ b/include/linux/agp_backend.h Fri Feb 14 00:27:29 2003 @@ -53,17 +53,6 @@ INTEL_460GX, INTEL_I7505, VIA_GENERIC, - VIA_VP3, - VIA_MVP3, - VIA_MVP4, - VIA_APOLLO_PRO, - VIA_APOLLO_KX133, - VIA_APOLLO_KT133, - VIA_APOLLO_KT400, - VIA_APOLLO_KT400_3, - VIA_APOLLO_PRO_266, - VIA_VT8605, - VIA_P4X, SIS_GENERIC, AMD_GENERIC, AMD_IRONGATE, @@ -84,6 +73,7 @@ SVWRKS_LE, SVWRKS_GENERIC, HP_ZX1, + ALPHA_CORE_AGP, }; struct agp_version { @@ -102,6 +92,7 @@ int current_memory; int cant_use_aperture; unsigned long page_mask; + struct vm_operations_struct *vm_ops; } agp_kern_info; /* diff -Nru a/include/linux/buffer_head.h b/include/linux/buffer_head.h --- a/include/linux/buffer_head.h Fri Feb 14 00:27:26 2003 +++ b/include/linux/buffer_head.h Fri Feb 14 00:27:26 2003 @@ -169,6 +169,7 @@ void free_buffer_head(struct buffer_head * bh); void FASTCALL(unlock_buffer(struct buffer_head *bh)); void ll_rw_block(int, int, struct buffer_head * bh[]); +void sync_dirty_buffer(struct buffer_head *bh); int submit_bh(int, struct buffer_head *); void write_boundary_block(struct block_device *bdev, sector_t bblock, unsigned blocksize); diff -Nru a/include/linux/cpufreq.h b/include/linux/cpufreq.h --- a/include/linux/cpufreq.h Fri Feb 14 00:27:28 2003 +++ b/include/linux/cpufreq.h Fri Feb 14 00:27:28 2003 @@ -2,10 +2,10 @@ * linux/include/linux/cpufreq.h * * Copyright (C) 2001 Russell King - * (C) 2002 Dominik Brodowski + * (C) 2002 - 2003 Dominik Brodowski * * - * $Id: cpufreq.h,v 1.29 2002/11/11 15:35:47 db Exp $ + * $Id: cpufreq.h,v 1.36 2003/01/20 17:31:48 db Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -20,6 +20,9 @@ #include +#define CPUFREQ_NAME_LEN 16 + + /********************************************************************* * CPUFREQ NOTIFIER INTERFACE * *********************************************************************/ @@ -37,14 +40,17 @@ #define CPUFREQ_POLICY_POWERSAVE (1) #define CPUFREQ_POLICY_PERFORMANCE (2) +#define CPUFREQ_POLICY_GOVERNOR (3) /* Frequency values here are CPU kHz so that hardware which doesn't run * with some frequencies can complain without having to guess what per * cent / per mille means. - * Maximum transition latency is in nanoseconds - if it's unknown, + * Maximum transition latency is in microseconds - if it's unknown, * CPUFREQ_ETERNAL shall be used. */ +struct cpufreq_governor; + #define CPUFREQ_ETERNAL (-1) struct cpufreq_cpuinfo { unsigned int max_freq; @@ -57,6 +63,7 @@ unsigned int min; /* in kHz */ unsigned int max; /* in kHz */ unsigned int policy; /* see above */ + struct cpufreq_governor *governor; /* see below */ struct cpufreq_cpuinfo cpuinfo; /* see above */ struct intf_data intf; /* interface data */ }; @@ -104,25 +111,62 @@ return carry + val; }; +/********************************************************************* + * CPUFREQ GOVERNORS * + *********************************************************************/ + +#define CPUFREQ_GOV_START 1 +#define CPUFREQ_GOV_STOP 2 +#define CPUFREQ_GOV_LIMITS 3 + +struct cpufreq_governor { + char name[CPUFREQ_NAME_LEN]; + int (*governor) (struct cpufreq_policy *policy, + unsigned int event); + struct list_head governor_list; + struct module *owner; +}; + +/* pass a target to the cpufreq driver + * _l : (cpufreq_driver_sem is not held) + */ +inline int cpufreq_driver_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation); + +inline int cpufreq_driver_target_l(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation); + +/* pass an event to the cpufreq governor */ +int cpufreq_governor_l(unsigned int cpu, unsigned int event); + +int cpufreq_register_governor(struct cpufreq_governor *governor); +void cpufreq_unregister_governor(struct cpufreq_governor *governor); /********************************************************************* * CPUFREQ DRIVER INTERFACE * *********************************************************************/ -#define CPUFREQ_NAME_LEN 16 +#define CPUFREQ_RELATION_L 0 /* lowest frequency at or above target */ +#define CPUFREQ_RELATION_H 1 /* highest frequency below or at target */ struct cpufreq_driver { /* needed by all drivers */ - int (*verify) (struct cpufreq_policy *policy); - int (*setpolicy) (struct cpufreq_policy *policy); - struct cpufreq_policy *policy; - char name[CPUFREQ_NAME_LEN]; + int (*verify) (struct cpufreq_policy *policy); + struct cpufreq_policy *policy; + char name[CPUFREQ_NAME_LEN]; + /* define one out of two */ + int (*setpolicy) (struct cpufreq_policy *policy); + int (*target) (struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation); /* optional, for the moment */ - int (*init) (struct cpufreq_policy *policy); - int (*exit) (struct cpufreq_policy *policy); + int (*init) (struct cpufreq_policy *policy); + int (*exit) (struct cpufreq_policy *policy); /* 2.4. compatible API */ #ifdef CONFIG_CPU_FREQ_24_API - unsigned int cpu_cur_freq[NR_CPUS]; + unsigned int cpu_cur_freq[NR_CPUS]; #endif }; @@ -275,5 +319,11 @@ int cpufreq_frequency_table_setpolicy(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table, unsigned int *index); + +int cpufreq_frequency_table_target(struct cpufreq_policy *policy, + struct cpufreq_frequency_table *table, + unsigned int target_freq, + unsigned int relation, + unsigned int *index); #endif /* _LINUX_CPUFREQ_H */ diff -Nru a/include/linux/eventpoll.h b/include/linux/eventpoll.h --- a/include/linux/eventpoll.h Fri Feb 14 00:27:28 2003 +++ b/include/linux/eventpoll.h Fri Feb 14 00:27:28 2003 @@ -32,10 +32,10 @@ /* Kernel space functions implementing the user space "epoll" API */ -asmlinkage int sys_epoll_create(int size); -asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); -asmlinkage int sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents, - int timeout); +asmlinkage long sys_epoll_create(int size); +asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); +asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents, + int timeout); /* Used to initialize the epoll bits inside the "struct file" */ void eventpoll_init_file(struct file *file); diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h --- a/include/linux/ext3_jbd.h Fri Feb 14 00:27:27 2003 +++ b/include/linux/ext3_jbd.h Fri Feb 14 00:27:27 2003 @@ -210,14 +210,6 @@ return journal_start(journal, nblocks); } -static inline handle_t * -ext3_journal_try_start(struct inode *inode, int nblocks) -{ - if (inode->i_sb->s_flags & MS_RDONLY) - return ERR_PTR(-EROFS); - return journal_try_start(EXT3_JOURNAL(inode), nblocks); -} - /* * The only special thing we need to do here is to make sure that all * journal_stop calls result in the superblock being marked dirty, so diff -Nru a/include/linux/hfs_sysdep.h b/include/linux/hfs_sysdep.h --- a/include/linux/hfs_sysdep.h Fri Feb 14 00:27:27 2003 +++ b/include/linux/hfs_sysdep.h Fri Feb 14 00:27:27 2003 @@ -155,13 +155,8 @@ } static inline void hfs_buffer_sync(hfs_buffer buffer) { - while (buffer_locked(buffer)) { - wait_on_buffer(buffer); - } - if (buffer_dirty(buffer)) { - ll_rw_block(WRITE, 1, &buffer); - wait_on_buffer(buffer); - } + if (buffer_dirty(buffer)) + sync_dirty_buffer(buffer); } static inline void *hfs_buffer_data(const hfs_buffer buffer) { diff -Nru a/include/linux/hiddev.h b/include/linux/hiddev.h --- a/include/linux/hiddev.h Fri Feb 14 00:27:27 2003 +++ b/include/linux/hiddev.h Fri Feb 14 00:27:27 2003 @@ -204,7 +204,7 @@ int hiddev_connect(struct hid_device *); void hiddev_disconnect(struct hid_device *); void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value); + struct hid_usage *usage, __s32 value, struct pt_regs *regs); void hiddev_report_event(struct hid_device *hid, struct hid_report *report); int __init hiddev_init(void); void __exit hiddev_exit(void); @@ -212,7 +212,7 @@ static inline int hiddev_connect(struct hid_device *hid) { return -1; } static inline void hiddev_disconnect(struct hid_device *hid) { } static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) { } + struct hid_usage *usage, __s32 value, struct pt_regs *regs) { } static inline void hiddev_report_event(struct hid_device *hid, struct hid_report *report) { } static inline int hiddev_init(void) { return 0; } static inline void hiddev_exit(void) { } diff -Nru a/include/linux/hugetlb.h b/include/linux/hugetlb.h --- a/include/linux/hugetlb.h Fri Feb 14 00:27:28 2003 +++ b/include/linux/hugetlb.h Fri Feb 14 00:27:28 2003 @@ -26,6 +26,7 @@ unsigned long address); struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, pmd_t *pmd, int write); +int is_aligned_hugepage_range(unsigned long addr, unsigned long len); int pmd_huge(pmd_t pmd); extern int htlbpage_max; @@ -56,6 +57,7 @@ #define hugepage_vma(mm, addr) 0 #define mark_mm_hugetlb(mm, vma) do { } while (0) #define follow_huge_pmd(mm, addr, pmd, write) 0 +#define is_aligned_hugepage_range(addr, len) 0 #define pmd_huge(x) 0 #ifndef HPAGE_MASK diff -Nru a/include/linux/input.h b/include/linux/input.h --- a/include/linux/input.h Fri Feb 14 00:27:28 2003 +++ b/include/linux/input.h Fri Feb 14 00:27:28 2003 @@ -774,6 +774,7 @@ struct timer_list timer; struct pm_dev *pm_dev; + struct pt_regs *regs; int state; int sync; @@ -899,12 +900,14 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); -#define input_sync(a) input_event(a, EV_SYN, SYN_REPORT, 0) #define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c)) #define input_report_rel(a,b,c) input_event(a, EV_REL, b, c) #define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c) #define input_report_ff(a,b,c) input_event(a, EV_FF, b, c) #define input_report_ff_status(a,b,c) input_event(a, EV_FF_STATUS, b, c) + +#define input_regs(a,b) do { (a)->regs = (b); } while (0) +#define input_sync(a) do { input_event(a, EV_SYN, SYN_REPORT, 0); (a)->regs = NULL; } while (0) extern struct device_class input_devclass; diff -Nru a/include/linux/jbd.h b/include/linux/jbd.h --- a/include/linux/jbd.h Fri Feb 14 00:27:29 2003 +++ b/include/linux/jbd.h Fri Feb 14 00:27:29 2003 @@ -726,7 +726,6 @@ */ extern handle_t *journal_start(journal_t *, int nblocks); -extern handle_t *journal_try_start(journal_t *, int nblocks); extern int journal_restart (handle_t *, int nblocks); extern int journal_extend (handle_t *, int nblocks); extern int journal_get_write_access (handle_t *, struct buffer_head *); diff -Nru a/include/linux/jiffies.h b/include/linux/jiffies.h --- a/include/linux/jiffies.h Fri Feb 14 00:27:26 2003 +++ b/include/linux/jiffies.h Fri Feb 14 00:27:26 2003 @@ -15,24 +15,14 @@ extern u64 jiffies_64; extern unsigned long volatile jiffies; +#if (BITS_PER_LONG < 64) +u64 get_jiffies_64(void); +#else static inline u64 get_jiffies_64(void) { -#if BITS_PER_LONG < 64 - extern seqlock_t xtime_lock; - unsigned long seq; - u64 tmp; - - do { - seq = read_seqbegin(&xtime_lock); - tmp = jiffies_64; - } while (read_seqretry(&xtime_lock, seq)); - - return tmp; -#else return (u64)jiffies; -#endif } - +#endif /* * These inlines deal with timer wrapping correctly. You are diff -Nru a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h --- a/include/linux/kbd_kern.h Fri Feb 14 00:27:29 2003 +++ b/include/linux/kbd_kern.h Fri Feb 14 00:27:29 2003 @@ -43,11 +43,12 @@ #define LED_SHOW_IOCTL 1 /* only change leds upon ioctl */ #define LED_SHOW_MEM 2 /* `heartbeat': peek into memory */ - unsigned char ledflagstate:3; /* flags, not lights */ - unsigned char default_ledflagstate:3; + unsigned char ledflagstate:4; /* flags, not lights */ + unsigned char default_ledflagstate:4; #define VC_SCROLLOCK 0 /* scroll-lock mode */ #define VC_NUMLOCK 1 /* numeric lock mode */ #define VC_CAPSLOCK 2 /* capslock mode */ +#define VC_KANALOCK 3 /* kanalock mode */ unsigned char kbdmode:2; /* one 2-bit value */ #define VC_XLATE 0 /* translate keycodes using keymap */ diff -Nru a/include/linux/keyboard.h b/include/linux/keyboard.h --- a/include/linux/keyboard.h Fri Feb 14 00:27:27 2003 +++ b/include/linux/keyboard.h Fri Feb 14 00:27:27 2003 @@ -9,6 +9,7 @@ #define KG_ALT 3 #define KG_ALTGR 1 #define KG_SHIFTL 4 +#define KG_KANASHIFT 4 #define KG_SHIFTR 5 #define KG_CTRLL 6 #define KG_CTRLR 7 diff -Nru a/include/linux/oprofile.h b/include/linux/oprofile.h --- a/include/linux/oprofile.h Fri Feb 14 00:27:28 2003 +++ b/include/linux/oprofile.h Fri Feb 14 00:27:28 2003 @@ -21,14 +21,6 @@ struct dentry; struct file_operations; -enum oprofile_cpu { - OPROFILE_CPU_PPRO, - OPROFILE_CPU_PII, - OPROFILE_CPU_PIII, - OPROFILE_CPU_ATHLON, - OPROFILE_CPU_TIMER -}; - /* Operations structure to be filled in */ struct oprofile_operations { /* create any necessary configuration files in the oprofile fs. @@ -42,20 +34,23 @@ int (*start)(void); /* Stop delivering interrupts. */ void (*stop)(void); + /* CPU identification string. */ + char * cpu_type; }; /** * One-time initialisation. *ops must be set to a filled-in - * operations structure. oprofile_cpu_type must be set. + * operations structure. * Return 0 on success. */ -int oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu); +int oprofile_arch_init(struct oprofile_operations ** ops); /** * Add a sample. This may be called from any context. Pass * smp_processor_id() as cpu. */ -extern void oprofile_add_sample(unsigned long eip, unsigned long event, int cpu); +extern void oprofile_add_sample(unsigned long eip, unsigned int is_kernel, + unsigned long event, int cpu); /** * Create a file of the given name as a child of the given root, with @@ -79,6 +74,12 @@ /** create a directory */ struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root, char const * name); + +/** + * Write the given asciz string to the given user buffer @buf, updating *offset + * appropriately. Returns bytes written or -EFAULT. + */ +ssize_t oprofilefs_str_to_user(char const * str, char * buf, size_t count, loff_t * offset); /** * Convert an unsigned long value into ASCII and copy it to the user buffer @buf, diff -Nru a/include/linux/pc_keyb.h b/include/linux/pc_keyb.h --- a/include/linux/pc_keyb.h Fri Feb 14 00:27:28 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,130 +0,0 @@ -/* - * include/linux/pc_keyb.h - * - * PC Keyboard And Keyboard Controller - * - * (c) 1997 Martin Mares - */ - -/* - * Configuration Switches - */ - -#undef KBD_REPORT_ERR /* Report keyboard errors */ -#define KBD_REPORT_UNKN /* Report unknown scan codes */ -#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */ -#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */ -#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */ - - - -#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */ -#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ -#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */ - -/* - * Internal variables of the driver - */ - -extern unsigned char pckbd_read_mask; -extern unsigned char aux_device_present; - -/* - * Keyboard Controller Registers on normal PCs. - */ - -#define KBD_STATUS_REG 0x64 /* Status register (R) */ -#define KBD_CNTL_REG 0x64 /* Controller command register (W) */ -#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ - -/* - * Keyboard Controller Commands - */ - -#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */ -#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ -#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */ -#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */ -#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */ -#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */ -#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */ -#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */ -#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */ -#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */ -#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if - initiated by the auxiliary device */ -#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */ - -/* - * Keyboard Commands - */ - -#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ -#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ -#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ -#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */ -#define KBD_CMD_RESET 0xFF /* Reset */ - -/* - * Keyboard Replies - */ - -#define KBD_REPLY_POR 0xAA /* Power on reset */ -#define KBD_REPLY_ACK 0xFA /* Command ACK */ -#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ - -/* - * Status Register Bits - */ - -#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ -#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ -#define KBD_STAT_SELFTEST 0x04 /* Self test successful */ -#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */ -#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */ -#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ -#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */ -#define KBD_STAT_PERR 0x80 /* Parity error */ - -#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF) - -/* - * Controller Mode Register Bits - */ - -#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */ -#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */ -#define KBD_MODE_SYS 0x04 /* The system flag (?) */ -#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */ -#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */ -#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */ -#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */ -#define KBD_MODE_RFU 0x80 - -/* - * Mouse Commands - */ - -#define AUX_SET_RES 0xE8 /* Set resolution */ -#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ -#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ -#define AUX_GET_SCALE 0xE9 /* Get scaling factor */ -#define AUX_SET_STREAM 0xEA /* Set stream mode */ -#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ -#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ -#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ -#define AUX_RESET 0xFF /* Reset aux device */ -#define AUX_ACK 0xFA /* Command byte ACK. */ - -#define AUX_BUF_SIZE 2048 /* This might be better divisible by - three to make overruns stay in sync - but then the read function would need - a lock etc - ick */ - -struct aux_queue { - unsigned long head; - unsigned long tail; - wait_queue_head_t proc_list; - struct fasync_struct *fasync; - unsigned char buf[AUX_BUF_SIZE]; -}; diff -Nru a/include/linux/sched.h b/include/linux/sched.h --- a/include/linux/sched.h Fri Feb 14 00:27:27 2003 +++ b/include/linux/sched.h Fri Feb 14 00:27:27 2003 @@ -509,6 +509,7 @@ /* per-UID process charging. */ extern struct user_struct * alloc_uid(uid_t); extern void free_uid(struct user_struct *); +extern void switch_uid(struct user_struct *); #include @@ -529,7 +530,7 @@ extern void proc_caches_init(void); extern void flush_signals(struct task_struct *); extern void flush_signal_handlers(struct task_struct *); -extern int dequeue_signal(sigset_t *mask, siginfo_t *info); +extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info); extern void block_all_signals(int (*notifier)(void *priv), void *priv, sigset_t *mask); extern void unblock_all_signals(void); @@ -615,7 +616,8 @@ extern NORET_TYPE void do_group_exit(int); extern void reparent_to_init(void); -extern void daemonize(void); +extern void daemonize(const char *, ...); +extern int allow_signal(int); extern task_t *child_reaper; extern int do_execve(char *, char **, char **, struct pt_regs *); diff -Nru a/include/linux/serio.h b/include/linux/serio.h --- a/include/linux/serio.h Fri Feb 14 00:27:28 2003 +++ b/include/linux/serio.h Fri Feb 14 00:27:28 2003 @@ -10,10 +10,13 @@ */ #include -#include #define SPIOCSTYPE _IOW('q', 0x01, unsigned long) +#ifdef __KERNEL__ + +#include + struct serio; struct serio { @@ -47,7 +50,7 @@ char *name; void (*write_wakeup)(struct serio *); - void (*interrupt)(struct serio *, unsigned char, unsigned int); + void (*interrupt)(struct serio *, unsigned char, unsigned int, struct pt_regs *); void (*connect)(struct serio *, struct serio_dev *dev); void (*disconnect)(struct serio *); void (*cleanup)(struct serio *); @@ -58,7 +61,7 @@ int serio_open(struct serio *serio, struct serio_dev *dev); void serio_close(struct serio *serio); void serio_rescan(struct serio *serio); -void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags); +void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs); void serio_register_port(struct serio *serio); void serio_unregister_port(struct serio *serio); @@ -85,6 +88,8 @@ serio->dev->cleanup(serio); } +#endif + /* * bit masks for use in "interrupt" flags (3rd argument) */ @@ -122,6 +127,8 @@ #define SERIO_TWIDKBD 0x23 #define SERIO_TWIDJOY 0x24 #define SERIO_HIL 0x25 +#define SERIO_SNES232 0x26 +#define SERIO_SEMTECH 0x27 #define SERIO_ID 0xff00UL #define SERIO_EXTRA 0xff0000UL diff -Nru a/include/linux/signal.h b/include/linux/signal.h --- a/include/linux/signal.h Fri Feb 14 00:27:27 2003 +++ b/include/linux/signal.h Fri Feb 14 00:27:27 2003 @@ -208,7 +208,7 @@ #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER struct pt_regs; -extern int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs); +extern int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs, void *cookie); #endif #endif /* __KERNEL__ */ diff -Nru a/include/linux/spinlock.h b/include/linux/spinlock.h --- a/include/linux/spinlock.h Fri Feb 14 00:27:28 2003 +++ b/include/linux/spinlock.h Fri Feb 14 00:27:28 2003 @@ -179,6 +179,7 @@ #define _raw_read_unlock(lock) do { (void)(lock); } while(0) #define _raw_write_lock(lock) do { (void)(lock); } while(0) #define _raw_write_unlock(lock) do { (void)(lock); } while(0) +#define _raw_write_trylock(lock) ({ (void)(lock); (1); }) #endif /* !SMP */ diff -Nru a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h --- a/include/linux/sunrpc/clnt.h Fri Feb 14 00:27:28 2003 +++ b/include/linux/sunrpc/clnt.h Fri Feb 14 00:27:28 2003 @@ -79,6 +79,7 @@ unsigned int nrvers; /* number of versions */ struct rpc_version ** version; /* version array */ struct rpc_stat * stats; /* statistics */ + char * pipe_dir_name; /* path to rpc_pipefs dir */ }; struct rpc_version { diff -Nru a/include/net/af_unix.h b/include/net/af_unix.h --- a/include/net/af_unix.h Fri Feb 14 00:27:29 2003 +++ b/include/net/af_unix.h Fri Feb 14 00:27:29 2003 @@ -13,9 +13,30 @@ extern atomic_t unix_tot_inflight; +static inline unix_socket *first_unix_socket(int *i) +{ + for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) { + if (unix_socket_table[*i]) + return unix_socket_table[*i]; + } + return NULL; +} -#define forall_unix_sockets(i, s) for (i=0; i<=UNIX_HASH_SIZE; i++) \ - for (s=unix_socket_table[i]; s; s=s->next) +static inline unix_socket *next_unix_socket(int *i, unix_socket *s) +{ + /* More in this chain? */ + if (s->next) + return s->next; + /* Look for next non-empty chain. */ + for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) { + if (unix_socket_table[*i]) + return unix_socket_table[*i]; + } + return NULL; +} + +#define forall_unix_sockets(i, s) \ + for (s = first_unix_socket(&(i)); s; s = next_unix_socket(&(i),(s))) struct unix_address { diff -Nru a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h --- a/include/net/irda/irda_device.h Fri Feb 14 00:27:30 2003 +++ b/include/net/irda/irda_device.h Fri Feb 14 00:27:30 2003 @@ -173,12 +173,33 @@ __u8 *head; /* start of buffer */ __u8 *data; /* start of data in buffer */ - __u8 *tail; /* end of data in buffer */ - int len; /* length of data */ - int truesize; /* total size of buffer */ + int len; /* current length of data */ + int truesize; /* total allocated size of buffer */ __u16 fcs; + + struct sk_buff *skb; /* ZeroCopy Rx in async_unwrap_char() */ } iobuff_t; + +/* Maximum SIR frame (skb) that we expect to receive *unwrapped*. + * Max LAP MTU (I field) is 2048 bytes max (IrLAP 1.1, chapt 6.6.5, p40). + * Max LAP header is 2 bytes (for now). + * Max CRC is 2 bytes at SIR, 4 bytes at FIR. + * Need 1 byte for skb_reserve() to align IP header for IrLAN. + * Add a few extra bytes just to be safe (buffer is power of two anyway) + * Jean II */ +#define IRDA_SKB_MAX_MTU 2064 +/* Maximum SIR frame that we expect to send, wrapped (i.e. with XBOFS + * and escaped characters on top of above). */ +#define IRDA_SIR_MAX_FRAME 4269 + +/* The SIR unwrapper async_unwrap_char() will use a Rx-copy-break mechanism + * when using the optional ZeroCopy Rx, where only small frames are memcpy + * to a smaller skb to save memory. This is the thresold under which copy + * will happen (and over which it won't happen). + * Some FIR drivers may use this #define as well... + * This is the same value as various Ethernet drivers. - Jean II */ +#define IRDA_RX_COPY_THRESHOLD 256 /* Function prototypes */ int irda_device_init(void); diff -Nru a/include/net/irda/wrapper.h b/include/net/irda/wrapper.h --- a/include/net/irda/wrapper.h Fri Feb 14 00:27:28 2003 +++ b/include/net/irda/wrapper.h Fri Feb 14 00:27:28 2003 @@ -52,8 +52,6 @@ /* Proto definitions */ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize); -void async_bump(struct net_device *dev, struct net_device_stats *stats, - __u8 *buf, int len); void async_unwrap_char(struct net_device *dev, struct net_device_stats *stats, iobuff_t *buf, __u8 byte); diff -Nru a/include/net/sctp/command.h b/include/net/sctp/command.h --- a/include/net/sctp/command.h Fri Feb 14 00:27:30 2003 +++ b/include/net/sctp/command.h Fri Feb 14 00:27:30 2003 @@ -1,34 +1,34 @@ /* SCTP kernel reference Implementation Copyright (C) 1999-2001 * Cisco, Motorola, and IBM - * + * * This file is part of the SCTP kernel reference Implementation - * + * * These are the definitions needed for the command object. - * - * The SCTP reference implementation is free software; - * you can redistribute it and/or modify it under the terms of + * + * The SCTP reference implementation is free software; + * you can redistribute it and/or modify it under the terms of * the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. - * - * the SCTP reference implementation is distributed in the hope that it + * + * the SCTP reference implementation is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied * ************************ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with GNU CC; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * + * Boston, MA 02111-1307, USA. + * * Please send any bug reports or fixes you make to one of the * following email addresses: - * + * * La Monte H.P. Yarroll * Karl Knutson * Ardelle Fan - * + * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. */ @@ -69,11 +69,11 @@ SCTP_CMD_INIT_FAILED, /* High level, do init failure work. */ SCTP_CMD_REPORT_DUP, /* Report a duplicate TSN. */ SCTP_CMD_REPORT_BIGGAP, /* Narc on a TSN (it was too high). */ - SCTP_CMD_SET_BIND_ADDR, /* Set the association bind_addr. */ SCTP_CMD_STRIKE, /* Mark a strike against a transport. */ SCTP_CMD_TRANSMIT, /* Transmit the outqueue. */ - SCTP_CMD_HB_TIMERS_START, /* Start the heartbeat timers. */ - SCTP_CMD_HB_TIMERS_UPDATE, /* Update the heartbeat timers. */ + SCTP_CMD_HB_TIMERS_START, /* Start the heartbeat timers. */ + SCTP_CMD_HB_TIMER_UPDATE, /* Update a heartbeat timers. */ + SCTP_CMD_HB_TIMERS_STOP, /* Stop the heartbeat timers. */ SCTP_CMD_TRANSPORT_RESET, /* Reset the status of a transport. */ SCTP_CMD_TRANSPORT_ON, /* Mark the transport as active. */ SCTP_CMD_REPORT_ERROR, /* Pass this error back out of the sm. */ @@ -112,7 +112,7 @@ void *ptr; sctp_chunk_t *chunk; sctp_association_t *asoc; - sctp_transport_t *transport; + struct sctp_transport *transport; sctp_bind_addr_t *bp; sctp_init_chunk_t *init; sctp_ulpevent_t *ulpevent; @@ -160,7 +160,7 @@ SCTP_ARG_CONSTRUCTOR(PTR, void *, ptr) SCTP_ARG_CONSTRUCTOR(CHUNK, sctp_chunk_t *, chunk) SCTP_ARG_CONSTRUCTOR(ASOC, sctp_association_t *, asoc) -SCTP_ARG_CONSTRUCTOR(TRANSPORT, sctp_transport_t *, transport) +SCTP_ARG_CONSTRUCTOR(TRANSPORT, struct sctp_transport *, transport) SCTP_ARG_CONSTRUCTOR(BA, sctp_bind_addr_t *, bp) SCTP_ARG_CONSTRUCTOR(PEER_INIT, sctp_init_chunk_t *, init) SCTP_ARG_CONSTRUCTOR(ULPEVENT, sctp_ulpevent_t *, ulpevent) diff -Nru a/include/net/sctp/constants.h b/include/net/sctp/constants.h --- a/include/net/sctp/constants.h Fri Feb 14 00:27:27 2003 +++ b/include/net/sctp/constants.h Fri Feb 14 00:27:27 2003 @@ -3,33 +3,33 @@ * Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001-2002 International Business Machines Corp. - * + * * This file is part of the SCTP kernel reference Implementation - * + * * This file is part of the implementation of the add-IP extension, * based on June 29, 2001, * for the SCTP kernel reference Implementation. - * - * The SCTP reference implementation is free software; - * you can redistribute it and/or modify it under the terms of + * + * The SCTP reference implementation is free software; + * you can redistribute it and/or modify it under the terms of * the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. - * - * the SCTP reference implementation is distributed in the hope that it + * + * the SCTP reference implementation is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty * ************************ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with GNU CC; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * + * Boston, MA 02111-1307, USA. + * * Please send any bug reports or fixes you make to one of the following email * addresses: - * + * * La Monte H.P. Yarroll * Karl Knutson * Randall Stewart @@ -38,14 +38,14 @@ * Xingang Guo * Sridhar Samudrala * Daisy Chang - * + * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. - * + * * There are still LOTS of bugs in this code... I always run on the motto * "it is a wonder any code ever works :)" - * - * + * + * */ #ifndef __sctp_constants_h__ @@ -56,17 +56,10 @@ #include /* For ipv6hdr. */ #include -/* What a hack! Jiminy Cricket! */ -enum { SCTP_MAX_STREAM = 10 }; - -/* Define the amount of space to reserve for SCTP, IP, LL. - * There is a little bit of waste that we are always allocating - * for ipv6 headers, but this seems worth the simplicity. - */ - -#define SCTP_IP_OVERHEAD ((sizeof(struct sctphdr)\ - + sizeof(struct ipv6hdr)\ - + MAX_HEADER)) +/* Value used for stream negotiation. */ +enum { SCTP_MAX_STREAM = 0xffff }; +enum { SCTP_DEFAULT_OUTSTREAMS = 10 }; +enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM }; /* Define the amount of space to reserve for SCTP, IP, LL. * There is a little bit of waste that we are always allocating @@ -105,57 +98,37 @@ */ typedef enum { - SCTP_EVENT_TIMEOUT_NONE = 0, SCTP_EVENT_TIMEOUT_T1_COOKIE, SCTP_EVENT_TIMEOUT_T1_INIT, SCTP_EVENT_TIMEOUT_T2_SHUTDOWN, SCTP_EVENT_TIMEOUT_T3_RTX, - SCTP_EVENT_TIMEOUT_T4_RTO, SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD, SCTP_EVENT_TIMEOUT_HEARTBEAT, SCTP_EVENT_TIMEOUT_SACK, SCTP_EVENT_TIMEOUT_AUTOCLOSE, - SCTP_EVENT_TIMEOUT_PMTU_RAISE, - } sctp_event_timeout_t; -#define SCTP_EVENT_TIMEOUT_MAX SCTP_EVENT_TIMEOUT_PMTU_RAISE +#define SCTP_EVENT_TIMEOUT_MAX SCTP_EVENT_TIMEOUT_AUTOCLOSE #define SCTP_NUM_TIMEOUT_TYPES (SCTP_EVENT_TIMEOUT_MAX + 1) typedef enum { - SCTP_EVENT_NO_PENDING_TSN = 0, - SCTP_EVENT_ICMP_UNREACHFRAG, - } sctp_event_other_t; -#define SCTP_EVENT_OTHER_MAX SCTP_EVENT_ICMP_UNREACHFRAG +#define SCTP_EVENT_OTHER_MAX SCTP_EVENT_NO_PENDING_TSN #define SCTP_NUM_OTHER_TYPES (SCTP_EVENT_OTHER_MAX + 1) /* These are primitive requests from the ULP. */ typedef enum { - - SCTP_PRIMITIVE_INITIALIZE = 0, - SCTP_PRIMITIVE_ASSOCIATE, + SCTP_PRIMITIVE_ASSOCIATE = 0, SCTP_PRIMITIVE_SHUTDOWN, SCTP_PRIMITIVE_ABORT, SCTP_PRIMITIVE_SEND, - SCTP_PRIMITIVE_SETPRIMARY, - SCTP_PRIMITIVE_RECEIVE, - SCTP_PRIMITIVE_STATUS, - SCTP_PRIMITIVE_CHANGEHEARTBEAT, SCTP_PRIMITIVE_REQUESTHEARTBEAT, - SCTP_PRIMITIVE_GETSRTTREPORT, - SCTP_PRIMITIVE_SETFAILURETHRESHOLD, - SCTP_PRIMITIVE_SETPROTOPARAMETERS, - SCTP_PRIMITIVE_RECEIVE_UNSENT, - SCTP_PRIMITIVE_RECEIVE_UNACKED, - SCTP_PRIMITIVE_DESTROY, - } sctp_event_primitive_t; -#define SCTP_EVENT_PRIMITIVE_MAX SCTP_PRIMITIVE_DESTROY +#define SCTP_EVENT_PRIMITIVE_MAX SCTP_PRIMITIVE_REQUESTHEARTBEAT #define SCTP_NUM_PRIMITIVE_TYPES (SCTP_EVENT_PRIMITIVE_MAX + 1) /* We define here a utility type for manipulating subtypes. @@ -268,8 +241,13 @@ #define SCTP_ADDR_REACHABLE 2 #define SCTP_ADDR_NOT_REACHABLE 1 +/* Maximum chunk length considering padding requirements. */ +enum { SCTP_MAX_CHUNK_LEN = ((1<<16) - sizeof(__u32)) }; - +/* Encourage Cookie-Echo bundling by pre-fragmenting chunks a little + * harder (until reaching ESTABLISHED state). + */ +enum { SCTP_ARBITRARY_COOKIE_ECHO_LEN = 200 }; /* Guess at how big to make the TSN mapping array. * We guarantee that we can handle at least this big a gap between the @@ -289,7 +267,8 @@ * is enough room for 131 duplicate reports. Round down to the * nearest power of 2. */ -#define SCTP_MAX_DUP_TSNS 128 +enum { SCTP_MIN_PMTU = 576 }; +enum { SCTP_MAX_DUP_TSNS = 128 }; typedef enum { SCTP_COUNTER_INIT_ERROR, @@ -298,7 +277,6 @@ /* How many counters does an association need? */ #define SCTP_NUMBER_COUNTERS 5 - /* Here we define the default timers. */ /* cookie timer def = ? seconds */ @@ -317,10 +295,6 @@ #define SCTP_DEFAULT_TIMEOUT_SACK ((200 * HZ) / 1000) #define SCTP_DEFAULT_TIMEOUT_SACK_MAX ((500 * HZ) / 1000) /* 500 ms */ -/* How long do we wait before attempting to raise the PMTU? */ -#define SCTP_DEFAULT_TIMEOUT_PMTU_RAISE (10 * 60 * HZ) /* 10 Minutes */ -#define SCTP_DEFAULT_TIMEOUT_PMTU_RAISE_MIN (10 * 60 * HZ) /* 10 Minutes */ - /* RTO.Initial - 3 seconds * RTO.Min - 1 second * RTO.Max - 60 seconds @@ -439,6 +413,13 @@ #define SCTP_ADDR6_PEERSUPP 0x00000004 /* IPv6 address is supported by peer */ +/* Reasons to retransmit. */ +typedef enum { + SCTP_RETRANSMIT_T3_RTX, + SCTP_RETRANSMIT_FAST_RTX, + SCTP_RETRANSMIT_PMTU_DISCOVERY, +} sctp_retransmit_reason_t; + /* Reasons to lower cwnd. */ typedef enum { SCTP_LOWER_CWND_T3_RTX, @@ -448,4 +429,3 @@ } sctp_lower_cwnd_t; #endif /* __sctp_constants_h__ */ - diff -Nru a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h --- a/include/net/sctp/sctp.h Fri Feb 14 00:27:27 2003 +++ b/include/net/sctp/sctp.h Fri Feb 14 00:27:27 2003 @@ -1,8 +1,8 @@ /* SCTP kernel reference Implementation * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001-2002 International Business Machines, Corp. - * Copyright (c) 2001 Intel Corp. + * Copyright (c) 2001-2003 International Business Machines, Corp. + * Copyright (c) 2001-2003 Intel Corp. * * This file is part of the SCTP kernel reference Implementation * @@ -36,7 +36,9 @@ * La Monte H.P. Yarroll * Xingang Guo * Jon Grimm - * Daisy Chang + * Daisy Chang + * Sridhar Samudrala + * Ardelle Fan * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -147,7 +149,9 @@ /* * sctp_crc32c.c */ -extern __u32 count_crc(__u8 *ptr, __u16 count); +extern __u32 sctp_start_cksum(__u8 *ptr, __u16 count); +extern __u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 cksum); +extern __u32 sctp_end_cksum(__u32 cksum); /* * sctp_input.c @@ -162,6 +166,9 @@ extern void __sctp_hash_endpoint(sctp_endpoint_t *); extern void sctp_unhash_endpoint(sctp_endpoint_t *); extern void __sctp_unhash_endpoint(sctp_endpoint_t *); +extern sctp_association_t *__sctp_lookup_association(const union sctp_addr *, + const union sctp_addr *, + struct sctp_transport **); /* * sctp_hashdriver.c @@ -266,6 +273,7 @@ extern atomic_t sctp_dbg_objcnt_chunk; extern atomic_t sctp_dbg_objcnt_bind_addr; extern atomic_t sctp_dbg_objcnt_addr; +extern atomic_t sctp_dbg_objcnt_ssnmap; /* Macros to atomically increment/decrement objcnt counters. */ #define SCTP_DBG_OBJCNT_INC(name) \ @@ -416,6 +424,23 @@ } return retval; +} + +/* Generate a random jitter in the range of -50% ~ +50% of input RTO. */ +static inline __s32 sctp_jitter(__u32 rto) +{ + static __u32 sctp_rand; + __s32 ret; + + sctp_rand += jiffies; + sctp_rand ^= (sctp_rand << 12); + sctp_rand ^= (sctp_rand >> 20); + + /* Choose random number from 0 to rto, then move to -50% ~ +50% + * of rto. + */ + ret = sctp_rand % rto - (rto >> 1); + return ret; } /* Walk through a list of TLV parameters. Don't trust the diff -Nru a/include/net/sctp/sm.h b/include/net/sctp/sm.h --- a/include/net/sctp/sm.h Fri Feb 14 00:27:28 2003 +++ b/include/net/sctp/sm.h Fri Feb 14 00:27:28 2003 @@ -256,7 +256,7 @@ const sctp_chunk_t *, const struct msghdr *); sctp_chunk_t *sctp_make_heartbeat(const sctp_association_t *, - const sctp_transport_t *, + const struct sctp_transport *, const void *payload, const size_t paylen); sctp_chunk_t *sctp_make_heartbeat_ack(const sctp_association_t *, @@ -269,6 +269,11 @@ const void *payload, size_t paylen); void sctp_chunk_assign_tsn(sctp_chunk_t *); +void sctp_chunk_assign_ssn(sctp_chunk_t *); +int sctp_datachunks_from_user(sctp_association_t *, + const struct sctp_sndrcvinfo *, + struct msghdr *, int len, + struct sk_buff_head *); /* Prototypes for statetable processing. */ diff -Nru a/include/net/sctp/structs.h b/include/net/sctp/structs.h --- a/include/net/sctp/structs.h Fri Feb 14 00:27:30 2003 +++ b/include/net/sctp/structs.h Fri Feb 14 00:27:30 2003 @@ -42,7 +42,7 @@ * Sridhar Samudrala * Daisy Chang * Dajiang Zhang - * Ardelle Fan + * Ardelle Fan * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -104,27 +104,26 @@ /* Forward declarations for data structures. */ -struct SCTP_protocol; +struct sctp_protocol; struct SCTP_endpoint; struct SCTP_association; -struct SCTP_transport; +struct sctp_transport; struct SCTP_packet; struct SCTP_chunk; struct SCTP_inqueue; -struct SCTP_outqueue; +struct sctp_outq; struct SCTP_bind_addr; +struct sctp_ulpq; struct sctp_opt; struct sctp_endpoint_common; +struct sctp_ssnmap; - -typedef struct SCTP_protocol sctp_protocol_t; +typedef struct sctp_protocol sctp_protocol_t; typedef struct SCTP_endpoint sctp_endpoint_t; typedef struct SCTP_association sctp_association_t; -typedef struct SCTP_transport sctp_transport_t; typedef struct SCTP_packet sctp_packet_t; typedef struct SCTP_chunk sctp_chunk_t; typedef struct SCTP_inqueue sctp_inqueue_t; -typedef struct SCTP_outqueue sctp_outqueue_t; typedef struct SCTP_bind_addr sctp_bind_addr_t; typedef struct sctp_opt sctp_opt_t; typedef struct sctp_endpoint_common sctp_endpoint_common_t; @@ -133,7 +132,6 @@ #include #include - /* Structures useful for managing bind/connect. */ typedef struct sctp_bind_bucket { @@ -157,7 +155,7 @@ /* The SCTP protocol structure. */ -struct SCTP_protocol { +struct sctp_protocol { /* RFC2960 Section 14. Suggested SCTP Protocol Parameter Values * * The following protocol parameters are RECOMMENDED: @@ -183,8 +181,8 @@ /* Valid.Cookie.Life - 60 seconds */ int valid_cookie_life; - - /* Whether Cookie Preservative is enabled(1) or not(0) */ + + /* Whether Cookie Preservative is enabled(1) or not(0) */ int cookie_preserve_enable; /* Association.Max.Retrans - 10 attempts @@ -239,7 +237,9 @@ * (i.e. things that depend on the address family.) */ struct sctp_af { - int (*queue_xmit) (struct sk_buff *skb); + int (*sctp_xmit) (struct sk_buff *skb, + struct sctp_transport *, + int ipfragok); int (*setsockopt) (struct sock *sk, int level, int optname, @@ -250,12 +250,18 @@ int optname, char *optval, int *optlen); - struct dst_entry *(*get_dst) (union sctp_addr *daddr, + struct dst_entry *(*get_dst) (sctp_association_t *asoc, + union sctp_addr *daddr, union sctp_addr *saddr); + void (*get_saddr) (sctp_association_t *asoc, + struct dst_entry *dst, + union sctp_addr *daddr, + union sctp_addr *saddr); void (*copy_addrlist) (struct list_head *, struct net_device *); void (*dst_saddr) (union sctp_addr *saddr, - struct dst_entry *dst); + struct dst_entry *dst, + unsigned short port); int (*cmp_addr) (const union sctp_addr *addr1, const union sctp_addr *addr2); void (*addr_copy) (union sctp_addr *dst, @@ -282,7 +288,7 @@ int sctp_register_af(struct sctp_af *); /* Protocol family functions. */ -typedef struct sctp_pf { +struct sctp_pf { void (*event_msgname)(sctp_ulpevent_t *, char *, int *); void (*skb_msgname) (struct sk_buff *, char *, int *); int (*af_supported) (sa_family_t); @@ -291,7 +297,7 @@ struct sctp_opt *); int (*bind_verify) (struct sctp_opt *, union sctp_addr *); struct sctp_af *af; -} sctp_pf_t; +}; /* SCTP Socket type: UDP or TCP style. */ typedef enum { @@ -318,7 +324,7 @@ __u32 autoclose; __u8 nodelay; __u8 disable_fragments; - sctp_pf_t *pf; + struct sctp_pf *pf; }; @@ -360,7 +366,8 @@ struct timeval expiration; /* Number of inbound/outbound streams which are set - * and negotiated during the INIT process. */ + * and negotiated during the INIT process. + */ __u16 sinit_num_ostreams; __u16 sinit_max_instreams; @@ -426,6 +433,49 @@ unsigned long sent_at; } sctp_sender_hb_info_t __attribute__((packed)); +/* + * RFC 2960 1.3.2 Sequenced Delivery within Streams + * + * The term "stream" is used in SCTP to refer to a sequence of user + * messages that are to be delivered to the upper-layer protocol in + * order with respect to other messages within the same stream. This is + * in contrast to its usage in TCP, where it refers to a sequence of + * bytes (in this document a byte is assumed to be eight bits). + * ... + * + * This is the structure we use to track both our outbound and inbound + * SSN, or Stream Sequence Numbers. + */ + +struct sctp_stream { + __u16 *ssn; + unsigned int len; +}; + +struct sctp_ssnmap { + struct sctp_stream in; + struct sctp_stream out; + int malloced; +}; + +struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *, __u16, __u16); +struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int priority); +void sctp_ssnmap_free(struct sctp_ssnmap *map); +void sctp_ssnmap_clear(struct sctp_ssnmap *map); + +/* What is the current SSN number for this stream? */ +static inline __u16 sctp_ssn_peek(struct sctp_stream *stream, __u16 id) +{ + return stream->ssn[id]; +} + +/* Return the next SSN number for this stream. */ +static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id) +{ + return stream->ssn[id]++; +} + + /* RFC2960 1.4 Key Terms * * o Chunk: A unit of information within an SCTP packet, consisting of @@ -499,6 +549,7 @@ __u8 rtt_in_progress; /* Is this chunk used for RTT calculation? */ __u8 num_times_sent; /* How man times did we send this? */ __u8 has_tsn; /* Does this chunk have a TSN yet? */ + __u8 has_ssn; /* Does this chunk have a SSN yet? */ __u8 singleton; /* Was this the only chunk in the packet? */ __u8 end_of_packet; /* Was this the last chunk in the packet? */ __u8 ecn_ce_done; /* Have we processed the ECN CE bit? */ @@ -516,15 +567,13 @@ * For an outbound chunk, it tells us where we'd like it to * go. It is NULL if we have no preference. */ - sctp_transport_t *transport; + struct sctp_transport *transport; }; sctp_chunk_t *sctp_make_chunk(const sctp_association_t *, __u8 type, __u8 flags, int size); void sctp_free_chunk(sctp_chunk_t *); -sctp_chunk_t *sctp_copy_chunk(sctp_chunk_t *, int flags); void *sctp_addto_chunk(sctp_chunk_t *chunk, int len, const void *data); -int sctp_user_addto_chunk(sctp_chunk_t *chunk, int len, struct iovec *data); sctp_chunk_t *sctp_chunkify(struct sk_buff *, const sctp_association_t *, struct sock *); void sctp_init_addrs(sctp_chunk_t *, union sctp_addr *, union sctp_addr *); @@ -560,7 +609,7 @@ * The function we finally use to pass down to the next lower * layer lives in the transport structure. */ - sctp_transport_t *transport; + struct sctp_transport *transport; /* Allow a callback for getting a high priority chunk * bundled early into the packet (This is used for ECNE). @@ -575,30 +624,33 @@ /* This packet contains a COOKIE-ECHO chunk. */ int has_cookie_echo; + /* SCTP cannot fragment this packet. So let ip fragment it. */ + int ipfragok; + int malloced; }; -typedef int (sctp_outqueue_thandler_t)(sctp_outqueue_t *, void *); -typedef int (sctp_outqueue_ehandler_t)(sctp_outqueue_t *); -typedef sctp_packet_t *(sctp_outqueue_ohandler_init_t) +typedef int (sctp_outq_thandler_t)(struct sctp_outq *, void *); +typedef int (sctp_outq_ehandler_t)(struct sctp_outq *); +typedef sctp_packet_t *(sctp_outq_ohandler_init_t) (sctp_packet_t *, - sctp_transport_t *, + struct sctp_transport *, __u16 sport, __u16 dport); -typedef sctp_packet_t *(sctp_outqueue_ohandler_config_t) +typedef sctp_packet_t *(sctp_outq_ohandler_config_t) (sctp_packet_t *, __u32 vtag, int ecn_capable, sctp_packet_phandler_t *get_prepend_chunk); -typedef sctp_xmit_t (sctp_outqueue_ohandler_t)(sctp_packet_t *, +typedef sctp_xmit_t (sctp_outq_ohandler_t)(sctp_packet_t *, sctp_chunk_t *); -typedef int (sctp_outqueue_ohandler_force_t)(sctp_packet_t *); +typedef int (sctp_outq_ohandler_force_t)(sctp_packet_t *); -sctp_outqueue_ohandler_init_t sctp_packet_init; -sctp_outqueue_ohandler_config_t sctp_packet_config; -sctp_outqueue_ohandler_t sctp_packet_append_chunk; -sctp_outqueue_ohandler_t sctp_packet_transmit_chunk; -sctp_outqueue_ohandler_force_t sctp_packet_transmit; +sctp_outq_ohandler_init_t sctp_packet_init; +sctp_outq_ohandler_config_t sctp_packet_config; +sctp_outq_ohandler_t sctp_packet_append_chunk; +sctp_outq_ohandler_t sctp_packet_transmit_chunk; +sctp_outq_ohandler_force_t sctp_packet_transmit; void sctp_packet_free(sctp_packet_t *); @@ -622,7 +674,7 @@ * period. * */ -struct SCTP_transport { +struct sctp_transport { /* A list of transports. */ struct list_head transports; @@ -692,6 +744,8 @@ /* Destination */ struct dst_entry *dst; + /* Source address. */ + union sctp_addr saddr; /* When was the last time(in jiffies) that a data packet was sent on * this transport? This is used to adjust the cwnd when the transport @@ -771,24 +825,26 @@ int malloced; /* Is this structure kfree()able? */ }; -extern sctp_transport_t *sctp_transport_new(const union sctp_addr *, int); -extern sctp_transport_t *sctp_transport_init(sctp_transport_t *, - const union sctp_addr *, int); -extern void sctp_transport_set_owner(sctp_transport_t *, sctp_association_t *); -extern void sctp_transport_route(sctp_transport_t *, union sctp_addr *, - struct sctp_opt *); -extern void sctp_transport_free(sctp_transport_t *); -extern void sctp_transport_destroy(sctp_transport_t *); -extern void sctp_transport_reset_timers(sctp_transport_t *); -extern void sctp_transport_hold(sctp_transport_t *); -extern void sctp_transport_put(sctp_transport_t *); -extern void sctp_transport_update_rto(sctp_transport_t *, __u32); -extern void sctp_transport_raise_cwnd(sctp_transport_t *, __u32, __u32); -extern void sctp_transport_lower_cwnd(sctp_transport_t *, sctp_lower_cwnd_t); +struct sctp_transport *sctp_transport_new(const union sctp_addr *, int); +struct sctp_transport *sctp_transport_init(struct sctp_transport *, + const union sctp_addr *, int); +void sctp_transport_set_owner(struct sctp_transport *, sctp_association_t *); +void sctp_transport_route(struct sctp_transport *, union sctp_addr *, + struct sctp_opt *); +void sctp_transport_pmtu(struct sctp_transport *); +void sctp_transport_free(struct sctp_transport *); +void sctp_transport_destroy(struct sctp_transport *); +void sctp_transport_reset_timers(struct sctp_transport *); +void sctp_transport_hold(struct sctp_transport *); +void sctp_transport_put(struct sctp_transport *); +void sctp_transport_update_rto(struct sctp_transport *, __u32); +void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32); +void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t); +unsigned long sctp_transport_timeout(struct sctp_transport *); + /* This is the structure we use to queue packets as they come into - * SCTP. We write packets to it and read chunks from it. It handles - * fragment reassembly and chunk unbundling. + * SCTP. We write packets to it and read chunks from it. */ struct SCTP_inqueue { /* This is actually a queue of sctp_chunk_t each @@ -835,7 +891,7 @@ * * When free()'d, it empties itself out via output_handler(). */ -struct SCTP_outqueue { +struct sctp_outq { sctp_association_t *asoc; /* BUG: This really should be an array of streams. @@ -861,11 +917,11 @@ * layer. This is always SCTP_packet, but we separate the two * structures to make testing simpler. */ - sctp_outqueue_ohandler_init_t *init_output; - sctp_outqueue_ohandler_config_t *config_output; - sctp_outqueue_ohandler_t *append_output; - sctp_outqueue_ohandler_t *build_output; - sctp_outqueue_ohandler_force_t *force_output; + sctp_outq_ohandler_init_t *init_output; + sctp_outq_ohandler_config_t *config_output; + sctp_outq_ohandler_t *append_output; + sctp_outq_ohandler_t *build_output; + sctp_outq_ohandler_force_t *force_output; /* How many unackd bytes do we have in-flight? */ __u32 outstanding_bytes; @@ -877,24 +933,24 @@ int malloced; }; -sctp_outqueue_t *sctp_outqueue_new(sctp_association_t *); -void sctp_outqueue_init(sctp_association_t *, sctp_outqueue_t *); -void sctp_outqueue_teardown(sctp_outqueue_t *); -void sctp_outqueue_free(sctp_outqueue_t*); -void sctp_force_outqueue(sctp_outqueue_t *); -int sctp_push_outqueue(sctp_outqueue_t *, sctp_chunk_t *chunk); -int sctp_flush_outqueue(sctp_outqueue_t *, int); -int sctp_sack_outqueue(sctp_outqueue_t *, sctp_sackhdr_t *); -int sctp_outqueue_is_empty(const sctp_outqueue_t *); -int sctp_outqueue_set_output_handlers(sctp_outqueue_t *, - sctp_outqueue_ohandler_init_t init, - sctp_outqueue_ohandler_config_t config, - sctp_outqueue_ohandler_t append, - sctp_outqueue_ohandler_t build, - sctp_outqueue_ohandler_force_t force); -void sctp_outqueue_restart(sctp_outqueue_t *); -void sctp_retransmit(sctp_outqueue_t *, sctp_transport_t *, __u8); -void sctp_retransmit_mark(sctp_outqueue_t *, sctp_transport_t *, __u8); +struct sctp_outq *sctp_outq_new(sctp_association_t *); +void sctp_outq_init(sctp_association_t *, struct sctp_outq *); +void sctp_outq_teardown(struct sctp_outq *); +void sctp_outq_free(struct sctp_outq*); +int sctp_outq_tail(struct sctp_outq *, sctp_chunk_t *chunk); +int sctp_outq_flush(struct sctp_outq *, int); +int sctp_outq_sack(struct sctp_outq *, sctp_sackhdr_t *); +int sctp_outq_is_empty(const struct sctp_outq *); +int sctp_outq_set_output_handlers(struct sctp_outq *, + sctp_outq_ohandler_init_t init, + sctp_outq_ohandler_config_t config, + sctp_outq_ohandler_t append, + sctp_outq_ohandler_t build, + sctp_outq_ohandler_force_t force); +void sctp_outq_restart(struct sctp_outq *); +void sctp_retransmit(struct sctp_outq *, struct sctp_transport *, + sctp_retransmit_reason_t); +void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8); /* These bind address data fields common between endpoints and associations */ @@ -1027,7 +1083,7 @@ /* These are the system-wide defaults and other stuff which is * endpoint-independent. */ - sctp_protocol_t *proto; + struct sctp_protocol *proto; /* Associations: A list of current associations and mappings * to the data consumers for each association. This @@ -1066,10 +1122,7 @@ { sctp_endpoint_t *ep; - /* We are not really a list, but the list_entry() macro is - * really quite generic to find the address of an outter struct. - */ - ep = list_entry(base, sctp_endpoint_t, base); + ep = container_of(base, sctp_endpoint_t, base); return ep; } @@ -1083,7 +1136,7 @@ void sctp_endpoint_add_asoc(sctp_endpoint_t *, sctp_association_t *asoc); sctp_association_t *sctp_endpoint_lookup_assoc(const sctp_endpoint_t *ep, const union sctp_addr *paddr, - sctp_transport_t **); + struct sctp_transport **); int sctp_endpoint_is_peeled_off(sctp_endpoint_t *, const union sctp_addr *); sctp_endpoint_t *sctp_endpoint_is_match(sctp_endpoint_t *, const union sctp_addr *); @@ -1184,7 +1237,7 @@ * designate the connection we are currently using to * transmit new data and most control chunks. */ - sctp_transport_t *primary_path; + struct sctp_transport *primary_path; /* Cache the primary path address here, when we * need a an address for msg_name. @@ -1195,7 +1248,7 @@ * The path that we are currently using to * transmit new data and most control chunks. */ - sctp_transport_t *active_path; + struct sctp_transport *active_path; /* retran_path * @@ -1207,13 +1260,13 @@ * different from the last destination address to * which the DATA chunk was sent. */ - sctp_transport_t *retran_path; + struct sctp_transport *retran_path; /* Pointer to last transport I have sent on. */ - sctp_transport_t *last_sent_to; + struct sctp_transport *last_sent_to; /* This is the last transport I have recieved DATA on. */ - sctp_transport_t *last_data_from; + struct sctp_transport *last_data_from; /* * Mapping An array of bits or bytes indicating which out of @@ -1325,7 +1378,7 @@ struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES]; /* Transport to which SHUTDOWN chunk was last sent. */ - sctp_transport_t *shutdown_last_sent_to; + struct sctp_transport *shutdown_last_sent_to; /* Next TSN : The next TSN number to be assigned to a new * : DATA chunk. This is sent in the INIT or INIT @@ -1408,18 +1461,15 @@ } defaults; /* This tracks outbound ssn for a given stream. */ - __u16 ssn[SCTP_MAX_STREAM]; + struct sctp_ssnmap *ssnmap; /* All outbound chunks go through this structure. */ - sctp_outqueue_t outqueue; + struct sctp_outq outqueue; /* A smart pipe that will handle reordering and fragmentation, * as well as handle passing events up to the ULP. - * In the future, we should make this at least dynamic, if - * not also some sparse structure. */ - sctp_ulpqueue_t ulpq; - __u8 _ssnmap[sctp_ulpqueue_storage_size(SCTP_MAX_STREAM)]; + struct sctp_ulpq ulpq; /* Need to send an ECNE Chunk? */ int need_ecne; @@ -1505,7 +1555,7 @@ * * * [I really think this is EXACTLY the sort of intelligence - * which already resides in SCTP_outqueue. Please move this + * which already resides in sctp_outq. Please move this * queue and its supporting logic down there. --piggy] */ struct sk_buff_head addip_chunks; @@ -1546,10 +1596,7 @@ { sctp_association_t *asoc; - /* We are not really a list, but the list_entry() macro is - * really quite generic find the address of an outter struct. - */ - asoc = list_entry(base, sctp_association_t, base); + asoc = container_of(base, sctp_association_t, base); return asoc; } @@ -1567,24 +1614,33 @@ void sctp_association_put(sctp_association_t *); void sctp_association_hold(sctp_association_t *); -sctp_transport_t *sctp_assoc_choose_shutdown_transport(sctp_association_t *); -sctp_transport_t *sctp_assoc_lookup_paddr(const sctp_association_t *, +struct sctp_transport *sctp_assoc_choose_shutdown_transport(sctp_association_t *); +struct sctp_transport *sctp_assoc_lookup_paddr(const sctp_association_t *, const union sctp_addr *); -sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *, +struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *, const union sctp_addr *address, const int priority); -void sctp_assoc_control_transport(sctp_association_t *, sctp_transport_t *, +void sctp_assoc_control_transport(sctp_association_t *, + struct sctp_transport *, sctp_transport_cmd_t, sctp_sn_error_t); -sctp_transport_t *sctp_assoc_lookup_tsn(sctp_association_t *, __u32); -sctp_transport_t *sctp_assoc_is_match(sctp_association_t *, - const union sctp_addr *, - const union sctp_addr *); +struct sctp_transport *sctp_assoc_lookup_tsn(sctp_association_t *, __u32); +struct sctp_transport *sctp_assoc_is_match(sctp_association_t *, + const union sctp_addr *, + const union sctp_addr *); void sctp_assoc_migrate(sctp_association_t *, struct sock *); void sctp_assoc_update(sctp_association_t *dst, sctp_association_t *src); __u32 __sctp_association_get_next_tsn(sctp_association_t *); __u32 __sctp_association_get_tsn_block(sctp_association_t *, int); __u16 __sctp_association_get_next_ssn(sctp_association_t *, __u16 sid); + +void sctp_assoc_sync_pmtu(sctp_association_t *); +void sctp_assoc_rwnd_increase(sctp_association_t *, int); +void sctp_assoc_rwnd_decrease(sctp_association_t *, int); + +int sctp_assoc_set_bind_addr_from_ep(sctp_association_t *, int); +int sctp_assoc_set_bind_addr_from_cookie(sctp_association_t *, + sctp_cookie_t *, int); int sctp_cmp_addr_exact(const union sctp_addr *ss1, const union sctp_addr *ss2); diff -Nru a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h --- a/include/net/sctp/ulpqueue.h Fri Feb 14 00:27:27 2003 +++ b/include/net/sctp/ulpqueue.h Fri Feb 14 00:27:27 2003 @@ -1,39 +1,44 @@ /* SCTP kernel reference Implementation * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001 International Business Machines, Corp. + * Copyright (c) 2001-2003 International Business Machines, Corp. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 La Monte H.P. Yarroll - * - * These are the definitions needed for the sctp_ulpqueue type. The - * sctp_ulpqueue is the interface between the Upper Layer Protocol, or ULP, + * + * These are the definitions needed for the sctp_ulpq type. The + * sctp_ulpq is the interface between the Upper Layer Protocol, or ULP, * and the core SCTP state machine. This is the component which handles - * reassembly and ordering. - * - * The SCTP reference implementation is free software; - * you can redistribute it and/or modify it under the terms of + * reassembly and ordering. + * + * The SCTP reference implementation is free software; + * you can redistribute it and/or modify it under the terms of * the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. - * - * the SCTP reference implementation is distributed in the hope that it + * + * the SCTP reference implementation is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied * ************************ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with GNU CC; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Please send any bug reports or fixes you make to one of the - * following email addresses: - * - * Jon Grimm - * La Monte H.P. Yarroll - * + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email addresses: + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Written or modified by: + * Jon Grimm + * La Monte H.P. Yarroll + * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. */ @@ -42,46 +47,26 @@ #define __sctp_ulpqueue_h__ /* A structure to carry information to the ULP (e.g. Sockets API) */ -typedef struct sctp_ulpqueue { +struct sctp_ulpq { int malloced; - spinlock_t lock; sctp_association_t *asoc; struct sk_buff_head reasm; struct sk_buff_head lobby; - __u16 ssn[0]; -} sctp_ulpqueue_t; - -/* This macro assists in creation of external storage for variable length - * internal buffers. - */ -#define sctp_ulpqueue_storage_size(inbound) (sizeof(__u16) * (inbound)) - -sctp_ulpqueue_t *sctp_ulpqueue_new(sctp_association_t *asoc, - __u16 inbound, - int priority); - -sctp_ulpqueue_t *sctp_ulpqueue_init(sctp_ulpqueue_t *ulpq, - sctp_association_t *asoc, - __u16 inbound); - -void sctp_ulpqueue_free(sctp_ulpqueue_t *); +}; +/* Prototypes. */ +struct sctp_ulpq *sctp_ulpq_new(sctp_association_t *asoc, int priority); +struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *, sctp_association_t *); +void sctp_ulpq_free(struct sctp_ulpq *); /* Add a new DATA chunk for processing. */ -int sctp_ulpqueue_tail_data(sctp_ulpqueue_t *, - sctp_chunk_t *chunk, - int priority); - +int sctp_ulpq_tail_data(struct sctp_ulpq *, sctp_chunk_t *chunk, int priority); /* Add a new event for propogation to the ULP. */ -int sctp_ulpqueue_tail_event(sctp_ulpqueue_t *, - sctp_ulpevent_t *event); - +int sctp_ulpq_tail_event(struct sctp_ulpq *, struct sctp_ulpevent *ev); /* Is the ulpqueue empty. */ -int sctp_ulpqueue_is_empty(sctp_ulpqueue_t *); - -int sctp_ulpqueue_is_data_empty(sctp_ulpqueue_t *); +int sctp_ulpqueue_is_empty(struct sctp_ulpq *); #endif /* __sctp_ulpqueue_h__ */ @@ -90,4 +75,4 @@ - + diff -Nru a/include/net/sctp/user.h b/include/net/sctp/user.h --- a/include/net/sctp/user.h Fri Feb 14 00:27:26 2003 +++ b/include/net/sctp/user.h Fri Feb 14 00:27:26 2003 @@ -100,6 +100,14 @@ #define SCTP_SOCKOPT_BINDX_REM SCTP_SOCKOPT_BINDX_REM SCTP_SOCKOPT_PEELOFF, /* peel off association. */ #define SCTP_SOCKOPT_PEELOFF SCTP_SOCKOPT_PEELOFF + SCTP_GET_PEER_ADDRS_NUM, /* Get number of peer addresss. */ +#define SCTP_GET_PEER_ADDRS_NUM SCTP_GET_PEER_ADDRS_NUM + SCTP_GET_PEER_ADDRS, /* Get all peer addresss. */ +#define SCTP_GET_PEER_ADDRS SCTP_GET_PEER_ADDRS + SCTP_GET_LOCAL_ADDRS_NUM, /* Get number of local addresss. */ +#define SCTP_GET_LOCAL_ADDRS_NUM SCTP_GET_LOCAL_ADDRS_NUM + SCTP_GET_LOCAL_ADDRS, /* Get all local addresss. */ +#define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS }; @@ -576,6 +584,15 @@ __u16 ssto_streamid_end; }; +/* + * 8.3 8.5 get all peer/local addresses on a socket + * This parameter struct is for getsockopt + */ +struct sctp_getaddrs { + sctp_assoc_t assoc_id; + int addr_num; + struct sockaddr_storage *addrs; +}; /* These are bit fields for msghdr->msg_flags. See section 5.1. */ /* On user space Linux, these live in as an enum. */ diff -Nru a/include/net/xfrm.h b/include/net/xfrm.h --- a/include/net/xfrm.h Fri Feb 14 00:27:29 2003 +++ b/include/net/xfrm.h Fri Feb 14 00:27:29 2003 @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -423,5 +424,24 @@ extern struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id); extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name); extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name); + +static inline int +xfrm6_selector_match(struct xfrm_selector *sel, struct flowi *fl) +{ + return !memcmp(fl->fl6_dst, sel->daddr.a6, sizeof(struct in6_addr)) && + !((fl->uli_u.ports.dport^sel->dport)&sel->dport_mask) && + !((fl->uli_u.ports.sport^sel->sport)&sel->sport_mask) && + (fl->proto == sel->proto || !sel->proto) && + (fl->oif == sel->ifindex || !sel->ifindex) && + !memcmp(fl->fl6_src, sel->saddr.a6, sizeof(struct in6_addr)); +} + +extern int xfrm6_register_type(struct xfrm_type *type); +extern int xfrm6_unregister_type(struct xfrm_type *type); +extern struct xfrm_type *xfrm6_get_type(u8 proto); + +extern struct xfrm_state *xfrm6_state_lookup(struct in6_addr *daddr, u32 spi, u8 proto); +struct xfrm_state * xfrm6_find_acq(u8 mode, u16 reqid, u8 proto, struct in6_addr *daddr, struct in6_addr *saddr, int create); +void xfrm6_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); #endif /* _NET_XFRM_H */ diff -Nru a/kernel/cpufreq.c b/kernel/cpufreq.c --- a/kernel/cpufreq.c Fri Feb 14 00:27:27 2003 +++ b/kernel/cpufreq.c Fri Feb 14 00:27:27 2003 @@ -2,9 +2,9 @@ * linux/kernel/cpufreq.c * * Copyright (C) 2001 Russell King - * (C) 2002 Dominik Brodowski + * (C) 2002 - 2003 Dominik Brodowski * - * $Id: cpufreq.c,v 1.50 2002/11/11 15:35:48 db Exp $ + * $Id: cpufreq.c,v 1.59 2003/01/20 17:31:48 db Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -34,7 +34,6 @@ #include #endif - /** * The "cpufreq driver" - the arch- or hardware-dependend low * level driver of CPUFreq support, and its locking mutex. @@ -67,6 +66,9 @@ static unsigned int cpu_cur_freq[NR_CPUS]; #endif +LIST_HEAD(cpufreq_governor_list); + +static int cpufreq_governor(unsigned int cpu, unsigned int event); /********************************************************************* * SYSFS INTERFACE * @@ -75,16 +77,31 @@ /** * cpufreq_parse_governor - parse a governor string */ -static int cpufreq_parse_governor (char *str_governor, unsigned int *governor) +static int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor) { - if (!strnicmp(str_governor, "performance", 11)) { - *governor = CPUFREQ_POLICY_PERFORMANCE; + if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { + *policy = CPUFREQ_POLICY_PERFORMANCE; return 0; - } else if (!strnicmp(str_governor, "powersave", 9)) { - *governor = CPUFREQ_POLICY_POWERSAVE; + } else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) { + *policy = CPUFREQ_POLICY_POWERSAVE; return 0; - } else - return -EINVAL; + } else { + struct cpufreq_governor *t; + down(&cpufreq_driver_sem); + if (!cpufreq_driver || !cpufreq_driver->target) + goto out; + list_for_each_entry(t, &cpufreq_governor_list, governor_list) { + if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) { + *governor = t; + *policy = CPUFREQ_POLICY_GOVERNOR; + up(&cpufreq_driver_sem); + return 0; + } + } + out: + up(&cpufreq_driver_sem); + } + return -EINVAL; } @@ -171,6 +188,8 @@ static ssize_t show_scaling_governor (struct device *dev, char *buf) { unsigned int value = 0; + char value2[CPUFREQ_NAME_LEN]; + if (!dev) return 0; @@ -178,6 +197,8 @@ down(&cpufreq_driver_sem); if (cpufreq_driver) value = cpufreq_driver->policy[to_cpu_nr(dev)].policy; + if (value == CPUFREQ_POLICY_GOVERNOR) + strncpy(value2, cpufreq_driver->policy[to_cpu_nr(dev)].governor->name, CPUFREQ_NAME_LEN); up(&cpufreq_driver_sem); switch (value) { @@ -185,6 +206,8 @@ return sprintf(buf, "powersave\n"); case CPUFREQ_POLICY_PERFORMANCE: return sprintf(buf, "performance\n"); + case CPUFREQ_POLICY_GOVERNOR: + return sprintf(buf, "%s\n", value2); } return -EINVAL; @@ -212,7 +235,7 @@ if (ret != 1) return -EINVAL; - if (cpufreq_parse_governor(str_governor, &policy.policy)) + if (cpufreq_parse_governor(str_governor, &policy.policy, &policy.governor)) return -EINVAL; ret = cpufreq_set_policy(&policy); @@ -241,6 +264,34 @@ return sprintf(buf, "%s\n", value); } +/** + * show_available_govs - show the available CPUfreq governors + */ +static ssize_t show_available_govs(struct device *dev, char *buf) +{ + ssize_t i = 0; + struct cpufreq_governor *t; + + if (!dev) + return 0; + + i += sprintf(buf, "performance powersave"); + + down(&cpufreq_driver_sem); + if (!cpufreq_driver || !cpufreq_driver->target) + goto out; + + list_for_each_entry(t, &cpufreq_governor_list, governor_list) { + if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2))) + goto out; + i += snprintf(&buf[i], CPUFREQ_NAME_LEN, " %s", t->name); + } + out: + up(&cpufreq_driver_sem); + i += sprintf(&buf[i], "\n"); + return i; +} + /** * cpufreq_per_cpu_attr_ro - read-only cpufreq per-CPU file @@ -267,6 +318,7 @@ static DEVICE_ATTR(scaling_governor, (S_IRUGO | S_IWUSR), show_scaling_governor, store_scaling_governor); static DEVICE_ATTR(scaling_driver, S_IRUGO, show_scaling_driver, NULL); +static DEVICE_ATTR(available_scaling_governors, S_IRUGO, show_available_govs, NULL); /** @@ -299,10 +351,12 @@ } /* set default policy on this CPU */ - policy.policy = cpufreq_driver->policy[cpu].policy; - policy.min = cpufreq_driver->policy[cpu].min; - policy.max = cpufreq_driver->policy[cpu].max; - policy.cpu = cpu; + memcpy(&policy, + &cpufreq_driver->policy[cpu], + sizeof(struct cpufreq_policy)); + + if (cpufreq_driver->target) + cpufreq_governor(cpu, CPUFREQ_GOV_START); up(&cpufreq_driver_sem); ret = cpufreq_set_policy(&policy); @@ -339,6 +393,7 @@ device_create_file (dev, &dev_attr_scaling_max_freq); device_create_file (dev, &dev_attr_scaling_governor); device_create_file (dev, &dev_attr_scaling_driver); + device_create_file (dev, &dev_attr_available_scaling_governors); up(&cpufreq_driver_sem); return ret; @@ -356,6 +411,9 @@ struct device * dev = intf->dev; unsigned int cpu = to_cpu_nr(dev); + if (cpufreq_driver->target) + cpufreq_governor(cpu, CPUFREQ_GOV_STOP); + if (cpufreq_driver->exit) cpufreq_driver->exit(&cpufreq_driver->policy[cpu]); @@ -364,7 +422,8 @@ device_remove_file (dev, &dev_attr_scaling_min_freq); device_remove_file (dev, &dev_attr_scaling_max_freq); device_remove_file (dev, &dev_attr_scaling_governor); - device_remove_file (dev, &dev_attr_scaling_governor); + device_remove_file (dev, &dev_attr_scaling_driver); + device_remove_file (dev, &dev_attr_available_scaling_governors); return 0; } @@ -443,12 +502,11 @@ return -EINVAL; scan_policy: - result = cpufreq_parse_governor(str_governor, &policy->policy); + result = cpufreq_parse_governor(str_governor, &policy->policy, &policy->governor); return result; } - /** * cpufreq_proc_read - read /proc/cpufreq * @@ -477,7 +535,8 @@ if (!cpu_online(i)) continue; - cpufreq_get_policy(&policy, i); + if (cpufreq_get_policy(&policy, i)) + continue; if (!policy.cpuinfo.max_freq) continue; @@ -494,6 +553,9 @@ case CPUFREQ_POLICY_PERFORMANCE: p += sprintf(p, "performance\n"); break; + case CPUFREQ_POLICY_GOVERNOR: + p += snprintf(p, CPUFREQ_NAME_LEN, "%s\n", policy.governor->name); + break; default: p += sprintf(p, "INVALID\n"); break; @@ -1065,6 +1127,136 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier); +/********************************************************************* + * GOVERNORS * + *********************************************************************/ + +inline int cpufreq_driver_target_l(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int ret; + down(&cpufreq_driver_sem); + if (!cpufreq_driver) + ret = -EINVAL; + else + ret = cpufreq_driver->target(policy, target_freq, relation); + up(&cpufreq_driver_sem); + return ret; +} +EXPORT_SYMBOL_GPL(cpufreq_driver_target_l); + + +inline int cpufreq_driver_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + return cpufreq_driver->target(policy, target_freq, relation); +} +EXPORT_SYMBOL_GPL(cpufreq_driver_target); + + +static int cpufreq_governor(unsigned int cpu, unsigned int event) +{ + int ret = 0; + struct cpufreq_policy *policy = &cpufreq_driver->policy[cpu]; + + switch (policy->policy) { + case CPUFREQ_POLICY_POWERSAVE: + if ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_START)) + ret = cpufreq_driver->target(policy, policy->min, CPUFREQ_RELATION_L); + break; + case CPUFREQ_POLICY_PERFORMANCE: + if ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_START)) + ret = cpufreq_driver->target(policy, policy->max, CPUFREQ_RELATION_H); + break; + case CPUFREQ_POLICY_GOVERNOR: + ret = -EINVAL; + if (event == CPUFREQ_GOV_START) + if (!try_module_get(cpufreq_driver->policy[cpu].governor->owner)) + break; + ret = cpufreq_driver->policy[cpu].governor->governor(policy, event); + if ((event == CPUFREQ_GOV_STOP) || + (ret && (event == CPUFREQ_GOV_START))) + module_put(cpufreq_driver->policy[cpu].governor->owner); + break; + default: + ret = -EINVAL; + } + return ret; +} + + +int cpufreq_governor_l(unsigned int cpu, unsigned int event) +{ + int ret = 0; + down(&cpufreq_driver_sem); + ret = cpufreq_governor(cpu, event); + up(&cpufreq_driver_sem); + return ret; +} +EXPORT_SYMBOL_GPL(cpufreq_governor_l); + + +int cpufreq_register_governor(struct cpufreq_governor *governor) +{ + struct cpufreq_governor *t; + + if (!governor) + return -EINVAL; + + if (!strnicmp(governor->name,"powersave",CPUFREQ_NAME_LEN)) + return -EBUSY; + if (!strnicmp(governor->name,"performance",CPUFREQ_NAME_LEN)) + return -EBUSY; + + down(&cpufreq_driver_sem); + + list_for_each_entry(t, &cpufreq_governor_list, governor_list) { + if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) { + up(&cpufreq_driver_sem); + return -EBUSY; + } + } + list_add(&governor->governor_list, &cpufreq_governor_list); + up(&cpufreq_driver_sem); + + return 0; +} +EXPORT_SYMBOL_GPL(cpufreq_register_governor); + + +void cpufreq_unregister_governor(struct cpufreq_governor *governor) +{ + unsigned int i; + + if (!governor) + return; + + down(&cpufreq_driver_sem); + /* + * Unless the user uses rmmod -f, we can be safe. But we never + * know, so check whether if it's currently used. If so, + * stop it and replace it with the default governor. + */ + for (i=0; ipolicy[i].policy == CPUFREQ_POLICY_GOVERNOR) && + (cpufreq_driver->policy[i].governor == governor)) { + cpufreq_governor(i, CPUFREQ_GOV_STOP); + cpufreq_driver->policy[i].policy = CPUFREQ_POLICY_PERFORMANCE; + cpufreq_governor(i, CPUFREQ_GOV_START); + } + } + /* now we can safely remove it from the list */ + list_del(&governor->governor_list); + up(&cpufreq_driver_sem); + return; +} +EXPORT_SYMBOL_GPL(cpufreq_unregister_governor); + + /********************************************************************* * POLICY INTERFACE * @@ -1084,15 +1276,11 @@ up(&cpufreq_driver_sem); return -EINVAL; } - - policy->min = cpufreq_driver->policy[cpu].min; - policy->max = cpufreq_driver->policy[cpu].max; - policy->policy = cpufreq_driver->policy[cpu].policy; - policy->cpuinfo.max_freq = cpufreq_driver->policy[cpu].cpuinfo.max_freq; - policy->cpuinfo.min_freq = cpufreq_driver->policy[cpu].cpuinfo.min_freq; - policy->cpuinfo.transition_latency = cpufreq_driver->policy[cpu].cpuinfo.transition_latency; - policy->cpu = cpu; + memcpy(policy, + &cpufreq_driver->policy[cpu], + sizeof(struct cpufreq_policy)); + up(&cpufreq_driver_sem); return 0; @@ -1111,16 +1299,15 @@ int ret; down(&cpufreq_driver_sem); - if (!cpufreq_driver || !cpufreq_driver->verify || - !cpufreq_driver->setpolicy || !policy || + if (!cpufreq_driver || !policy || (policy->cpu >= NR_CPUS) || (!cpu_online(policy->cpu))) { up(&cpufreq_driver_sem); return -EINVAL; } - policy->cpuinfo.max_freq = cpufreq_driver->policy[policy->cpu].cpuinfo.max_freq; - policy->cpuinfo.min_freq = cpufreq_driver->policy[policy->cpu].cpuinfo.min_freq; - policy->cpuinfo.transition_latency = cpufreq_driver->policy[policy->cpu].cpuinfo.transition_latency; + memcpy(&policy->cpuinfo, + &cpufreq_driver->policy[policy->cpu].cpuinfo, + sizeof(struct cpufreq_cpuinfo)); /* verify the cpu speed can be set within this limit */ ret = cpufreq_driver->verify(policy); @@ -1156,13 +1343,35 @@ cpufreq_driver->policy[policy->cpu].min = policy->min; cpufreq_driver->policy[policy->cpu].max = policy->max; - cpufreq_driver->policy[policy->cpu].policy = policy->policy; #ifdef CONFIG_CPU_FREQ_24_API cpu_cur_freq[policy->cpu] = policy->max; #endif - ret = cpufreq_driver->setpolicy(policy); + if (cpufreq_driver->setpolicy) { + cpufreq_driver->policy[policy->cpu].policy = policy->policy; + ret = cpufreq_driver->setpolicy(policy); + } else { + if ((policy->policy != cpufreq_driver->policy[policy->cpu].policy) || + ((policy->policy == CPUFREQ_POLICY_GOVERNOR) && (policy->governor != cpufreq_driver->policy[policy->cpu].governor))) { + unsigned int old_pol = cpufreq_driver->policy[policy->cpu].policy; + struct cpufreq_governor *old_gov = cpufreq_driver->policy[policy->cpu].governor; + /* end old governor */ + cpufreq_governor(policy->cpu, CPUFREQ_GOV_STOP); + cpufreq_driver->policy[policy->cpu].policy = policy->policy; + cpufreq_driver->policy[policy->cpu].governor = policy->governor; + /* start new governor */ + if (cpufreq_governor(policy->cpu, CPUFREQ_GOV_START)) { + cpufreq_driver->policy[policy->cpu].policy = old_pol; + cpufreq_driver->policy[policy->cpu].governor = old_gov; + cpufreq_governor(policy->cpu, CPUFREQ_GOV_START); + } + /* might be a policy change, too */ + cpufreq_governor(policy->cpu, CPUFREQ_GOV_LIMITS); + } else { + cpufreq_governor(policy->cpu, CPUFREQ_GOV_LIMITS); + } + } up(&cpufreq_driver_sem); @@ -1253,7 +1462,7 @@ return -EBUSY; if (!driver_data || !driver_data->verify || - !driver_data->setpolicy) + ((!driver_data->setpolicy) && (!driver_data->target))) return -EINVAL; down(&cpufreq_driver_sem); @@ -1271,6 +1480,7 @@ up(&cpufreq_driver_sem); return -ENOMEM; } + memset(cpufreq_driver->policy, 0, NR_CPUS * sizeof(struct cpufreq_policy)); } up(&cpufreq_driver_sem); @@ -1359,11 +1569,8 @@ up(&cpufreq_driver_sem); return 0; } - - policy.min = cpufreq_driver->policy[i].min; - policy.max = cpufreq_driver->policy[i].max; - policy.policy = cpufreq_driver->policy[i].policy; - policy.cpu = i; + + memcpy(&policy, &cpufreq_driver->policy[i], sizeof(struct cpufreq_policy)); up(&cpufreq_driver_sem); ret += cpufreq_set_policy(&policy); @@ -1493,3 +1700,73 @@ return 0; } EXPORT_SYMBOL_GPL(cpufreq_frequency_table_setpolicy); + +int cpufreq_frequency_table_target(struct cpufreq_policy *policy, + struct cpufreq_frequency_table *table, + unsigned int target_freq, + unsigned int relation, + unsigned int *index) +{ + struct cpufreq_frequency_table optimal = { .index = ~0, }; + struct cpufreq_frequency_table suboptimal = { .index = ~0, }; + unsigned int i; + + switch (relation) { + case CPUFREQ_RELATION_H: + optimal.frequency = 0; + suboptimal.frequency = ~0; + break; + case CPUFREQ_RELATION_L: + optimal.frequency = ~0; + suboptimal.frequency = 0; + break; + } + + if (!cpu_online(policy->cpu)) + return -EINVAL; + + for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { + unsigned int freq = table[i].frequency; + if (freq == CPUFREQ_ENTRY_INVALID) + continue; + if ((freq < policy->min) || (freq > policy->max)) + continue; + switch(relation) { + case CPUFREQ_RELATION_H: + if (freq <= target_freq) { + if (freq >= optimal.frequency) { + optimal.frequency = freq; + optimal.index = i; + } + } else { + if (freq <= suboptimal.frequency) { + suboptimal.frequency = freq; + suboptimal.index = i; + } + } + break; + case CPUFREQ_RELATION_L: + if (freq >= target_freq) { + if (freq <= optimal.frequency) { + optimal.frequency = freq; + optimal.index = i; + } + } else { + if (freq >= suboptimal.frequency) { + suboptimal.frequency = freq; + suboptimal.index = i; + } + } + break; + } + } + if (optimal.index > i) { + if (suboptimal.index > i) + return -EINVAL; + *index = suboptimal.index; + } else + *index = optimal.index; + + return 0; +} +EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); diff -Nru a/kernel/exit.c b/kernel/exit.c --- a/kernel/exit.c Fri Feb 14 00:27:30 2003 +++ b/kernel/exit.c Fri Feb 14 00:27:30 2003 @@ -249,7 +249,7 @@ /* signals? */ security_task_reparent_to_init(current); memcpy(current->rlim, init_task.rlim, sizeof(*(current->rlim))); - current->user = INIT_USER; + switch_uid(INIT_USER); write_unlock_irq(&tasklist_lock); } @@ -278,14 +278,38 @@ } /* + * Let kernel threads use this to say that they + * allow a certain signal (since daemonize() will + * have disabled all of them by default). + */ +int allow_signal(int sig) +{ + if (sig < 1 || sig > _NSIG) + return -EINVAL; + + spin_lock_irq(¤t->sighand->siglock); + sigdelset(¤t->blocked, sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + return 0; +} + +EXPORT_SYMBOL(allow_signal); + +/* * Put all the gunge required to become a kernel thread without * attached user resources in one place where it belongs. */ -void daemonize(void) +void daemonize(const char *name, ...) { + va_list args; struct fs_struct *fs; + sigset_t blocked; + va_start(args, name); + vsnprintf(current->comm, sizeof(current->comm), name, args); + va_end(args); /* * If we were started as result of loading a module, close all of the @@ -296,6 +320,11 @@ set_special_pids(1, 1); current->tty = NULL; + + /* Block and flush all signals */ + sigfillset(&blocked); + sigprocmask(SIG_BLOCK, &blocked, NULL); + flush_signals(current); /* Become as one with the init task */ diff -Nru a/kernel/kmod.c b/kernel/kmod.c --- a/kernel/kmod.c Fri Feb 14 00:27:27 2003 +++ b/kernel/kmod.c Fri Feb 14 00:27:27 2003 @@ -110,10 +110,10 @@ as the super user right after the execve fails if you time the signal just right. */ - spin_lock_irq(&curtask->sighand->siglock); - sigemptyset(&curtask->blocked); flush_signals(curtask); flush_signal_handlers(curtask); + spin_lock_irq(&curtask->sighand->siglock); + sigemptyset(&curtask->blocked); recalc_sigpending(); spin_unlock_irq(&curtask->sighand->siglock); @@ -121,15 +121,7 @@ if (curtask->files->fd[i]) close(i); } - /* Drop the "current user" thing */ - { - struct user_struct *user = curtask->user; - curtask->user = INIT_USER; - atomic_inc(&INIT_USER->__count); - atomic_inc(&INIT_USER->processes); - atomic_dec(&user->processes); - free_uid(user); - } + switch_uid(INIT_USER); /* Give kmod all effective privileges.. */ curtask->euid = curtask->fsuid = 0; diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c --- a/kernel/ksyms.c Fri Feb 14 00:27:26 2003 +++ b/kernel/ksyms.c Fri Feb 14 00:27:26 2003 @@ -208,6 +208,7 @@ EXPORT_SYMBOL(__brelse); EXPORT_SYMBOL(__bforget); EXPORT_SYMBOL(ll_rw_block); +EXPORT_SYMBOL(sync_dirty_buffer); EXPORT_SYMBOL(submit_bh); EXPORT_SYMBOL(unlock_buffer); EXPORT_SYMBOL(__wait_on_buffer); @@ -489,6 +490,9 @@ EXPORT_SYMBOL(xtime_lock); EXPORT_SYMBOL(do_gettimeofday); EXPORT_SYMBOL(do_settimeofday); +#if (BITS_PER_LONG < 64) +EXPORT_SYMBOL(get_jiffies_64); +#endif #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP EXPORT_SYMBOL(__might_sleep); #endif diff -Nru a/kernel/pm.c b/kernel/pm.c --- a/kernel/pm.c Fri Feb 14 00:27:27 2003 +++ b/kernel/pm.c Fri Feb 14 00:27:27 2003 @@ -24,6 +24,7 @@ #include #include #include +#include int pm_active; @@ -292,3 +293,41 @@ EXPORT_SYMBOL(pm_send_all); EXPORT_SYMBOL(pm_find); EXPORT_SYMBOL(pm_active); + + +#ifdef CONFIG_MAGIC_SYSRQ + +/** + * handle_poweroff - sysrq callback for power down + * @key: key pressed (unused) + * @pt_regs: register state (unused) + * @kbd: keyboard state (unused) + * @tty: tty involved (unused) + * + * When the user hits Sys-Rq o to power down the machine this is the + * callback we use. + */ + +static void handle_poweroff (int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + if (pm_power_off) + pm_power_off(); +} + +static struct sysrq_key_op sysrq_poweroff_op = { + .handler = handle_poweroff, + .help_msg = "powerOff", + .action_msg = "Power Off\n" +}; + +#endif /* CONFIG_MAGIC_SYSRQ */ + + +static int pm_init(void) +{ + register_sysrq_key('o', &sysrq_poweroff_op); + return 0; +} + +subsys_initcall(pm_init); diff -Nru a/kernel/ptrace.c b/kernel/ptrace.c --- a/kernel/ptrace.c Fri Feb 14 00:27:30 2003 +++ b/kernel/ptrace.c Fri Feb 14 00:27:30 2003 @@ -351,4 +351,9 @@ set_current_state(TASK_STOPPED); notify_parent(current, SIGCHLD); schedule(); + + /* + * Signals sent while we were stopped might set TIF_SIGPENDING. + */ + recalc_sigpending(); } diff -Nru a/kernel/sched.c b/kernel/sched.c --- a/kernel/sched.c Fri Feb 14 00:27:29 2003 +++ b/kernel/sched.c Fri Feb 14 00:27:29 2003 @@ -506,7 +506,8 @@ */ void wake_up_forked_process(task_t * p) { - runqueue_t *rq = this_rq_lock(); + unsigned long flags; + runqueue_t *rq = task_rq_lock(current, &flags); p->state = TASK_RUNNING; if (!rt_task(p)) { @@ -522,7 +523,7 @@ set_task_cpu(p, smp_processor_id()); activate_task(p, rq); - rq_unlock(rq); + task_rq_unlock(rq, &flags); } /* @@ -2245,8 +2246,7 @@ runqueue_t *rq; int ret; - daemonize(); - sigfillset(¤t->blocked); + daemonize("migration/%d", cpu); set_fs(KERNEL_DS); /* @@ -2259,8 +2259,6 @@ rq = this_rq(); rq->migration_thread = current; - - sprintf(current->comm, "migration/%d", smp_processor_id()); for (;;) { runqueue_t *rq_src, *rq_dest; diff -Nru a/kernel/signal.c b/kernel/signal.c --- a/kernel/signal.c Fri Feb 14 00:27:28 2003 +++ b/kernel/signal.c Fri Feb 14 00:27:28 2003 @@ -141,14 +141,34 @@ (((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) && \ ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN)) -#define sig_ignored(t, signr) \ - (!((t)->ptrace & PT_PTRACED) && \ - (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_IGN) - #define sig_fatal(t, signr) \ (!T(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \ (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL) +static inline int sig_ignored(struct task_struct *t, int sig) +{ + void * handler; + + /* + * Tracers always want to know about signals.. + */ + if (t->ptrace & PT_PTRACED) + return 0; + + /* + * Blocked signals are never ignored, since the + * signal handler may change by the time it is + * unblocked. + */ + if (sigismember(&t->blocked, sig)) + return 0; + + /* Is it explicitly or implicitly ignored? */ + handler = t->sighand->action[sig-1].sa.sa_handler; + return handler == SIG_IGN || + (handler == SIG_DFL && sig_kernel_ignore(sig)); +} + /* * Re-calculate pending state from the set of locally pending * signals, globally pending signals, and blocked signals. @@ -256,8 +276,13 @@ void flush_signals(struct task_struct *t) { + unsigned long flags; + + spin_lock_irqsave(&t->sighand->siglock, flags); clear_tsk_thread_flag(t,TIF_SIGPENDING); flush_sigqueue(&t->pending); + flush_sigqueue(&t->signal->shared_pending); + spin_unlock_irqrestore(&t->sighand->siglock, flags); } /* @@ -460,11 +485,11 @@ * * All callers have to hold the siglock. */ -int dequeue_signal(sigset_t *mask, siginfo_t *info) +int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) { - int signr = __dequeue_signal(¤t->pending, mask, info); + int signr = __dequeue_signal(&tsk->pending, mask, info); if (!signr) - signr = __dequeue_signal(¤t->signal->shared_pending, + signr = __dequeue_signal(&tsk->signal->shared_pending, mask, info); return signr; } @@ -619,6 +644,7 @@ rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending); t = p; do { + unsigned int state; rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending); /* @@ -635,9 +661,12 @@ * Wake up the stopped thread _after_ setting * TIF_SIGPENDING */ - if (!sigismember(&t->blocked, SIGCONT)) + state = TASK_STOPPED; + if (sig_user_defined(t, SIGCONT) && !sigismember(&t->blocked, SIGCONT)) { set_tsk_thread_flag(t, TIF_SIGPENDING); - wake_up_state(t, TASK_STOPPED); + state |= TASK_INTERRUPTIBLE; + } + wake_up_state(t, state); t = next_thread(t); } while (t != p); @@ -1396,7 +1425,7 @@ #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER -int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs) +int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs, void *cookie) { sigset_t *mask = ¤t->blocked; @@ -1427,13 +1456,15 @@ continue; } dequeue: - signr = dequeue_signal(mask, info); + signr = dequeue_signal(current, mask, info); spin_unlock_irq(¤t->sighand->siglock); if (!signr) break; if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { + ptrace_signal_deliver(regs, cookie); + /* * If there is a group stop in progress, * we must participate in the bookkeeping. @@ -1576,7 +1607,6 @@ return -EINTR; } - /* * We don't need to get the kernel lock - this is all local to this * particular thread.. (and that's good, because this is _heavily_ @@ -1781,7 +1811,7 @@ } spin_lock_irq(¤t->sighand->siglock); - sig = dequeue_signal(&these, &info); + sig = dequeue_signal(current, &these, &info); if (!sig) { timeout = MAX_SCHEDULE_TIMEOUT; if (uts) @@ -1801,7 +1831,7 @@ timeout = schedule_timeout(timeout); spin_lock_irq(¤t->sighand->siglock); - sig = dequeue_signal(&these, &info); + sig = dequeue_signal(current, &these, &info); current->blocked = current->real_blocked; siginitset(¤t->real_blocked, 0); recalc_sigpending(); diff -Nru a/kernel/softirq.c b/kernel/softirq.c --- a/kernel/softirq.c Fri Feb 14 00:27:27 2003 +++ b/kernel/softirq.c Fri Feb 14 00:27:27 2003 @@ -300,17 +300,14 @@ { int cpu = (int) (long) __bind_cpu; - daemonize(); + daemonize("ksoftirqd/%d", cpu); set_user_nice(current, 19); current->flags |= PF_IOTHREAD; - sigfillset(¤t->blocked); /* Migrate to the right CPU */ set_cpus_allowed(current, 1UL << cpu); if (smp_processor_id() != cpu) BUG(); - - sprintf(current->comm, "ksoftirqd/%d", cpu); __set_current_state(TASK_INTERRUPTIBLE); mb(); diff -Nru a/kernel/sys.c b/kernel/sys.c --- a/kernel/sys.c Fri Feb 14 00:27:27 2003 +++ b/kernel/sys.c Fri Feb 14 00:27:27 2003 @@ -561,19 +561,12 @@ static int set_user(uid_t new_ruid, int dumpclear) { - struct user_struct *new_user, *old_user; + struct user_struct *new_user; - /* What if a process setreuid()'s and this brings the - * new uid over his NPROC rlimit? We can check this now - * cheaply with the new uid cache, so if it matters - * we should be checking for it. -DaveM - */ new_user = alloc_uid(new_ruid); if (!new_user) return -EAGAIN; - old_user = current->user; - atomic_dec(&old_user->processes); - atomic_inc(&new_user->processes); + switch_uid(new_user); if(dumpclear) { @@ -581,8 +574,6 @@ wmb(); } current->uid = new_ruid; - current->user = new_user; - free_uid(old_user); return 0; } @@ -916,6 +907,7 @@ p = find_task_by_pid(pid); if (!p) goto out; + err = -EINVAL; if (!thread_group_leader(p)) goto out; @@ -927,11 +919,16 @@ err = -EACCES; if (p->did_exec) goto out; - } else if (p != current) - goto out; + } else { + err = -ESRCH; + if (p != current) + goto out; + } + err = -EPERM; if (p->leader) goto out; + if (pgid != pid) { struct task_struct *p; struct pid *pid; diff -Nru a/kernel/time.c b/kernel/time.c --- a/kernel/time.c Fri Feb 14 00:27:27 2003 +++ b/kernel/time.c Fri Feb 14 00:27:27 2003 @@ -27,7 +27,6 @@ #include #include #include - #include /* @@ -416,3 +415,17 @@ return now; } + +#if (BITS_PER_LONG < 64) +u64 get_jiffies_64(void) +{ + unsigned long seq; + u64 ret; + + do { + seq = read_seqbegin(&xtime_lock); + ret = jiffies_64; + } while (read_seqretry(&xtime_lock, seq)); + return ret; +} +#endif diff -Nru a/kernel/user.c b/kernel/user.c --- a/kernel/user.c Fri Feb 14 00:27:27 2003 +++ b/kernel/user.c Fri Feb 14 00:27:27 2003 @@ -116,6 +116,23 @@ return up; } +void switch_uid(struct user_struct *new_user) +{ + struct user_struct *old_user; + + /* What if a process setreuid()'s and this brings the + * new uid over his NPROC rlimit? We can check this now + * cheaply with the new uid cache, so if it matters + * we should be checking for it. -DaveM + */ + old_user = current->user; + atomic_inc(&new_user->__count); + atomic_inc(&new_user->processes); + atomic_dec(&old_user->processes); + current->user = new_user; + free_uid(old_user); +} + static int __init uid_cache_init(void) { diff -Nru a/kernel/workqueue.c b/kernel/workqueue.c --- a/kernel/workqueue.c Fri Feb 14 00:27:30 2003 +++ b/kernel/workqueue.c Fri Feb 14 00:27:30 2003 @@ -172,19 +172,14 @@ DECLARE_WAITQUEUE(wait, current); struct k_sigaction sa; - daemonize(); - sprintf(current->comm, "%s/%d", startup->name, cpu); + daemonize("%s/%d", startup->name, cpu); + allow_signal(SIGCHLD); current->flags |= PF_IOTHREAD; cwq->thread = current; set_user_nice(current, -10); set_cpus_allowed(current, 1UL << cpu); - spin_lock_irq(¤t->sighand->siglock); - siginitsetinv(¤t->blocked, sigmask(SIGCHLD)); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - complete(&startup->done); /* Install a handler so SIGCLD is delivered */ @@ -213,10 +208,7 @@ /* SIGCHLD - auto-reaping */ ; /* zap all other signals */ - spin_lock_irq(¤t->sighand->siglock); flush_signals(current); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); } } remove_wait_queue(&cwq->more_work, &wait); diff -Nru a/lib/radix-tree.c b/lib/radix-tree.c --- a/lib/radix-tree.c Fri Feb 14 00:27:27 2003 +++ b/lib/radix-tree.c Fri Feb 14 00:27:27 2003 @@ -154,8 +154,7 @@ /* Increase the height. */ node->slots[0] = root->rnode; - if (root->rnode) - node->count = 1; + node->count = 1; root->rnode = node; root->height++; } while (height > root->height); diff -Nru a/lib/vsprintf.c b/lib/vsprintf.c --- a/lib/vsprintf.c Fri Feb 14 00:27:30 2003 +++ b/lib/vsprintf.c Fri Feb 14 00:27:30 2003 @@ -306,7 +306,8 @@ /* get the conversion qualifier */ qualifier = -1; - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || + *fmt =='Z' || *fmt == 'z') { qualifier = *fmt; ++fmt; if (qualifier == 'l' && *fmt == 'l') { @@ -381,7 +382,7 @@ if (qualifier == 'l') { long * ip = va_arg(args, long *); *ip = (str - buf); - } else if (qualifier == 'Z') { + } else if (qualifier == 'Z' || qualifier == 'z') { size_t * ip = va_arg(args, size_t *); *ip = (str - buf); } else { @@ -432,7 +433,7 @@ num = va_arg(args, unsigned long); if (flags & SIGN) num = (signed long) num; - } else if (qualifier == 'Z') { + } else if (qualifier == 'Z' || qualifier == 'z') { num = va_arg(args, size_t); } else if (qualifier == 'h') { num = (unsigned short) va_arg(args, int); @@ -565,7 +566,8 @@ /* get conversion qualifier */ qualifier = -1; - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'Z') { + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || + *fmt == 'Z' || *fmt == 'z') { qualifier = *fmt; fmt++; } @@ -680,6 +682,7 @@ } break; case 'Z': + case 'z': { size_t *s = (size_t*) va_arg(args,size_t*); *s = (size_t) simple_strtoul(str,&next,base); diff -Nru a/mm/fadvise.c b/mm/fadvise.c --- a/mm/fadvise.c Fri Feb 14 00:27:28 2003 +++ b/mm/fadvise.c Fri Feb 14 00:27:28 2003 @@ -20,7 +20,7 @@ * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could * deactivate the pages and clear PG_Referenced. */ -int sys_fadvise64(int fd, loff_t offset, size_t len, int advice) +long sys_fadvise64(int fd, loff_t offset, size_t len, int advice) { struct file *file = fget(fd); struct inode *inode; diff -Nru a/mm/mmap.c b/mm/mmap.c --- a/mm/mmap.c Fri Feb 14 00:27:29 2003 +++ b/mm/mmap.c Fri Feb 14 00:27:29 2003 @@ -801,6 +801,13 @@ return -ENOMEM; if (addr & ~PAGE_MASK) return -EINVAL; + if (file && is_file_hugepages(file)) { + unsigned long ret; + + ret = is_aligned_hugepage_range(addr, len); + if (ret) + return ret; + } return addr; } @@ -1224,8 +1231,10 @@ /* we have start < mpnt->vm_end */ if (is_vm_hugetlb_page(mpnt)) { - if ((start & ~HPAGE_MASK) || (len & ~HPAGE_MASK)) - return -EINVAL; + int ret = is_aligned_hugepage_range(start, len); + + if (ret) + return ret; } /* if it doesn't overlap, we have nothing.. */ diff -Nru a/mm/pdflush.c b/mm/pdflush.c --- a/mm/pdflush.c Fri Feb 14 00:27:30 2003 +++ b/mm/pdflush.c Fri Feb 14 00:27:30 2003 @@ -86,14 +86,7 @@ static int __pdflush(struct pdflush_work *my_work) { - daemonize(); - strcpy(current->comm, "pdflush"); - - /* interruptible sleep, so block all signals */ - spin_lock_irq(¤t->sighand->siglock); - siginitsetinv(¤t->blocked, 0); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + daemonize("pdflush"); current->flags |= PF_FLUSHER; my_work->fn = NULL; diff -Nru a/mm/swap_state.c b/mm/swap_state.c --- a/mm/swap_state.c Fri Feb 14 00:27:28 2003 +++ b/mm/swap_state.c Fri Feb 14 00:27:28 2003 @@ -294,7 +294,7 @@ */ void free_pages_and_swap_cache(struct page **pages, int nr) { - const int chunk = 16; + int chunk = 16; struct page **pagep = pages; lru_add_drain(); diff -Nru a/mm/vmscan.c b/mm/vmscan.c --- a/mm/vmscan.c Fri Feb 14 00:27:27 2003 +++ b/mm/vmscan.c Fri Feb 14 00:27:27 2003 @@ -757,7 +757,7 @@ */ static int shrink_caches(struct zone *classzone, int priority, int *total_scanned, - int gfp_mask, const int nr_pages, struct page_state *ps) + int gfp_mask, int nr_pages, struct page_state *ps) { struct zone *first_classzone; struct zone *zone; @@ -928,10 +928,8 @@ struct task_struct *tsk = current; DEFINE_WAIT(wait); - daemonize(); + daemonize("kswapd%d", pgdat->node_id); set_cpus_allowed(tsk, node_to_cpumask(pgdat->node_id)); - sprintf(tsk->comm, "kswapd%d", pgdat->node_id); - sigfillset(&tsk->blocked); /* * Tell the memory management that we're a "memory allocator", diff -Nru a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c --- a/net/ax25/sysctl_net_ax25.c Fri Feb 14 00:27:30 2003 +++ b/net/ax25/sysctl_net_ax25.c Fri Feb 14 00:27:30 2003 @@ -33,73 +33,168 @@ static int ax25_table_size; static ctl_table ax25_dir_table[] = { - {NET_AX25, "ax25", NULL, 0, 0555, NULL}, - {0} + { + .ctl_name = NET_AX25, + .procname = "ax25", + .maxlen = 0, + .mode = 0555, + }, + { .ctl_name = 0 } }; static ctl_table ax25_root_table[] = { - {CTL_NET, "net", NULL, 0, 0555, ax25_dir_table}, - {0} + { + .ctl_name = CTL_NET, + .procname = "net", + .maxlen = 0, + .mode = 0555, + .child = ax25_dir_table + }, + { .ctl_name = 0 } }; static const ctl_table ax25_param_table[] = { - {NET_AX25_IP_DEFAULT_MODE, "ip_default_mode", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_ipdefmode, &max_ipdefmode}, - {NET_AX25_DEFAULT_MODE, "ax25_default_mode", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_axdefmode, &max_axdefmode}, - {NET_AX25_BACKOFF_TYPE, "backoff_type", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_backoff, &max_backoff}, - {NET_AX25_CONNECT_MODE, "connect_mode", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_conmode, &max_conmode}, - {NET_AX25_STANDARD_WINDOW, "standard_window_size", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_window, &max_window}, - {NET_AX25_EXTENDED_WINDOW, "extended_window_size", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_ewindow, &max_ewindow}, - {NET_AX25_T1_TIMEOUT, "t1_timeout", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_t1, &max_t1}, - {NET_AX25_T2_TIMEOUT, "t2_timeout", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_t2, &max_t2}, - {NET_AX25_T3_TIMEOUT, "t3_timeout", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_t3, &max_t3}, - {NET_AX25_IDLE_TIMEOUT, "idle_timeout", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_idle, &max_idle}, - {NET_AX25_N2, "maximum_retry_count", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_n2, &max_n2}, - {NET_AX25_PACLEN, "maximum_packet_length", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_paclen, &max_paclen}, - {NET_AX25_PROTOCOL, "protocol", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_proto, &max_proto}, - {NET_AX25_DAMA_SLAVE_TIMEOUT, "dama_slave_timeout", - NULL, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, NULL, - &min_ds_timeout, &max_ds_timeout}, - {0} /* that's all, folks! */ + { + .ctl_name = NET_AX25_IP_DEFAULT_MODE, + .procname = "ip_default_mode", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_ipdefmode, + .extra2 = &max_ipdefmode + }, + { + .ctl_name = NET_AX25_DEFAULT_MODE, + .procname = "ax25_default_mode", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_axdefmode, + .extra2 = &max_axdefmode + }, + { + .ctl_name = NET_AX25_BACKOFF_TYPE, + .procname = "backoff_type", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_backoff, + .extra2 = &max_backoff + }, + { + .ctl_name = NET_AX25_CONNECT_MODE, + .procname = "connect_mode", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_conmode, + .extra2 = &max_conmode + }, + { + .ctl_name = NET_AX25_STANDARD_WINDOW, + .procname = "standard_window_size", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_window, + .extra2 = &max_window + }, + { + .ctl_name = NET_AX25_EXTENDED_WINDOW, + .procname = "extended_window_size", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_ewindow, + .extra2 = &max_ewindow + }, + { + .ctl_name = NET_AX25_T1_TIMEOUT, + .procname = "t1_timeout", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_t1, + .extra2 = &max_t1 + }, + { + .ctl_name = NET_AX25_T2_TIMEOUT, + .procname = "t2_timeout", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_t2, + .extra2 = &max_t2 + }, + { + .ctl_name = NET_AX25_T3_TIMEOUT, + .procname = "t3_timeout", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_t3, + .extra2 = &max_t3 + }, + { + .ctl_name = NET_AX25_IDLE_TIMEOUT, + .procname = "idle_timeout", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_idle, + .extra2 = &max_idle + }, + { + .ctl_name = NET_AX25_N2, + .procname = "maximum_retry_count", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_n2, + .extra2 = &max_n2 + }, + { + .ctl_name = NET_AX25_PACLEN, + .procname = "maximum_packet_length", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_paclen, + .extra2 = &max_paclen + }, + { + .ctl_name = NET_AX25_PROTOCOL, + .procname = "protocol", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_proto, + .extra2 = &max_proto + }, + { + .ctl_name = NET_AX25_DAMA_SLAVE_TIMEOUT, + .procname = "dama_slave_timeout", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_ds_timeout, + .extra2 = &max_ds_timeout + }, + { .ctl_name = 0 } /* that's all, folks! */ }; void ax25_register_sysctl(void) diff -Nru a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c --- a/net/bluetooth/af_bluetooth.c Fri Feb 14 00:27:27 2003 +++ b/net/bluetooth/af_bluetooth.c Fri Feb 14 00:27:27 2003 @@ -92,7 +92,7 @@ static int bt_sock_create(struct socket *sock, int proto) { - if (proto > BT_MAX_PROTO) + if (proto >= BT_MAX_PROTO) return -EINVAL; #if defined(CONFIG_KMOD) diff -Nru a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c --- a/net/bluetooth/bnep/core.c Fri Feb 14 00:27:29 2003 +++ b/net/bluetooth/bnep/core.c Fri Feb 14 00:27:29 2003 @@ -478,13 +478,9 @@ BT_DBG(""); - daemonize(); + daemonize("kbnepd %s", dev->name); set_user_nice(current, -15); current->flags |= PF_IOTHREAD; - sigfillset(¤t->blocked); - flush_signals(current); - - sprintf(current->comm, "kbnepd %s", dev->name); set_fs(KERNEL_DS); diff -Nru a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c --- a/net/bluetooth/rfcomm/core.c Fri Feb 14 00:27:26 2003 +++ b/net/bluetooth/rfcomm/core.c Fri Feb 14 00:27:26 2003 @@ -1705,13 +1705,9 @@ atomic_inc(&running); - daemonize(); + daemonize("krfcommd"); set_user_nice(current, -10); current->flags |= PF_IOTHREAD; - sigfillset(¤t->blocked); - flush_signals(current); - - sprintf(current->comm, "krfcommd"); set_fs(KERNEL_DS); diff -Nru a/net/core/rtnetlink.c b/net/core/rtnetlink.c --- a/net/core/rtnetlink.c Fri Feb 14 00:27:30 2003 +++ b/net/core/rtnetlink.c Fri Feb 14 00:27:30 2003 @@ -351,7 +351,7 @@ return 0; family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family; - if (family > NPROTO) { + if (family >= NPROTO) { *errp = -EAFNOSUPPORT; return -1; } diff -Nru a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c --- a/net/core/sysctl_net_core.c Fri Feb 14 00:27:27 2003 +++ b/net/core/sysctl_net_core.c Fri Feb 14 00:27:27 2003 @@ -36,59 +36,139 @@ ctl_table core_table[] = { #ifdef CONFIG_NET - {NET_CORE_WMEM_MAX, "wmem_max", - &sysctl_wmem_max, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_CORE_RMEM_MAX, "rmem_max", - &sysctl_rmem_max, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_CORE_WMEM_DEFAULT, "wmem_default", - &sysctl_wmem_default, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_CORE_RMEM_DEFAULT, "rmem_default", - &sysctl_rmem_default, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_CORE_DEV_WEIGHT, "dev_weight", - &weight_p, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_CORE_MAX_BACKLOG, "netdev_max_backlog", - &netdev_max_backlog, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_CORE_NO_CONG_THRESH, "no_cong_thresh", - &no_cong, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_CORE_NO_CONG, "no_cong", - &no_cong, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_CORE_LO_CONG, "lo_cong", - &lo_cong, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_CORE_MOD_CONG, "mod_cong", - &mod_cong, sizeof(int), 0644, NULL, - &proc_dointvec}, + { + .ctl_name = NET_CORE_WMEM_MAX, + .procname = "wmem_max", + .data = &sysctl_wmem_max, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_CORE_RMEM_MAX, + .procname = "rmem_max", + .data = &sysctl_rmem_max, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_CORE_WMEM_DEFAULT, + .procname = "wmem_default", + .data = &sysctl_wmem_default, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_CORE_RMEM_DEFAULT, + .procname = "rmem_default", + .data = &sysctl_rmem_default, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_CORE_DEV_WEIGHT, + .procname = "dev_weight", + .data = &weight_p, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_CORE_MAX_BACKLOG, + .procname = "netdev_max_backlog", + .data = &netdev_max_backlog, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_CORE_NO_CONG_THRESH, + .procname = "no_cong_thresh", + .data = &no_cong, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_CORE_NO_CONG, + .procname = "no_cong", + .data = &no_cong, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_CORE_LO_CONG, + .procname = "lo_cong", + .data = &lo_cong, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_CORE_MOD_CONG, + .procname = "mod_cong", + .data = &mod_cong, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, #ifdef CONFIG_NET_FASTROUTE - {NET_CORE_FASTROUTE, "netdev_fastroute", - &netdev_fastroute, sizeof(int), 0644, NULL, - &proc_dointvec}, + { + .ctl_name = NET_CORE_FASTROUTE, + .procname = "netdev_fastroute", + .data = &netdev_fastroute, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, #endif - {NET_CORE_MSG_COST, "message_cost", - &net_msg_cost, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies}, - {NET_CORE_MSG_BURST, "message_burst", - &net_msg_burst, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies}, - {NET_CORE_OPTMEM_MAX, "optmem_max", - &sysctl_optmem_max, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_CORE_HOT_LIST_LENGTH, "hot_list_length", - &sysctl_hot_list_len, sizeof(int), 0644, NULL, - &proc_dointvec}, + { + .ctl_name = NET_CORE_MSG_COST, + .procname = "message_cost", + .data = &net_msg_cost, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies + }, + { + .ctl_name = NET_CORE_MSG_BURST, + .procname = "message_burst", + .data = &net_msg_burst, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies + }, + { + .ctl_name = NET_CORE_OPTMEM_MAX, + .procname = "optmem_max", + .data = &sysctl_optmem_max, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_CORE_HOT_LIST_LENGTH, + .procname = "hot_list_length", + .data = &sysctl_hot_list_len, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, #ifdef CONFIG_NET_DIVERT - {NET_CORE_DIVERT_VERSION, "divert_version", - (void *)sysctl_divert_version, 32, 0444, NULL, - &proc_dostring}, + { + .ctl_name = NET_CORE_DIVERT_VERSION, + .procname = "divert_version", + .data = (void *)sysctl_divert_version, + .maxlen = 32, + .mode = 0444, + .proc_handler = &proc_dostring + }, #endif /* CONFIG_NET_DIVERT */ #endif /* CONFIG_NET */ - { 0 } + { .ctl_name = 0 } }; #endif diff -Nru a/net/econet/af_econet.c b/net/econet/af_econet.c --- a/net/econet/af_econet.c Fri Feb 14 00:27:28 2003 +++ b/net/econet/af_econet.c Fri Feb 14 00:27:28 2003 @@ -338,6 +338,7 @@ eb = (struct ec_cb *)&skb->cb; + /* BUG: saddr may be NULL */ eb->cookie = saddr->cookie; eb->sec = *saddr; eb->sent = ec_tx_done; diff -Nru a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c --- a/net/ipv4/netfilter/arptable_filter.c Fri Feb 14 00:27:26 2003 +++ b/net/ipv4/netfilter/arptable_filter.c Fri Feb 14 00:27:26 2003 @@ -37,10 +37,10 @@ } initial_table __initdata = { { "filter", FILTER_VALID_HOOKS, 3, sizeof(struct arpt_standard) * 2 + sizeof(struct arpt_error), - { [NF_ARP_IN] 0, - [NF_ARP_OUT] sizeof(struct arpt_standard) }, - { [NF_ARP_IN] 0, - [NF_ARP_OUT] sizeof(struct arpt_standard), }, + { [NF_ARP_IN] = 0, + [NF_ARP_OUT] = sizeof(struct arpt_standard) }, + { [NF_ARP_IN] = 0, + [NF_ARP_OUT] = sizeof(struct arpt_standard), }, 0, NULL, { } }, { /* ARP_IN */ diff -Nru a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c --- a/net/ipv4/netfilter/ip_conntrack_core.c Fri Feb 14 00:27:26 2003 +++ b/net/ipv4/netfilter/ip_conntrack_core.c Fri Feb 14 00:27:26 2003 @@ -1361,19 +1361,37 @@ static struct ctl_table_header *ip_conntrack_sysctl_header; static ctl_table ip_conntrack_table[] = { - { NET_IP_CONNTRACK_MAX, NET_IP_CONNTRACK_MAX_NAME, &ip_conntrack_max, - sizeof(ip_conntrack_max), 0644, NULL, proc_dointvec }, - { 0 } + { + .ctl_name = NET_IP_CONNTRACK_MAX, + .procname = NET_IP_CONNTRACK_MAX_NAME, + .data = &ip_conntrack_max, + .maxlen = sizeof(ip_conntrack_max), + .mode = 0644, + .proc_handler = proc_dointvec + }, + { .ctl_name = 0 } }; static ctl_table ip_conntrack_dir_table[] = { - {NET_IPV4, "ipv4", NULL, 0, 0555, ip_conntrack_table, 0, 0, 0, 0, 0}, - { 0 } + { + .ctl_name = NET_IPV4, + .procname = "ipv4", + .maxlen = 0, + .mode = 0555, + .child = ip_conntrack_table + }, + { .ctl_name = 0 } }; static ctl_table ip_conntrack_root_table[] = { - {CTL_NET, "net", NULL, 0, 0555, ip_conntrack_dir_table, 0, 0, 0, 0, 0}, - { 0 } + { + .ctl_name = CTL_NET, + .procname = "net", + .maxlen = 0, + .mode = 0555, + .child = ip_conntrack_dir_table + }, + { .ctl_name = 0 } }; #endif /*CONFIG_SYSCTL*/ diff -Nru a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c --- a/net/ipv4/netfilter/ip_nat_ftp.c Fri Feb 14 00:27:29 2003 +++ b/net/ipv4/netfilter/ip_nat_ftp.c Fri Feb 14 00:27:29 2003 @@ -160,10 +160,10 @@ unsigned int, struct ip_conntrack *, enum ip_conntrack_info) -= { [IP_CT_FTP_PORT] mangle_rfc959_packet, - [IP_CT_FTP_PASV] mangle_rfc959_packet, - [IP_CT_FTP_EPRT] mangle_eprt_packet, - [IP_CT_FTP_EPSV] mangle_epsv_packet += { [IP_CT_FTP_PORT] = mangle_rfc959_packet, + [IP_CT_FTP_PASV] = mangle_rfc959_packet, + [IP_CT_FTP_EPRT] = mangle_eprt_packet, + [IP_CT_FTP_EPSV] = mangle_epsv_packet }; static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info, diff -Nru a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c --- a/net/ipv4/netfilter/ip_nat_rule.c Fri Feb 14 00:27:28 2003 +++ b/net/ipv4/netfilter/ip_nat_rule.c Fri Feb 14 00:27:28 2003 @@ -56,12 +56,12 @@ } nat_initial_table __initdata = { { "nat", NAT_VALID_HOOKS, 4, sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error), - { [NF_IP_PRE_ROUTING] 0, - [NF_IP_POST_ROUTING] sizeof(struct ipt_standard), - [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2 }, - { [NF_IP_PRE_ROUTING] 0, - [NF_IP_POST_ROUTING] sizeof(struct ipt_standard), - [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2 }, + { [NF_IP_PRE_ROUTING] = 0, + [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard), + [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 }, + { [NF_IP_PRE_ROUTING] = 0, + [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard), + [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 }, 0, NULL, { } }, { /* PRE_ROUTING */ diff -Nru a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c --- a/net/ipv4/netfilter/ip_queue.c Fri Feb 14 00:27:30 2003 +++ b/net/ipv4/netfilter/ip_queue.c Fri Feb 14 00:27:30 2003 @@ -586,19 +586,37 @@ static struct ctl_table_header *ipq_sysctl_header; static ctl_table ipq_table[] = { - { NET_IPQ_QMAX, NET_IPQ_QMAX_NAME, &sysctl_maxlen, - sizeof(sysctl_maxlen), 0644, NULL, proc_dointvec }, - { 0 } + { + .ctl_name = NET_IPQ_QMAX, + .procname = NET_IPQ_QMAX_NAME, + .data = &sysctl_maxlen, + .maxlen = sizeof(sysctl_maxlen), + .mode = 0644, + .proc_handler = proc_dointvec + }, + { .ctl_name = 0 } }; static ctl_table ipq_dir_table[] = { - {NET_IPV4, "ipv4", NULL, 0, 0555, ipq_table, 0, 0, 0, 0, 0}, - { 0 } + { + .ctl_name = NET_IPV4, + .procname = "ipv4", + .maxlen = 0, + .mode = 0555, + .child = ipq_table + }, + { .ctl_name = 0 } }; static ctl_table ipq_root_table[] = { - {CTL_NET, "net", NULL, 0, 0555, ipq_dir_table, 0, 0, 0, 0, 0}, - { 0 } + { + .ctl_name = CTL_NET, + .procname = "net", + .maxlen = 0, + .mode = 0555, + .child = ipq_dir_table + }, + { .ctl_name = 0 } }; static int diff -Nru a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c --- a/net/ipv4/netfilter/iptable_filter.c Fri Feb 14 00:27:27 2003 +++ b/net/ipv4/netfilter/iptable_filter.c Fri Feb 14 00:27:27 2003 @@ -35,12 +35,12 @@ } initial_table __initdata = { { "filter", FILTER_VALID_HOOKS, 4, sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error), - { [NF_IP_LOCAL_IN] 0, - [NF_IP_FORWARD] sizeof(struct ipt_standard), - [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2 }, - { [NF_IP_LOCAL_IN] 0, - [NF_IP_FORWARD] sizeof(struct ipt_standard), - [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2 }, + { [NF_IP_LOCAL_IN] = 0, + [NF_IP_FORWARD] = sizeof(struct ipt_standard), + [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 }, + { [NF_IP_LOCAL_IN] = 0, + [NF_IP_FORWARD] = sizeof(struct ipt_standard), + [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 }, 0, NULL, { } }, { /* LOCAL_IN */ diff -Nru a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c --- a/net/ipv4/netfilter/iptable_mangle.c Fri Feb 14 00:27:30 2003 +++ b/net/ipv4/netfilter/iptable_mangle.c Fri Feb 14 00:27:30 2003 @@ -48,16 +48,16 @@ } initial_table __initdata = { { "mangle", MANGLE_VALID_HOOKS, 6, sizeof(struct ipt_standard) * 5 + sizeof(struct ipt_error), - { [NF_IP_PRE_ROUTING] 0, - [NF_IP_LOCAL_IN] sizeof(struct ipt_standard), - [NF_IP_FORWARD] sizeof(struct ipt_standard) * 2, - [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 3, - [NF_IP_POST_ROUTING] sizeof(struct ipt_standard) * 4 }, - { [NF_IP_PRE_ROUTING] 0, - [NF_IP_LOCAL_IN] sizeof(struct ipt_standard), - [NF_IP_FORWARD] sizeof(struct ipt_standard) * 2, - [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 3, - [NF_IP_POST_ROUTING] sizeof(struct ipt_standard) * 4 }, + { [NF_IP_PRE_ROUTING] = 0, + [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard), + [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2, + [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3, + [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4 }, + { [NF_IP_PRE_ROUTING] = 0, + [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard), + [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2, + [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3, + [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4 }, 0, NULL, { } }, { /* PRE_ROUTING */ diff -Nru a/net/ipv4/proc.c b/net/ipv4/proc.c --- a/net/ipv4/proc.c Fri Feb 14 00:27:26 2003 +++ b/net/ipv4/proc.c Fri Feb 14 00:27:26 2003 @@ -99,7 +99,7 @@ *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) + sizeof (unsigned long) * nr)); res += - *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) + + *((unsigned long *) (((void *) per_cpu_ptr(mib[1], i)) + sizeof (unsigned long) * nr)); } return res; diff -Nru a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c --- a/net/ipv4/sysctl_net_ipv4.c Fri Feb 14 00:27:29 2003 +++ b/net/ipv4/sysctl_net_ipv4.c Fri Feb 14 00:27:29 2003 @@ -88,144 +88,465 @@ } ctl_table ipv4_table[] = { - {NET_IPV4_TCP_TIMESTAMPS, "tcp_timestamps", - &sysctl_tcp_timestamps, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_TCP_WINDOW_SCALING, "tcp_window_scaling", - &sysctl_tcp_window_scaling, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_TCP_SACK, "tcp_sack", - &sysctl_tcp_sack, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_TCP_RETRANS_COLLAPSE, "tcp_retrans_collapse", - &sysctl_tcp_retrans_collapse, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_FORWARD, "ip_forward", - &ipv4_devconf.forwarding, sizeof(int), 0644, NULL, - &ipv4_sysctl_forward,&ipv4_sysctl_forward_strategy}, - {NET_IPV4_DEFAULT_TTL, "ip_default_ttl", - &sysctl_ip_default_ttl, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_AUTOCONFIG, "ip_autoconfig", - &ipv4_config.autoconfig, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_NO_PMTU_DISC, "ip_no_pmtu_disc", - &ipv4_config.no_pmtu_disc, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_NONLOCAL_BIND, "ip_nonlocal_bind", - &sysctl_ip_nonlocal_bind, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_TCP_SYN_RETRIES, "tcp_syn_retries", - &sysctl_tcp_syn_retries, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_SYNACK_RETRIES, "tcp_synack_retries", - &sysctl_tcp_synack_retries, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_MAX_ORPHANS, "tcp_max_orphans", - &sysctl_tcp_max_orphans, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_MAX_TW_BUCKETS, "tcp_max_tw_buckets", - &sysctl_tcp_max_tw_buckets, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_IPFRAG_HIGH_THRESH, "ipfrag_high_thresh", - &sysctl_ipfrag_high_thresh, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_IPFRAG_LOW_THRESH, "ipfrag_low_thresh", - &sysctl_ipfrag_low_thresh, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_DYNADDR, "ip_dynaddr", - &sysctl_ip_dynaddr, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_IPFRAG_TIME, "ipfrag_time", - &sysctl_ipfrag_time, sizeof(int), 0644, NULL, &proc_dointvec_jiffies, - &sysctl_jiffies}, - {NET_IPV4_TCP_KEEPALIVE_TIME, "tcp_keepalive_time", - &sysctl_tcp_keepalive_time, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, - {NET_IPV4_TCP_KEEPALIVE_PROBES, "tcp_keepalive_probes", - &sysctl_tcp_keepalive_probes, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_TCP_KEEPALIVE_INTVL, "tcp_keepalive_intvl", - &sysctl_tcp_keepalive_intvl, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, - {NET_IPV4_TCP_RETRIES1, "tcp_retries1", - &sysctl_tcp_retries1, sizeof(int), 0644, NULL, &proc_dointvec_minmax, - &sysctl_intvec, NULL, NULL, &tcp_retr1_max}, - {NET_IPV4_TCP_RETRIES2, "tcp_retries2", - &sysctl_tcp_retries2, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_TCP_FIN_TIMEOUT, "tcp_fin_timeout", - &sysctl_tcp_fin_timeout, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, + { + .ctl_name = NET_IPV4_TCP_TIMESTAMPS, + .procname = "tcp_timestamps", + .data = &sysctl_tcp_timestamps, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_TCP_WINDOW_SCALING, + .procname = "tcp_window_scaling", + .data = &sysctl_tcp_window_scaling, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_TCP_SACK, + .procname = "tcp_sack", + .data = &sysctl_tcp_sack, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_TCP_RETRANS_COLLAPSE, + .procname = "tcp_retrans_collapse", + .data = &sysctl_tcp_retrans_collapse, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_FORWARD, + .procname = "ip_forward", + .data = &ipv4_devconf.forwarding, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &ipv4_sysctl_forward, + .strategy = &ipv4_sysctl_forward_strategy + }, + { + .ctl_name = NET_IPV4_DEFAULT_TTL, + .procname = "ip_default_ttl", + .data = &sysctl_ip_default_ttl, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_AUTOCONFIG, + .procname = "ip_autoconfig", + .data = &ipv4_config.autoconfig, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_NO_PMTU_DISC, + .procname = "ip_no_pmtu_disc", + .data = &ipv4_config.no_pmtu_disc, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_NONLOCAL_BIND, + .procname = "ip_nonlocal_bind", + .data = &sysctl_ip_nonlocal_bind, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_TCP_SYN_RETRIES, + .procname = "tcp_syn_retries", + .data = &sysctl_tcp_syn_retries, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_SYNACK_RETRIES, + .procname = "tcp_synack_retries", + .data = &sysctl_tcp_synack_retries, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_MAX_ORPHANS, + .procname = "tcp_max_orphans", + .data = &sysctl_tcp_max_orphans, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_MAX_TW_BUCKETS, + .procname = "tcp_max_tw_buckets", + .data = &sysctl_tcp_max_tw_buckets, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH, + .procname = "ipfrag_high_thresh", + .data = &sysctl_ipfrag_high_thresh, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_IPFRAG_LOW_THRESH, + .procname = "ipfrag_low_thresh", + .data = &sysctl_ipfrag_low_thresh, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_DYNADDR, + .procname = "ip_dynaddr", + .data = &sysctl_ip_dynaddr, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_IPFRAG_TIME, + .procname = "ipfrag_time", + .data = &sysctl_ipfrag_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_IPV4_TCP_KEEPALIVE_TIME, + .procname = "tcp_keepalive_time", + .data = &sysctl_tcp_keepalive_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_IPV4_TCP_KEEPALIVE_PROBES, + .procname = "tcp_keepalive_probes", + .data = &sysctl_tcp_keepalive_probes, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_TCP_KEEPALIVE_INTVL, + .procname = "tcp_keepalive_intvl", + .data = &sysctl_tcp_keepalive_intvl, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_IPV4_TCP_RETRIES1, + .procname = "tcp_retries1", + .data = &sysctl_tcp_retries1, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra2 = &tcp_retr1_max + }, + { + .ctl_name = NET_IPV4_TCP_RETRIES2, + .procname = "tcp_retries2", + .data = &sysctl_tcp_retries2, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_TCP_FIN_TIMEOUT, + .procname = "tcp_fin_timeout", + .data = &sysctl_tcp_fin_timeout, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, #ifdef CONFIG_SYN_COOKIES - {NET_TCP_SYNCOOKIES, "tcp_syncookies", - &sysctl_tcp_syncookies, sizeof(int), 0644, NULL, &proc_dointvec}, + { + .ctl_name = NET_TCP_SYNCOOKIES, + .procname = "tcp_syncookies", + .data = &sysctl_tcp_syncookies, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, #endif - {NET_TCP_TW_RECYCLE, "tcp_tw_recycle", - &sysctl_tcp_tw_recycle, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_ABORT_ON_OVERFLOW, "tcp_abort_on_overflow", - &sysctl_tcp_abort_on_overflow, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_STDURG, "tcp_stdurg", &sysctl_tcp_stdurg, - sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_RFC1337, "tcp_rfc1337", &sysctl_tcp_rfc1337, - sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_MAX_SYN_BACKLOG, "tcp_max_syn_backlog", &sysctl_max_syn_backlog, - sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_LOCAL_PORT_RANGE, "ip_local_port_range", - &sysctl_local_port_range, sizeof(sysctl_local_port_range), 0644, - NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL, - ip_local_port_range_min, ip_local_port_range_max }, - {NET_IPV4_ICMP_ECHO_IGNORE_ALL, "icmp_echo_ignore_all", - &sysctl_icmp_echo_ignore_all, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS, "icmp_echo_ignore_broadcasts", - &sysctl_icmp_echo_ignore_broadcasts, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES, "icmp_ignore_bogus_error_responses", - &sysctl_icmp_ignore_bogus_error_responses, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_ROUTE, "route", NULL, 0, 0555, ipv4_route_table}, + { + .ctl_name = NET_TCP_TW_RECYCLE, + .procname = "tcp_tw_recycle", + .data = &sysctl_tcp_tw_recycle, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_ABORT_ON_OVERFLOW, + .procname = "tcp_abort_on_overflow", + .data = &sysctl_tcp_abort_on_overflow, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_STDURG, + .procname = "tcp_stdurg", + .data = &sysctl_tcp_stdurg, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_RFC1337, + .procname = "tcp_rfc1337", + .data = &sysctl_tcp_rfc1337, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_MAX_SYN_BACKLOG, + .procname = "tcp_max_syn_backlog", + .data = &sysctl_max_syn_backlog, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_LOCAL_PORT_RANGE, + .procname = "ip_local_port_range", + .data = &sysctl_local_port_range, + .maxlen = sizeof(sysctl_local_port_range), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = ip_local_port_range_min, + .extra2 = ip_local_port_range_max + }, + { + .ctl_name = NET_IPV4_ICMP_ECHO_IGNORE_ALL, + .procname = "icmp_echo_ignore_all", + .data = &sysctl_icmp_echo_ignore_all, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS, + .procname = "icmp_echo_ignore_broadcasts", + .data = &sysctl_icmp_echo_ignore_broadcasts, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES, + .procname = "icmp_ignore_bogus_error_responses", + .data = &sysctl_icmp_ignore_bogus_error_responses, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_ROUTE, + .procname = "route", + .maxlen = 0, + .mode = 0555, + .child = ipv4_route_table + }, #ifdef CONFIG_IP_MULTICAST - {NET_IPV4_IGMP_MAX_MEMBERSHIPS, "igmp_max_memberships", - &sysctl_igmp_max_memberships, sizeof(int), 0644, NULL, &proc_dointvec}, + { + .ctl_name = NET_IPV4_IGMP_MAX_MEMBERSHIPS, + .procname = "igmp_max_memberships", + .data = &sysctl_igmp_max_memberships, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + #endif - {NET_IPV4_INET_PEER_THRESHOLD, "inet_peer_threshold", - &inet_peer_threshold, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_INET_PEER_MINTTL, "inet_peer_minttl", - &inet_peer_minttl, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, - {NET_IPV4_INET_PEER_MAXTTL, "inet_peer_maxttl", - &inet_peer_maxttl, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, - {NET_IPV4_INET_PEER_GC_MINTIME, "inet_peer_gc_mintime", - &inet_peer_gc_mintime, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, - {NET_IPV4_INET_PEER_GC_MAXTIME, "inet_peer_gc_maxtime", - &inet_peer_gc_maxtime, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, - {NET_TCP_ORPHAN_RETRIES, "tcp_orphan_retries", - &sysctl_tcp_orphan_retries, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_FACK, "tcp_fack", - &sysctl_tcp_fack, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_REORDERING, "tcp_reordering", - &sysctl_tcp_reordering, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_ECN, "tcp_ecn", - &sysctl_tcp_ecn, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_DSACK, "tcp_dsack", - &sysctl_tcp_dsack, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_MEM, "tcp_mem", - &sysctl_tcp_mem, sizeof(sysctl_tcp_mem), 0644, NULL, &proc_dointvec}, - {NET_TCP_WMEM, "tcp_wmem", - &sysctl_tcp_wmem, sizeof(sysctl_tcp_wmem), 0644, NULL, &proc_dointvec}, - {NET_TCP_RMEM, "tcp_rmem", - &sysctl_tcp_rmem, sizeof(sysctl_tcp_rmem), 0644, NULL, &proc_dointvec}, - {NET_TCP_APP_WIN, "tcp_app_win", - &sysctl_tcp_app_win, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_ADV_WIN_SCALE, "tcp_adv_win_scale", - &sysctl_tcp_adv_win_scale, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_ICMP_RATELIMIT, "icmp_ratelimit", - &sysctl_icmp_ratelimit, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_ICMP_RATEMASK, "icmp_ratemask", - &sysctl_icmp_ratemask, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_TW_REUSE, "tcp_tw_reuse", - &sysctl_tcp_tw_reuse, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_FRTO, "tcp_frto", - &sysctl_tcp_frto, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_LOW_LATENCY, "tcp_low_latency", - &sysctl_tcp_low_latency, sizeof(int), 0644, NULL, &proc_dointvec}, - {0} + { + .ctl_name = NET_IPV4_INET_PEER_THRESHOLD, + .procname = "inet_peer_threshold", + .data = &inet_peer_threshold, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_INET_PEER_MINTTL, + .procname = "inet_peer_minttl", + .data = &inet_peer_minttl, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_IPV4_INET_PEER_MAXTTL, + .procname = "inet_peer_maxttl", + .data = &inet_peer_maxttl, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_IPV4_INET_PEER_GC_MINTIME, + .procname = "inet_peer_gc_mintime", + .data = &inet_peer_gc_mintime, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_IPV4_INET_PEER_GC_MAXTIME, + .procname = "inet_peer_gc_maxtime", + .data = &inet_peer_gc_maxtime, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_TCP_ORPHAN_RETRIES, + .procname = "tcp_orphan_retries", + .data = &sysctl_tcp_orphan_retries, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_FACK, + .procname = "tcp_fack", + .data = &sysctl_tcp_fack, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_REORDERING, + .procname = "tcp_reordering", + .data = &sysctl_tcp_reordering, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_ECN, + .procname = "tcp_ecn", + .data = &sysctl_tcp_ecn, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_DSACK, + .procname = "tcp_dsack", + .data = &sysctl_tcp_dsack, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_MEM, + .procname = "tcp_mem", + .data = &sysctl_tcp_mem, + .maxlen = sizeof(sysctl_tcp_mem), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_WMEM, + .procname = "tcp_wmem", + .data = &sysctl_tcp_wmem, + .maxlen = sizeof(sysctl_tcp_wmem), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_RMEM, + .procname = "tcp_rmem", + .data = &sysctl_tcp_rmem, + .maxlen = sizeof(sysctl_tcp_rmem), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_APP_WIN, + .procname = "tcp_app_win", + .data = &sysctl_tcp_app_win, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_ADV_WIN_SCALE, + .procname = "tcp_adv_win_scale", + .data = &sysctl_tcp_adv_win_scale, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_ICMP_RATELIMIT, + .procname = "icmp_ratelimit", + .data = &sysctl_icmp_ratelimit, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_ICMP_RATEMASK, + .procname = "icmp_ratemask", + .data = &sysctl_icmp_ratemask, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_TW_REUSE, + .procname = "tcp_tw_reuse", + .data = &sysctl_tcp_tw_reuse, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_FRTO, + .procname = "tcp_frto", + .data = &sysctl_tcp_frto, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_TCP_LOW_LATENCY, + .procname = "tcp_low_latency", + .data = &sysctl_tcp_low_latency, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { .ctl_name = 0 } }; #endif /* CONFIG_SYSCTL */ diff -Nru a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c --- a/net/ipv4/tcp_output.c Fri Feb 14 00:27:29 2003 +++ b/net/ipv4/tcp_output.c Fri Feb 14 00:27:29 2003 @@ -1522,7 +1522,8 @@ } if (err <= 0) { - tp->backoff++; + if (tp->backoff < sysctl_tcp_retries2) + tp->backoff++; tp->probes_out++; tcp_reset_xmit_timer (sk, TCP_TIME_PROBE0, min(tp->rto << tp->backoff, TCP_RTO_MAX)); diff -Nru a/net/ipv4/xfrm_state.c b/net/ipv4/xfrm_state.c --- a/net/ipv4/xfrm_state.c Fri Feb 14 00:27:29 2003 +++ b/net/ipv4/xfrm_state.c Fri Feb 14 00:27:29 2003 @@ -1,6 +1,7 @@ #include #include #include +#include /* Each xfrm_state may be linked to two tables: @@ -219,7 +220,8 @@ spin_lock_bh(&xfrm_state_lock); list_for_each_entry(x, xfrm_state_bydst+h, bydst) { - if (daddr == x->id.daddr.xfrm4_addr && + if (x->props.family == AF_INET && + daddr == x->id.daddr.xfrm4_addr && x->props.reqid == tmpl->reqid && (saddr == x->props.saddr.xfrm4_addr || !saddr || !x->props.saddr.xfrm4_addr) && tmpl->mode == x->props.mode && @@ -282,6 +284,7 @@ x->id = tmpl->id; if (x->id.daddr.xfrm4_addr == 0) x->id.daddr.xfrm4_addr = daddr; + x->props.family = AF_INET; x->props.saddr = tmpl->saddr; if (x->props.saddr.xfrm4_addr == 0) x->props.saddr.xfrm4_addr = saddr; @@ -317,7 +320,12 @@ void xfrm_state_insert(struct xfrm_state *x) { - unsigned h = ntohl(x->id.daddr.xfrm4_addr); + unsigned h = 0; + + if (x->props.family == AF_INET) + h = ntohl(x->id.daddr.xfrm4_addr); + else if (x->props.family == AF_INET6) + h = ntohl(x->id.daddr.a6[2]^x->id.daddr.a6[3]); h = (h ^ (h>>16)) % XFRM_DST_HSIZE; @@ -325,7 +333,10 @@ list_add(&x->bydst, xfrm_state_bydst+h); atomic_inc(&x->refcnt); - h = ntohl(x->id.daddr.xfrm4_addr^x->id.spi^x->id.proto); + if (x->props.family == AF_INET) + h = ntohl(x->id.daddr.xfrm4_addr^x->id.spi^x->id.proto); + else + h = ntohl(x->id.daddr.a6[2]^x->id.daddr.a6[3]^x->id.spi^x->id.proto); h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE; list_add(&x->byspi, xfrm_state_byspi+h); atomic_inc(&x->refcnt); @@ -382,7 +393,8 @@ spin_lock_bh(&xfrm_state_lock); list_for_each_entry(x, xfrm_state_byspi+h, byspi) { - if (spi == x->id.spi && + if (x->props.family == AF_INET && + spi == x->id.spi && daddr == x->id.daddr.xfrm4_addr && proto == x->id.proto) { atomic_inc(&x->refcnt); @@ -405,7 +417,8 @@ spin_lock_bh(&xfrm_state_lock); list_for_each_entry(x, xfrm_state_bydst+h, bydst) { - if (daddr == x->id.daddr.xfrm4_addr && + if (x->props.family == AF_INET && + daddr == x->id.daddr.xfrm4_addr && mode == x->props.mode && proto == x->id.proto && saddr == x->props.saddr.xfrm4_addr && @@ -432,6 +445,7 @@ x0->km.state = XFRM_STATE_ACQ; x0->id.daddr.xfrm4_addr = daddr; x0->id.proto = proto; + x0->props.family = AF_INET; x0->props.mode = mode; x0->props.reqid = reqid; x0->lft.hard_add_expires_seconds = ACQ_EXPIRES; @@ -591,8 +605,14 @@ int i; for (i=0; isel, fl)) + if (x[i]->props.family == AF_INET && + !xfrm4_selector_match(&x[i]->sel, fl)) + return -EINVAL; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + if (x[i]->props.family == AF_INET6 && + !xfrm6_selector_match(&x[i]->sel, fl)) return -EINVAL; +#endif } return 0; } @@ -701,3 +721,119 @@ INIT_LIST_HEAD(&xfrm_state_byspi[i]); } } + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +struct xfrm_state * +xfrm6_state_lookup(struct in6_addr *daddr, u32 spi, u8 proto) +{ + unsigned h = ntohl(daddr->s6_addr32[2]^daddr->s6_addr32[3]^spi^proto); + struct xfrm_state *x; + + h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE; + + spin_lock_bh(&xfrm_state_lock); + list_for_each_entry(x, xfrm_state_byspi+h, byspi) { + if (x->props.family == AF_INET6 && + spi == x->id.spi && + !ipv6_addr_cmp(daddr, (struct in6_addr *)x->id.daddr.a6) && + proto == x->id.proto) { + atomic_inc(&x->refcnt); + spin_unlock_bh(&xfrm_state_lock); + return x; + } + } + spin_unlock_bh(&xfrm_state_lock); + return NULL; +} + +struct xfrm_state * +xfrm6_find_acq(u8 mode, u16 reqid, u8 proto, struct in6_addr *daddr, struct in6_addr *saddr, int create) +{ + struct xfrm_state *x, *x0; + unsigned h = ntohl(daddr->s6_addr32[2]^daddr->s6_addr32[3]); + + h = (h ^ (h>>16)) % XFRM_DST_HSIZE; + x0 = NULL; + + spin_lock_bh(&xfrm_state_lock); + list_for_each_entry(x, xfrm_state_bydst+h, bydst) { + if (x->props.family == AF_INET6 && + !memcmp(daddr, x->id.daddr.a6, sizeof(struct in6_addr)) && + mode == x->props.mode && + proto == x->id.proto && + !memcmp(saddr, x->props.saddr.a6, sizeof(struct in6_addr)) && + reqid == x->props.reqid && + x->km.state == XFRM_STATE_ACQ) { + if (!x0) + x0 = x; + if (x->id.spi) + continue; + x0 = x; + break; + } + } + if (x0) { + atomic_inc(&x0->refcnt); + } else if (create && (x0 = xfrm_state_alloc()) != NULL) { + memcpy(x0->sel.daddr.a6, daddr, sizeof(struct in6_addr)); + memcpy(x0->sel.saddr.a6, saddr, sizeof(struct in6_addr)); + x0->sel.prefixlen_d = 128; + x0->sel.prefixlen_s = 128; + memcpy(x0->props.saddr.a6, saddr, sizeof(struct in6_addr)); + x0->km.state = XFRM_STATE_ACQ; + memcpy(x0->id.daddr.a6, daddr, sizeof(struct in6_addr)); + x0->id.proto = proto; + x0->props.family = AF_INET6; + x0->props.mode = mode; + x0->props.reqid = reqid; + x0->lft.hard_add_expires_seconds = ACQ_EXPIRES; + atomic_inc(&x0->refcnt); + mod_timer(&x0->timer, jiffies + ACQ_EXPIRES*HZ); + atomic_inc(&x0->refcnt); + list_add_tail(&x0->bydst, xfrm_state_bydst+h); + wake_up(&km_waitq); + } + spin_unlock_bh(&xfrm_state_lock); + return x0; +} + +void +xfrm6_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi) +{ + u32 h; + struct xfrm_state *x0; + + if (x->id.spi) + return; + + if (minspi == maxspi) { + x0 = xfrm6_state_lookup((struct in6_addr*)x->id.daddr.a6, minspi, x->id.proto); + if (x0) { + xfrm_state_put(x0); + return; + } + x->id.spi = minspi; + } else { + u32 spi = 0; + minspi = ntohl(minspi); + maxspi = ntohl(maxspi); + for (h=0; hid.daddr.a6, htonl(spi), x->id.proto); + if (x0 == NULL) + break; + xfrm_state_put(x0); + } + x->id.spi = htonl(spi); + } + if (x->id.spi) { + spin_lock_bh(&xfrm_state_lock); + h = ntohl(x->id.daddr.a6[2]^x->id.daddr.a6[3]^x->id.spi^x->id.proto); + h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE; + list_add(&x->byspi, xfrm_state_byspi+h); + atomic_inc(&x->refcnt); + spin_unlock_bh(&xfrm_state_lock); + wake_up(&km_waitq); + } +} +#endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */ diff -Nru a/net/ipv6/Makefile b/net/ipv6/Makefile --- a/net/ipv6/Makefile Fri Feb 14 00:27:29 2003 +++ b/net/ipv6/Makefile Fri Feb 14 00:27:29 2003 @@ -11,3 +11,5 @@ ip6_flowlabel.o ipv6_syms.o obj-$(CONFIG_NETFILTER) += netfilter/ + +obj-y += xfrm_policy.o diff -Nru a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c --- a/net/ipv6/ipv6_syms.c Fri Feb 14 00:27:29 2003 +++ b/net/ipv6/ipv6_syms.c Fri Feb 14 00:27:29 2003 @@ -4,6 +4,7 @@ #include #include #include +#include EXPORT_SYMBOL(ipv6_addr_type); EXPORT_SYMBOL(icmpv6_send); @@ -25,3 +26,6 @@ EXPORT_SYMBOL(inet6_ioctl); EXPORT_SYMBOL(ipv6_get_saddr); EXPORT_SYMBOL(ipv6_chk_addr); +EXPORT_SYMBOL(xfrm6_register_type); +EXPORT_SYMBOL(xfrm6_unregister_type); +EXPORT_SYMBOL(xfrm6_get_type); diff -Nru a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c --- a/net/ipv6/netfilter/ip6_queue.c Fri Feb 14 00:27:27 2003 +++ b/net/ipv6/netfilter/ip6_queue.c Fri Feb 14 00:27:27 2003 @@ -628,19 +628,37 @@ static struct ctl_table_header *ipq_sysctl_header; static ctl_table ipq_table[] = { - { NET_IPQ_QMAX, NET_IPQ_QMAX_NAME, &sysctl_maxlen, - sizeof(sysctl_maxlen), 0644, NULL, proc_dointvec }, - { 0 } + { + .ctl_name = NET_IPQ_QMAX, + .procname = NET_IPQ_QMAX_NAME, + .data = &sysctl_maxlen, + .maxlen = sizeof(sysctl_maxlen), + .mode = 0644, + .proc_handler = proc_dointvec + }, + { .ctl_name = 0 } }; static ctl_table ipq_dir_table[] = { - {NET_IPV6, "ipv6", NULL, 0, 0555, ipq_table, 0, 0, 0, 0, 0}, - { 0 } + { + .ctl_name = NET_IPV6, + .procname = "ipv6", + .maxlen = 0, + .mode = 0555, + .child = ipq_table + }, + { .ctl_name = 0 } }; static ctl_table ipq_root_table[] = { - {CTL_NET, "net", NULL, 0, 0555, ipq_dir_table, 0, 0, 0, 0, 0}, - { 0 } + { + .ctl_name = CTL_NET, + .procname = "net", + .maxlen = 0, + .mode = 0555, + .child = ipq_dir_table + }, + { .ctl_name = 0 } }; static int diff -Nru a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c --- a/net/ipv6/netfilter/ip6table_filter.c Fri Feb 14 00:27:27 2003 +++ b/net/ipv6/netfilter/ip6table_filter.c Fri Feb 14 00:27:27 2003 @@ -35,12 +35,12 @@ } initial_table __initdata = { { "filter", FILTER_VALID_HOOKS, 4, sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error), - { [NF_IP6_LOCAL_IN] 0, - [NF_IP6_FORWARD] sizeof(struct ip6t_standard), - [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) * 2 }, - { [NF_IP6_LOCAL_IN] 0, - [NF_IP6_FORWARD] sizeof(struct ip6t_standard), - [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) * 2 }, + { [NF_IP6_LOCAL_IN] = 0, + [NF_IP6_FORWARD] = sizeof(struct ip6t_standard), + [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 }, + { [NF_IP6_LOCAL_IN] = 0, + [NF_IP6_FORWARD] = sizeof(struct ip6t_standard), + [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 }, 0, NULL, { } }, { /* LOCAL_IN */ diff -Nru a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c --- a/net/ipv6/netfilter/ip6table_mangle.c Fri Feb 14 00:27:28 2003 +++ b/net/ipv6/netfilter/ip6table_mangle.c Fri Feb 14 00:27:28 2003 @@ -45,16 +45,16 @@ } initial_table __initdata = { { "mangle", MANGLE_VALID_HOOKS, 6, sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error), - { [NF_IP6_PRE_ROUTING] 0, - [NF_IP6_LOCAL_IN] sizeof(struct ip6t_standard), - [NF_IP6_FORWARD] sizeof(struct ip6t_standard) * 2, - [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) * 3, - [NF_IP6_POST_ROUTING] sizeof(struct ip6t_standard) * 4}, - { [NF_IP6_PRE_ROUTING] 0, - [NF_IP6_LOCAL_IN] sizeof(struct ip6t_standard), - [NF_IP6_FORWARD] sizeof(struct ip6t_standard) * 2, - [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) * 3, - [NF_IP6_POST_ROUTING] sizeof(struct ip6t_standard) * 4}, + { [NF_IP6_PRE_ROUTING] = 0, + [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard), + [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2, + [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3, + [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4}, + { [NF_IP6_PRE_ROUTING] = 0, + [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard), + [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2, + [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3, + [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4}, 0, NULL, { } }, { /* PRE_ROUTING */ diff -Nru a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c --- a/net/ipv6/sysctl_net_ipv6.c Fri Feb 14 00:27:27 2003 +++ b/net/ipv6/sysctl_net_ipv6.c Fri Feb 14 00:27:27 2003 @@ -20,24 +20,54 @@ #ifdef CONFIG_SYSCTL ctl_table ipv6_table[] = { - {NET_IPV6_ROUTE, "route", NULL, 0, 0555, ipv6_route_table}, - {NET_IPV6_ICMP, "icmp", NULL, 0, 0500, ipv6_icmp_table}, - {NET_IPV6_BINDV6ONLY, "bindv6only", - &sysctl_ipv6_bindv6only, sizeof(int), 0644, NULL, &proc_dointvec}, - {0} + { + .ctl_name = NET_IPV6_ROUTE, + .procname = "route", + .maxlen = 0, + .mode = 0555, + .child = ipv6_route_table + }, + { + .ctl_name = NET_IPV6_ICMP, + .procname = "icmp", + .maxlen = 0, + .mode = 0500, + .child = ipv6_icmp_table + }, + { + .ctl_name = NET_IPV6_BINDV6ONLY, + .procname = "bindv6only", + .data = &sysctl_ipv6_bindv6only, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { .ctl_name = 0 } }; #ifdef MODULE static struct ctl_table_header *ipv6_sysctl_header; static ctl_table ipv6_net_table[] = { - {NET_IPV6, "ipv6", NULL, 0, 0555, ipv6_table}, - {0} + { + .ctl_name = NET_IPV6, + .procname = "ipv6", + .maxlen = 0, + .mode = 0555, + .child = ipv6_table + }, + { .ctl_name = 0 } }; static ctl_table ipv6_root_table[] = { - {CTL_NET, "net", NULL, 0, 0555, ipv6_net_table}, - {0} + { + .ctl_name = CTL_NET, + .procname = "net", + .maxlen = 0, + .mode = 0555, + .child = ipv6_net_table + }, + { .ctl_name = 0 } }; void ipv6_sysctl_register(void) diff -Nru a/net/ipv6/xfrm_policy.c b/net/ipv6/xfrm_policy.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/ipv6/xfrm_policy.c Fri Feb 14 00:27:30 2003 @@ -0,0 +1,43 @@ +#include +#include + +static struct xfrm_type *xfrm6_type_map[256]; +static rwlock_t xfrm6_type_lock = RW_LOCK_UNLOCKED; + +int xfrm6_register_type(struct xfrm_type *type) +{ + int err = 0; + + write_lock(&xfrm6_type_lock); + if (xfrm6_type_map[type->proto] == NULL) + xfrm6_type_map[type->proto] = type; + else + err = -EEXIST; + write_unlock(&xfrm6_type_lock); + return err; +} + +int xfrm6_unregister_type(struct xfrm_type *type) +{ + int err = 0; + + write_lock(&xfrm6_type_lock); + if (xfrm6_type_map[type->proto] != type) + err = -ENOENT; + else + xfrm6_type_map[type->proto] = NULL; + write_unlock(&xfrm6_type_lock); + return err; +} + +struct xfrm_type *xfrm6_get_type(u8 proto) +{ + struct xfrm_type *type; + + read_lock(&xfrm6_type_lock); + type = xfrm6_type_map[proto]; + if (type && !try_module_get(type->owner)) + type = NULL; + read_unlock(&xfrm6_type_lock); + return type; +} diff -Nru a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c --- a/net/irda/ircomm/ircomm_param.c Fri Feb 14 00:27:28 2003 +++ b/net/irda/ircomm/ircomm_param.c Fri Feb 14 00:27:28 2003 @@ -442,7 +442,9 @@ param->pv.i = self->settings.dte; else { dte = (__u8) param->pv.i; - + + self->settings.dce = 0; + if (dte & IRCOMM_DELTA_DTR) self->settings.dce |= (IRCOMM_DELTA_DSR| IRCOMM_DELTA_RI | diff -Nru a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c --- a/net/irda/ircomm/ircomm_tty.c Fri Feb 14 00:27:27 2003 +++ b/net/irda/ircomm/ircomm_tty.c Fri Feb 14 00:27:27 2003 @@ -490,7 +490,8 @@ if (line < 0x10) { self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE; self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */ - self->settings.dce = IRCOMM_CTS | IRCOMM_CD; /* Default line settings */ + /* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */ + self->settings.dce = IRCOMM_CTS | IRCOMM_CD | IRCOMM_DSR | IRCOMM_RI; /* Default line settings */ IRDA_DEBUG(2, "%s(), IrCOMM device\n", __FUNCTION__ ); } else { IRDA_DEBUG(2, "%s(), IrLPT device\n", __FUNCTION__ ); diff -Nru a/net/irda/irlap_event.c b/net/irda/irlap_event.c --- a/net/irda/irlap_event.c Fri Feb 14 00:27:29 2003 +++ b/net/irda/irlap_event.c Fri Feb 14 00:27:29 2003 @@ -1870,7 +1870,7 @@ irlap_update_nr_received(self, info->nr); irlap_wait_min_turn_around(self, &self->qos_tx); - irlap_send_rr_frame(self, CMD_FRAME); + irlap_send_rr_frame(self, RSP_FRAME); irlap_start_wd_timer(self, self->wd_timeout); } @@ -2035,18 +2035,18 @@ irlap_update_nr_received(self, info->nr); if (self->remote_busy) { irlap_wait_min_turn_around(self, &self->qos_tx); - irlap_send_rr_frame(self, CMD_FRAME); + irlap_send_rr_frame(self, RSP_FRAME); } else - irlap_resend_rejected_frames(self, CMD_FRAME); + irlap_resend_rejected_frames(self, RSP_FRAME); irlap_start_wd_timer(self, self->wd_timeout); break; case RECV_SREJ_CMD: irlap_update_nr_received(self, info->nr); if (self->remote_busy) { irlap_wait_min_turn_around(self, &self->qos_tx); - irlap_send_rr_frame(self, CMD_FRAME); + irlap_send_rr_frame(self, RSP_FRAME); } else - irlap_resend_rejected_frame(self, CMD_FRAME); + irlap_resend_rejected_frame(self, RSP_FRAME); irlap_start_wd_timer(self, self->wd_timeout); break; case WD_TIMER_EXPIRED: diff -Nru a/net/irda/irsyms.c b/net/irda/irsyms.c --- a/net/irda/irsyms.c Fri Feb 14 00:27:30 2003 +++ b/net/irda/irsyms.c Fri Feb 14 00:27:30 2003 @@ -165,6 +165,7 @@ EXPORT_SYMBOL(async_wrap_skb); EXPORT_SYMBOL(async_unwrap_char); EXPORT_SYMBOL(irda_calc_crc16); +EXPORT_SYMBOL(irda_crc16_table); EXPORT_SYMBOL(irda_start_timer); EXPORT_SYMBOL(setup_dma); EXPORT_SYMBOL(infrared_mode); diff -Nru a/net/irda/irsysctl.c b/net/irda/irsysctl.c --- a/net/irda/irsysctl.c Fri Feb 14 00:27:28 2003 +++ b/net/irda/irsysctl.c Fri Feb 14 00:27:28 2003 @@ -99,60 +99,175 @@ /* One file */ static ctl_table irda_table[] = { - { DISCOVERY, "discovery", &sysctl_discovery, - sizeof(int), 0644, NULL, &proc_dointvec }, - { DEVNAME, "devname", sysctl_devname, - 65, 0644, NULL, &do_devname, &sysctl_string}, + { + .ctl_name = DISCOVERY, + .procname = "discovery", + .data = &sysctl_discovery, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = DEVNAME, + .procname = "devname", + .data = sysctl_devname, + .maxlen = 65, + .mode = 0644, + .proc_handler = &do_devname, + .strategy = &sysctl_string + }, #ifdef CONFIG_IRDA_DEBUG - { DEBUG, "debug", &irda_debug, - sizeof(int), 0644, NULL, &proc_dointvec }, + { + .ctl_name = DEBUG, + .procname = "debug", + .data = &irda_debug, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, #endif #ifdef CONFIG_IRDA_FAST_RR - { FAST_POLL, "fast_poll_increase", &sysctl_fast_poll_increase, - sizeof(int), 0644, NULL, &proc_dointvec }, + { + .ctl_name = FAST_POLL, + .procname = "fast_poll_increase", + .data = &sysctl_fast_poll_increase, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, #endif - { DISCOVERY_SLOTS, "discovery_slots", &sysctl_discovery_slots, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, - NULL, &min_discovery_slots, &max_discovery_slots }, - { DISCOVERY_TIMEOUT, "discovery_timeout", &sysctl_discovery_timeout, - sizeof(int), 0644, NULL, &proc_dointvec }, - { SLOT_TIMEOUT, "slot_timeout", &sysctl_slot_timeout, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, - NULL, &min_slot_timeout, &max_slot_timeout }, - { MAX_BAUD_RATE, "max_baud_rate", &sysctl_max_baud_rate, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, - NULL, &min_max_baud_rate, &max_max_baud_rate }, - { MIN_TX_TURN_TIME, "min_tx_turn_time", &sysctl_min_tx_turn_time, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, - NULL, &min_min_tx_turn_time, &max_min_tx_turn_time }, - { MAX_TX_DATA_SIZE, "max_tx_data_size", &sysctl_max_tx_data_size, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, - NULL, &min_max_tx_data_size, &max_max_tx_data_size }, - { MAX_TX_WINDOW, "max_tx_window", &sysctl_max_tx_window, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, - NULL, &min_max_tx_window, &max_max_tx_window }, - { MAX_NOREPLY_TIME, "max_noreply_time", &sysctl_max_noreply_time, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, - NULL, &min_max_noreply_time, &max_max_noreply_time }, - { WARN_NOREPLY_TIME, "warn_noreply_time", &sysctl_warn_noreply_time, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, - NULL, &min_warn_noreply_time, &max_warn_noreply_time }, - { LAP_KEEPALIVE_TIME, "lap_keepalive_time", &sysctl_lap_keepalive_time, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, - NULL, &min_lap_keepalive_time, &max_lap_keepalive_time }, - { 0 } + { + .ctl_name = DISCOVERY_SLOTS, + .procname = "discovery_slots", + .data = &sysctl_discovery_slots, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_discovery_slots, + .extra2 = &max_discovery_slots + }, + { + .ctl_name = DISCOVERY_TIMEOUT, + .procname = "discovery_timeout", + .data = &sysctl_discovery_timeout, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = SLOT_TIMEOUT, + .procname = "slot_timeout", + .data = &sysctl_slot_timeout, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_slot_timeout, + .extra2 = &max_slot_timeout + }, + { + .ctl_name = MAX_BAUD_RATE, + .procname = "max_baud_rate", + .data = &sysctl_max_baud_rate, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_max_baud_rate, + .extra2 = &max_max_baud_rate + }, + { + .ctl_name = MIN_TX_TURN_TIME, + .procname = "min_tx_turn_time", + .data = &sysctl_min_tx_turn_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_min_tx_turn_time, + .extra2 = &max_min_tx_turn_time + }, + { + .ctl_name = MAX_TX_DATA_SIZE, + .procname = "max_tx_data_size", + .data = &sysctl_max_tx_data_size, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_max_tx_data_size, + .extra2 = &max_max_tx_data_size + }, + { + .ctl_name = MAX_TX_WINDOW, + .procname = "max_tx_window", + .data = &sysctl_max_tx_window, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_max_tx_window, + .extra2 = &max_max_tx_window + }, + { + .ctl_name = MAX_NOREPLY_TIME, + .procname = "max_noreply_time", + .data = &sysctl_max_noreply_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_max_noreply_time, + .extra2 = &max_max_noreply_time + }, + { + .ctl_name = WARN_NOREPLY_TIME, + .procname = "warn_noreply_time", + .data = &sysctl_warn_noreply_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_warn_noreply_time, + .extra2 = &max_warn_noreply_time + }, + { + .ctl_name = LAP_KEEPALIVE_TIME, + .procname = "lap_keepalive_time", + .data = &sysctl_lap_keepalive_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_lap_keepalive_time, + .extra2 = &max_lap_keepalive_time + }, + { .ctl_name = 0 } }; /* One directory */ static ctl_table irda_net_table[] = { - { NET_IRDA, "irda", NULL, 0, 0555, irda_table }, - { 0 } + { + .ctl_name = NET_IRDA, + .procname = "irda", + .maxlen = 0, + .mode = 0555, + .child = irda_table + }, + { .ctl_name = 0 } }; /* The parent directory */ static ctl_table irda_root_table[] = { - { CTL_NET, "net", NULL, 0, 0555, irda_net_table }, - { 0 } + { + .ctl_name = CTL_NET, + .procname = "net", + .maxlen = 0, + .mode = 0555, + .child = irda_net_table + }, + { .ctl_name = 0 } }; static struct ctl_table_header *irda_table_header; diff -Nru a/net/irda/qos.c b/net/irda/qos.c --- a/net/irda/qos.c Fri Feb 14 00:27:29 2003 +++ b/net/irda/qos.c Fri Feb 14 00:27:29 2003 @@ -722,8 +722,8 @@ i = value_index(speed, baud_rates, 10); j = value_index(max_turn_time, max_turn_times, 4); - ASSERT(((i >=0) && (i <=10)), return 0;); - ASSERT(((j >=0) && (j <=4)), return 0;); + ASSERT(((i >=0) && (i <10)), return 0;); + ASSERT(((j >=0) && (j <4)), return 0;); line_capacity = max_line_capacities[i][j]; diff -Nru a/net/irda/wrapper.c b/net/irda/wrapper.c --- a/net/irda/wrapper.c Fri Feb 14 00:27:29 2003 +++ b/net/irda/wrapper.c Fri Feb 14 00:27:29 2003 @@ -13,6 +13,7 @@ * * Copyright (c) 1998-2000 Dag Brattli , * All Rights Reserved. + * Copyright (c) 2000-2002 Jean Tourrilhes * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -37,29 +38,41 @@ #include #include -static inline int stuff_byte(__u8 byte, __u8 *buf); - -static void state_outside_frame(struct net_device *dev, - struct net_device_stats *stats, - iobuff_t *rx_buff, __u8 byte); -static void state_begin_frame(struct net_device *dev, - struct net_device_stats *stats, - iobuff_t *rx_buff, __u8 byte); -static void state_link_escape(struct net_device *dev, - struct net_device_stats *stats, - iobuff_t *rx_buff, __u8 byte); -static void state_inside_frame(struct net_device *dev, - struct net_device_stats *stats, - iobuff_t *rx_buff, __u8 byte); +/************************** FRAME WRAPPING **************************/ +/* + * Unwrap and unstuff SIR frames + * + * Note : at FIR and MIR, HDLC framing is used and usually handled + * by the controller, so we come here only for SIR... Jean II + */ -static void (*state[])(struct net_device *dev, struct net_device_stats *stats, - iobuff_t *rx_buff, __u8 byte) = +/* + * Function stuff_byte (byte, buf) + * + * Byte stuff one single byte and put the result in buffer pointed to by + * buf. The buffer must at all times be able to have two bytes inserted. + * + * This is in a tight loop, better inline it, so need to be prior to callers. + * (2000 bytes on P6 200MHz, non-inlined ~370us, inline ~170us) - Jean II + */ +static inline int stuff_byte(__u8 byte, __u8 *buf) { - state_outside_frame, - state_begin_frame, - state_link_escape, - state_inside_frame, -}; + switch (byte) { + case BOF: /* FALLTHROUGH */ + case EOF: /* FALLTHROUGH */ + case CE: + /* Insert transparently coded */ + buf[0] = CE; /* Send link escape */ + buf[1] = byte^IRDA_TRANS; /* Complement bit 5 */ + return 2; + /* break; */ + default: + /* Non-special value, no transparency required */ + buf[0] = byte; + return 1; + /* break; */ + } +} /* * Function async_wrap (skb, *tx_buff, buffsize) @@ -107,7 +120,7 @@ xbofs = 163; } - memset(tx_buff+n, XBOF, xbofs); + memset(tx_buff + n, XBOF, xbofs); n += xbofs; /* Start of packet character BOF */ @@ -140,31 +153,45 @@ return n; } +/************************* FRAME UNWRAPPING *************************/ /* - * Function stuff_byte (byte, buf) + * Unwrap and unstuff SIR frames * - * Byte stuff one single byte and put the result in buffer pointed to by - * buf. The buffer must at all times be able to have two bytes inserted. + * Complete rewrite by Jean II : + * More inline, faster, more compact, more logical. Jean II + * (16 bytes on P6 200MHz, old 5 to 7 us, new 4 to 6 us) + * (24 bytes on P6 200MHz, old 9 to 10 us, new 7 to 8 us) + * (for reference, 115200 b/s is 1 byte every 69 us) + * And reduce wrapper.o by ~900B in the process ;-) + * + * Then, we have the addition of ZeroCopy, which is optional + * (i.e. the driver must initiate it) and improve final processing. + * (2005 B frame + EOF on P6 200MHz, without 30 to 50 us, with 10 to 25 us) * + * Note : at FIR and MIR, HDLC framing is used and usually handled + * by the controller, so we come here only for SIR... Jean II */ -static inline int stuff_byte(__u8 byte, __u8 *buf) -{ - switch (byte) { - case BOF: /* FALLTHROUGH */ - case EOF: /* FALLTHROUGH */ - case CE: - /* Insert transparently coded */ - buf[0] = CE; /* Send link escape */ - buf[1] = byte^IRDA_TRANS; /* Complement bit 5 */ - return 2; - /* break; */ - default: - /* Non-special value, no transparency required */ - buf[0] = byte; - return 1; - /* break; */ - } -} + +/* + * We can also choose where we want to do the CRC calculation. We can + * do it "inline", as we receive the bytes, or "postponed", when + * receiving the End-Of-Frame. + * (16 bytes on P6 200MHz, inlined 4 to 6 us, postponed 4 to 5 us) + * (24 bytes on P6 200MHz, inlined 7 to 8 us, postponed 5 to 7 us) + * With ZeroCopy : + * (2005 B frame on P6 200MHz, inlined 10 to 25 us, postponed 140 to 180 us) + * Without ZeroCopy : + * (2005 B frame on P6 200MHz, inlined 30 to 50 us, postponed 150 to 180 us) + * (Note : numbers taken with irq disabled) + * + * From those numbers, it's not clear which is the best strategy, because + * we end up running through a lot of data one way or another (i.e. cache + * misses). I personally prefer to avoid the huge latency spike of the + * "postponed" solution, because it come just at the time when we have + * lot's of protocol processing to do and it will hurt our ability to + * reach low link turnaround times... Jean II + */ +//#define POSTPONE_RX_CRC /* * Function async_bump (buf, len, stats) @@ -172,136 +199,228 @@ * Got a frame, make a copy of it, and pass it up the stack! We can try * to inline it since it's only called from state_inside_frame */ -inline void async_bump(struct net_device *dev, struct net_device_stats *stats, - __u8 *buf, int len) +static inline void +async_bump(struct net_device *dev, + struct net_device_stats *stats, + iobuff_t *rx_buff) { - struct sk_buff *skb; - - skb = dev_alloc_skb(len+1); - if (!skb) { + struct sk_buff *newskb; + struct sk_buff *dataskb; + int docopy; + + /* Check if we need to copy the data to a new skb or not. + * If the driver doesn't use ZeroCopy Rx, we have to do it. + * With ZeroCopy Rx, the rx_buff already point to a valid + * skb. But, if the frame is small, it is more efficient to + * copy it to save memory (copy will be fast anyway - that's + * called Rx-copy-break). Jean II */ + docopy = ((rx_buff->skb == NULL) || + (rx_buff->len < IRDA_RX_COPY_THRESHOLD)); + + /* Allocate a new skb */ + newskb = dev_alloc_skb(docopy ? rx_buff->len + 1 : rx_buff->truesize); + if (!newskb) { stats->rx_dropped++; + /* We could deliver the current skb if doing ZeroCopy Rx, + * but this would stall the Rx path. Better drop the + * packet... Jean II */ return; } - /* Align IP header to 20 bytes */ - skb_reserve(skb, 1); + /* Align IP header to 20 bytes (i.e. increase skb->data) + * Note this is only useful with IrLAN, as PPP has a variable + * header size (2 or 1 bytes) - Jean II */ + skb_reserve(newskb, 1); + + if(docopy) { + /* Copy data without CRC (lenght already checked) */ + memcpy(newskb->data, rx_buff->data, rx_buff->len - 2); + /* Deliver this skb */ + dataskb = newskb; + } else { + /* We are using ZeroCopy. Deliver old skb */ + dataskb = rx_buff->skb; + /* And hook the new skb to the rx_buff */ + rx_buff->skb = newskb; + rx_buff->head = newskb->data; /* NOT newskb->head */ + //printk(KERN_DEBUG "ZeroCopy : len = %d, dataskb = %p, newskb = %p\n", rx_buff->len, dataskb, newskb); + } - /* Copy data without CRC */ - memcpy(skb_put(skb, len-2), buf, len-2); + /* Set proper length on skb (without CRC) */ + skb_put(dataskb, rx_buff->len - 2); /* Feed it to IrLAP layer */ - skb->dev = dev; - skb->mac.raw = skb->data; - skb->protocol = htons(ETH_P_IRDA); + dataskb->dev = dev; + dataskb->mac.raw = dataskb->data; + dataskb->protocol = htons(ETH_P_IRDA); - netif_rx(skb); + netif_rx(dataskb); stats->rx_packets++; - stats->rx_bytes += len; + stats->rx_bytes += rx_buff->len; + + /* Clean up rx_buff (redundant with async_unwrap_bof() ???) */ + rx_buff->data = rx_buff->head; + rx_buff->len = 0; } /* - * Function async_unwrap_char (dev, rx_buff, byte) + * Function async_unwrap_bof(dev, byte) * - * Parse and de-stuff frame received from the IrDA-port + * Handle Beggining Of Frame character received within a frame * */ -inline void async_unwrap_char(struct net_device *dev, - struct net_device_stats *stats, - iobuff_t *rx_buff, __u8 byte) +static inline void +async_unwrap_bof(struct net_device *dev, + struct net_device_stats *stats, + iobuff_t *rx_buff, __u8 byte) { - (*state[rx_buff->state])(dev, stats, rx_buff, byte); + switch(rx_buff->state) { + case LINK_ESCAPE: + case INSIDE_FRAME: + /* Not supposed to happen, the previous frame is not + * finished - Jean II */ + IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n", + __FUNCTION__); + stats->rx_errors++; + stats->rx_missed_errors++; + irda_device_set_media_busy(dev, TRUE); + break; + + case OUTSIDE_FRAME: + case BEGIN_FRAME: + default: + /* We may receive multiple BOF at the start of frame */ + break; + } + + /* Now receiving frame */ + rx_buff->state = BEGIN_FRAME; + rx_buff->in_frame = TRUE; + + /* Time to initialize receive buffer */ + rx_buff->data = rx_buff->head; + rx_buff->len = 0; + rx_buff->fcs = INIT_FCS; } /* - * Function state_outside_frame (dev, rx_buff, byte) + * Function async_unwrap_eof(dev, byte) * - * Not receiving any frame (or just bogus data) + * Handle End Of Frame character received within a frame * */ -static void state_outside_frame(struct net_device *dev, - struct net_device_stats *stats, - iobuff_t *rx_buff, __u8 byte) +static inline void +async_unwrap_eof(struct net_device *dev, + struct net_device_stats *stats, + iobuff_t *rx_buff, __u8 byte) { - switch (byte) { - case BOF: - rx_buff->state = BEGIN_FRAME; - rx_buff->in_frame = TRUE; - break; - case XBOF: - /* idev->xbofs++; */ - break; - case EOF: +#ifdef POSTPONE_RX_CRC + int i; +#endif + + switch(rx_buff->state) { + case OUTSIDE_FRAME: + /* Probably missed the BOF */ + stats->rx_errors++; + stats->rx_missed_errors++; irda_device_set_media_busy(dev, TRUE); break; + + case BEGIN_FRAME: + case LINK_ESCAPE: + case INSIDE_FRAME: default: - irda_device_set_media_busy(dev, TRUE); + /* Note : in the case of BEGIN_FRAME and LINK_ESCAPE, + * the fcs will most likely not match and generate an + * error, as expected - Jean II */ + rx_buff->state = OUTSIDE_FRAME; + rx_buff->in_frame = FALSE; + +#ifdef POSTPONE_RX_CRC + /* If we haven't done the CRC as we receive bytes, we + * must do it now... Jean II */ + for(i = 0; i < rx_buff->len; i++) + rx_buff->fcs = irda_fcs(rx_buff->fcs, + rx_buff->data[i]); +#endif + + /* Test FCS and signal success if the frame is good */ + if (rx_buff->fcs == GOOD_FCS) { + /* Deliver frame */ + async_bump(dev, stats, rx_buff); + break; + } else { + /* Wrong CRC, discard frame! */ + irda_device_set_media_busy(dev, TRUE); + + IRDA_DEBUG(1, "%s(), crc error\n", __FUNCTION__); + stats->rx_errors++; + stats->rx_crc_errors++; + } break; } } /* - * Function state_begin_frame (idev, byte) + * Function async_unwrap_ce(dev, byte) * - * Begin of frame detected + * Handle Character Escape character received within a frame * */ -static void state_begin_frame(struct net_device *dev, - struct net_device_stats *stats, - iobuff_t *rx_buff, __u8 byte) +static inline void +async_unwrap_ce(struct net_device *dev, + struct net_device_stats *stats, + iobuff_t *rx_buff, __u8 byte) { - /* Time to initialize receive buffer */ - rx_buff->data = rx_buff->head; - rx_buff->len = 0; - rx_buff->fcs = INIT_FCS; - - switch (byte) { - case BOF: - /* Continue */ - break; - case CE: - /* Stuffed byte */ - rx_buff->state = LINK_ESCAPE; + switch(rx_buff->state) { + case OUTSIDE_FRAME: + /* Activate carrier sense */ + irda_device_set_media_busy(dev, TRUE); break; - case EOF: - /* Abort frame */ - rx_buff->state = OUTSIDE_FRAME; - IRDA_DEBUG(1, "%s(), abort frame\n", __FUNCTION__); - stats->rx_errors++; - stats->rx_frame_errors++; + + case LINK_ESCAPE: + WARNING("%s: state not defined\n", __FUNCTION__); break; + + case BEGIN_FRAME: + case INSIDE_FRAME: default: - rx_buff->data[rx_buff->len++] = byte; - rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); - rx_buff->state = INSIDE_FRAME; + /* Stuffed byte comming */ + rx_buff->state = LINK_ESCAPE; break; } } /* - * Function state_link_escape (dev, byte) + * Function async_unwrap_other(dev, byte) * - * Found link escape character + * Handle other characters received within a frame * */ -static void state_link_escape(struct net_device *dev, - struct net_device_stats *stats, - iobuff_t *rx_buff, __u8 byte) +static inline void +async_unwrap_other(struct net_device *dev, + struct net_device_stats *stats, + iobuff_t *rx_buff, __u8 byte) { - switch (byte) { - case BOF: /* New frame? */ - IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n", - __FUNCTION__); - rx_buff->state = BEGIN_FRAME; - irda_device_set_media_busy(dev, TRUE); - break; - case CE: - WARNING("%s: state not defined\n", __FUNCTION__); - break; - case EOF: /* Abort frame */ - rx_buff->state = OUTSIDE_FRAME; + switch(rx_buff->state) { + /* This is on the critical path, case are ordered by + * probability (most frequent first) - Jean II */ + case INSIDE_FRAME: + /* Must be the next byte of the frame */ + if (rx_buff->len < rx_buff->truesize) { + rx_buff->data[rx_buff->len++] = byte; +#ifndef POSTPONE_RX_CRC + rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); +#endif + } else { + IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n", + __FUNCTION__); + rx_buff->state = OUTSIDE_FRAME; + } break; - default: + + case LINK_ESCAPE: /* * Stuffed char, complement bit 5 of byte * following CE, IrLAP p.114 @@ -309,67 +428,58 @@ byte ^= IRDA_TRANS; if (rx_buff->len < rx_buff->truesize) { rx_buff->data[rx_buff->len++] = byte; +#ifndef POSTPONE_RX_CRC rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); +#endif rx_buff->state = INSIDE_FRAME; } else { - IRDA_DEBUG(1, "%s(), rx buffer overflow\n", + IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n", __FUNCTION__); rx_buff->state = OUTSIDE_FRAME; } break; + + case OUTSIDE_FRAME: + /* Activate carrier sense */ + if(byte != XBOF) + irda_device_set_media_busy(dev, TRUE); + break; + + case BEGIN_FRAME: + default: + rx_buff->data[rx_buff->len++] = byte; +#ifndef POSTPONE_RX_CRC + rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); +#endif + rx_buff->state = INSIDE_FRAME; + break; } } /* - * Function state_inside_frame (dev, byte) + * Function async_unwrap_char (dev, rx_buff, byte) * - * Handle bytes received within a frame + * Parse and de-stuff frame received from the IrDA-port * + * This is the main entry point for SIR drivers. */ -static void state_inside_frame(struct net_device *dev, - struct net_device_stats *stats, - iobuff_t *rx_buff, __u8 byte) +void async_unwrap_char(struct net_device *dev, + struct net_device_stats *stats, + iobuff_t *rx_buff, __u8 byte) { - int ret = 0; - - switch (byte) { - case BOF: /* New frame? */ - IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n", - __FUNCTION__); - rx_buff->state = BEGIN_FRAME; - irda_device_set_media_busy(dev, TRUE); + switch(byte) { + case CE: + async_unwrap_ce(dev, stats, rx_buff, byte); break; - case CE: /* Stuffed char */ - rx_buff->state = LINK_ESCAPE; + case BOF: + async_unwrap_bof(dev, stats, rx_buff, byte); break; - case EOF: /* End of frame */ - rx_buff->state = OUTSIDE_FRAME; - rx_buff->in_frame = FALSE; - - /* Test FCS and signal success if the frame is good */ - if (rx_buff->fcs == GOOD_FCS) { - /* Deliver frame */ - async_bump(dev, stats, rx_buff->data, rx_buff->len); - ret = TRUE; - break; - } else { - /* Wrong CRC, discard frame! */ - irda_device_set_media_busy(dev, TRUE); - - IRDA_DEBUG(1, "%s(), crc error\n", __FUNCTION__); - stats->rx_errors++; - stats->rx_crc_errors++; - } + case EOF: + async_unwrap_eof(dev, stats, rx_buff, byte); break; - default: /* Must be the next byte of the frame */ - if (rx_buff->len < rx_buff->truesize) { - rx_buff->data[rx_buff->len++] = byte; - rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); - } else { - IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n", - __FUNCTION__); - rx_buff->state = OUTSIDE_FRAME; - } + default: + async_unwrap_other(dev, stats, rx_buff, byte); break; } } + diff -Nru a/net/key/af_key.c b/net/key/af_key.c --- a/net/key/af_key.c Fri Feb 14 00:27:27 2003 +++ b/net/key/af_key.c Fri Feb 14 00:27:27 2003 @@ -9,6 +9,7 @@ * Authors: Maxim Giryaev * David S. Miller * Alexey Kuznetsov + * Kunihiro Ishiguro */ #include @@ -351,7 +352,9 @@ struct sadb_address *sp = p; struct sockaddr *addr = (struct sockaddr *)(sp + 1); struct sockaddr_in *sin; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) struct sockaddr_in6 *sin6; +#endif int len; switch (addr->sa_family) { @@ -362,7 +365,7 @@ sp->sadb_address_prefixlen > 32) return -EINVAL; break; - +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) case AF_INET6: len = sizeof(*sp) + sizeof(*sin6) + (sizeof(uint64_t) - 1); len /= sizeof(uint64_t); @@ -370,7 +373,7 @@ sp->sadb_address_prefixlen > 128) return -EINVAL; break; - +#endif default: /* It is user using kernel to keep track of security * associations for another protocol, such as @@ -400,7 +403,11 @@ d_addr = (struct sockaddr *)(dst + 1); if (s_addr->sa_family != d_addr->sa_family) return 0; - if (s_addr->sa_family != AF_INET) + if (s_addr->sa_family != AF_INET +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + && s_addr->sa_family != AF_INET6 +#endif + ) return 0; return 1; @@ -497,25 +504,27 @@ return (proto ? proto : IPSEC_PROTO_ANY); } -static xfrm_address_t *pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, - xfrm_address_t *xaddr) +static int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, + xfrm_address_t *xaddr) { switch (((struct sockaddr*)(addr + 1))->sa_family) { case AF_INET: xaddr->xfrm4_addr = - ((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr; + ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr; if (addr->sadb_address_prefixlen) xaddr->xfrm4_mask = htonl(~0 << (32 - addr->sadb_address_prefixlen)); - break; + return AF_INET; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) case AF_INET6: memcpy(xaddr->a6, - &((struct sockaddr_in6*)(addr + 1))->sin6_addr, - sizeof(xaddr->a6)); + &((struct sockaddr_in6 *)(addr + 1))->sin6_addr, + sizeof(struct in6_addr)); + return AF_INET6; +#endif default: - return NULL; + return 0; } - - return xaddr; + /* NOTREACHED */ } static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs) @@ -540,11 +549,15 @@ switch (((struct sockaddr *)(addr + 1))->sa_family) { case AF_INET: - x = xfrm_state_lookup(((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr, + x = xfrm_state_lookup(((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr, sa->sadb_sa_spi, proto); break; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) case AF_INET6: - /* XXX handle IPv6 */ + x = xfrm6_state_lookup(&((struct sockaddr_in6 *)(addr + 1))->sin6_addr, + sa->sadb_sa_spi, proto); + break; +#endif default: x = NULL; break; @@ -554,6 +567,22 @@ } #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) +static int +pfkey_sockaddr_size(sa_family_t family) +{ + switch (family) { + case AF_INET: + return PFKEY_ALIGN8(sizeof(struct sockaddr_in)); +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + return PFKEY_ALIGN8(sizeof(struct sockaddr_in6)); +#endif + default: + return 0; + } + /* NOTREACHED */ +} + static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, int hsc) { struct sk_buff *skb; @@ -563,9 +592,19 @@ struct sadb_address *addr; struct sadb_key *key; struct sadb_x_sa2 *sa2; + struct sockaddr_in *sin; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; +#endif int size; int auth_key_size = 0; int encrypt_key_size = 0; + int sockaddr_size; + + /* address family check */ + sockaddr_size = pfkey_sockaddr_size(x->props.family); + if (!sockaddr_size) + ERR_PTR(-EINVAL); /* base, SA, (lifetime (HSC),) address(SD), (address(P),) key(AE), (identity(SD),) (sensitivity)> */ @@ -574,13 +613,18 @@ ((hsc & 1) ? sizeof(struct sadb_lifetime) : 0) + ((hsc & 2) ? sizeof(struct sadb_lifetime) : 0) + sizeof(struct sadb_address)*2 + - sizeof(struct sockaddr_in)*2 + /* XXX */ + sockaddr_size*2 + sizeof(struct sadb_x_sa2); - /* XXX identity & sensitivity */ + /* identity & sensitivity */ - if (x->sel.saddr.xfrm4_addr != x->props.saddr.xfrm4_addr) - size += sizeof(struct sadb_address) + - sizeof(struct sockaddr_in); /* XXX */ + if ((x->props.family == AF_INET && + x->sel.saddr.xfrm4_addr != x->props.saddr.xfrm4_addr) +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + || (x->props.family == AF_INET6 && + memcmp (x->sel.saddr.a6, x->props.saddr.a6, sizeof (struct in6_addr))) +#endif + ) + size += sizeof(struct sadb_address) + sockaddr_size; if (add_keys) { if (x->aalg && x->aalg->alg_key_len) { @@ -664,50 +708,113 @@ lifetime->sadb_lifetime_usetime = x->curlft.use_time; /* src address */ addr = (struct sadb_address*) skb_put(skb, - sizeof(struct sadb_address)+sizeof(struct sockaddr_in)); + sizeof(struct sadb_address)+sockaddr_size); addr->sadb_address_len = - (sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/ + (sizeof(struct sadb_address)+sockaddr_size)/ sizeof(uint64_t); addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; /* "if the ports are non-zero, then the sadb_address_proto field, normally zero, MUST be filled in with the transport protocol's number." - RFC2367 */ addr->sadb_address_proto = 0; - addr->sadb_address_prefixlen = 32; /* XXX */ addr->sadb_address_reserved = 0; - ((struct sockaddr_in*)(addr + 1))->sin_family = AF_INET; - ((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr = - x->props.saddr.xfrm4_addr; + if (x->props.family == AF_INET) { + addr->sadb_address_prefixlen = 32; + + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = x->props.saddr.xfrm4_addr; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (x->props.family == AF_INET6) { + addr->sadb_address_prefixlen = 128; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, x->props.saddr.a6, + sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else + BUG(); + /* dst address */ addr = (struct sadb_address*) skb_put(skb, - sizeof(struct sadb_address)+sizeof(struct sockaddr_in)); + sizeof(struct sadb_address)+sockaddr_size); addr->sadb_address_len = - (sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/ + (sizeof(struct sadb_address)+sockaddr_size)/ sizeof(uint64_t); addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; addr->sadb_address_proto = 0; addr->sadb_address_prefixlen = 32; /* XXX */ addr->sadb_address_reserved = 0; - ((struct sockaddr_in*)(addr + 1))->sin_family = AF_INET; - ((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr = - x->id.daddr.xfrm4_addr; - - if (x->sel.saddr.xfrm4_addr != x->props.saddr.xfrm4_addr) { - addr = (struct sadb_address*) skb_put(skb, - sizeof(struct sadb_address)+sizeof(struct sockaddr_in)); - addr->sadb_address_len = - (sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/ + if (x->props.family == AF_INET) { + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = x->id.daddr.xfrm4_addr; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + + if (x->sel.saddr.xfrm4_addr != x->props.saddr.xfrm4_addr) { + addr = (struct sadb_address*) skb_put(skb, + sizeof(struct sadb_address)+sockaddr_size); + addr->sadb_address_len = + (sizeof(struct sadb_address)+sockaddr_size)/ + sizeof(uint64_t); + addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; + addr->sadb_address_proto = + pfkey_proto_from_xfrm(x->sel.proto); + addr->sadb_address_prefixlen = x->sel.prefixlen_s; + addr->sadb_address_reserved = 0; + + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = x->sel.saddr.xfrm4_addr; + sin->sin_port = x->sel.sport; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (x->props.family == AF_INET6) { + addr->sadb_address_prefixlen = 128; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, x->id.daddr.a6, sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + + if (memcmp (x->sel.saddr.a6, x->props.saddr.a6, + sizeof(struct in6_addr))) { + addr = (struct sadb_address *) skb_put(skb, + sizeof(struct sadb_address)+sockaddr_size); + addr->sadb_address_len = + (sizeof(struct sadb_address)+sockaddr_size)/ sizeof(uint64_t); - addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; - addr->sadb_address_proto = pfkey_proto_from_xfrm(x->sel.proto); - addr->sadb_address_prefixlen = x->sel.prefixlen_s; - addr->sadb_address_reserved = 0; - ((struct sockaddr_in*)(addr + 1))->sin_family = AF_INET; - ((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr = - x->sel.saddr.xfrm4_addr; - ((struct sockaddr_in*)(addr + 1))->sin_port = - x->sel.sport; + addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; + addr->sadb_address_proto = + pfkey_proto_from_xfrm(x->sel.proto); + addr->sadb_address_prefixlen = x->sel.prefixlen_s; + addr->sadb_address_reserved = 0; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = x->sel.sport; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, x->sel.saddr.a6, + sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } } +#endif + else + BUG(); /* auth key */ if (add_keys && auth_key_size) { @@ -797,6 +904,7 @@ return ERR_PTR(-EINVAL); key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1]; if (key != NULL && + sa->sadb_sa_encrypt != SADB_EALG_NULL && ((key->sadb_key_bits+7) / 8 == 0 || (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) return ERR_PTR(-EINVAL); @@ -864,8 +972,10 @@ } /* x->algo.flags = sa->sadb_sa_flags; */ - pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_SRC-1], - &x->props.saddr); + x->props.family = pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_SRC-1], + &x->props.saddr); + if (!x->props.family) + goto out; pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_DST-1], &x->id.daddr); @@ -885,7 +995,20 @@ x->sel.prefixlen_s = addr->sadb_address_prefixlen; } - x->type = xfrm_get_type(proto); + switch (x->props.family) { + case AF_INET: + x->type = xfrm_get_type(proto); + break; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + x->type = xfrm6_get_type(proto); + break; +#endif + default: + x->type = NULL; + break; + } + if (x->type == NULL) goto out; if (x->type->init_state(x, NULL)) @@ -912,8 +1035,7 @@ { struct sk_buff *resp_skb; struct sadb_x_sa2 *sa2; - struct sadb_address *addr; - struct sockaddr_in *saddr, *daddr; + struct sadb_address *saddr, *daddr; struct sadb_msg *out_hdr; struct xfrm_state *x; u8 mode; @@ -936,13 +1058,27 @@ reqid = 0; } - addr = ext_hdrs[SADB_EXT_ADDRESS_SRC-1]; - saddr = (struct sockaddr_in*)(addr + 1); - addr = ext_hdrs[SADB_EXT_ADDRESS_DST-1]; - daddr = (struct sockaddr_in*)(addr + 1); + saddr = ext_hdrs[SADB_EXT_ADDRESS_SRC-1]; + daddr = ext_hdrs[SADB_EXT_ADDRESS_DST-1]; + + switch (((struct sockaddr *)(saddr + 1))->sa_family) { + case AF_INET: + x = xfrm_find_acq(mode, reqid, proto, + ((struct sockaddr_in *)(daddr + 1))->sin_addr.s_addr, + ((struct sockaddr_in *)(saddr + 1))->sin_addr.s_addr, 1); + break; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + x = xfrm6_find_acq(mode, reqid, proto, + &((struct sockaddr_in6 *)(daddr + 1))->sin6_addr, + &((struct sockaddr_in6 *)(saddr + 1))->sin6_addr, 1); + break; +#endif + default: + x = NULL; + break; + } - x = xfrm_find_acq(mode, reqid, proto, daddr->sin_addr.s_addr, - saddr->sin_addr.s_addr, 1); if (x == NULL) return -ENOENT; @@ -960,7 +1096,18 @@ min_spi = htonl(0x100); max_spi = htonl(0x0fffffff); } - xfrm_alloc_spi(x, min_spi, max_spi); + switch (x->props.family) { + case AF_INET: + xfrm_alloc_spi(x, min_spi, max_spi); + break; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + xfrm6_alloc_spi(x, min_spi, max_spi); + break; +#endif + default: + break; + } if (x->id.spi) resp_skb = pfkey_xfrm_state2msg(x, 0, 3); } @@ -1028,9 +1175,23 @@ /* XXX there is race condition */ x1 = pfkey_xfrm_state_lookup(hdr, ext_hdrs); if (!x1) { - x1 = xfrm_find_acq(x->props.mode, x->props.reqid, x->id.proto, - x->id.daddr.xfrm4_addr, - x->props.saddr.xfrm4_addr, 0); + switch (x->props.family) { + case AF_INET: + x1 = xfrm_find_acq(x->props.mode, x->props.reqid, x->id.proto, + x->id.daddr.xfrm4_addr, + x->props.saddr.xfrm4_addr, 0); + break; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + x1 = xfrm6_find_acq(x->props.mode, x->props.reqid, x->id.proto, + (struct in6_addr*)x->id.daddr.a6, + (struct in6_addr*)x->props.saddr.a6, 0); + break; +#endif + default: + x1 = NULL; + break; + } if (x1 && x1->id.spi != x->id.spi && x1->id.spi) { xfrm_state_put(x1); x1 = NULL; @@ -1339,7 +1500,10 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) { struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; - struct sockaddr_in *addr; + struct sockaddr_in *sin; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; +#endif if (xp->xfrm_nr >= XFRM_MAX_DEPTH) return -ELOOP; @@ -1361,10 +1525,32 @@ /* addresses present only in tunnel mode */ if (t->mode) { - addr = (void*)(rq+1); - t->saddr.xfrm4_addr = addr->sin_addr.s_addr; - addr++; - t->id.daddr.xfrm4_addr = addr->sin_addr.s_addr; + switch (xp->family) { + case AF_INET: + sin = (void*)(rq+1); + if (sin->sin_family != AF_INET) + return -EINVAL; + t->saddr.xfrm4_addr = sin->sin_addr.s_addr; + sin++; + if (sin->sin_family != AF_INET) + return -EINVAL; + t->id.daddr.xfrm4_addr = sin->sin_addr.s_addr; + break; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + sin6 = (void *)(rq+1); + if (sin6->sin6_family != AF_INET6) + return -EINVAL; + memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr)); + sin6++; + if (sin6->sin6_family != AF_INET6) + return -EINVAL; + memcpy(t->id.daddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr)); + break; +#endif + default: + return -EINVAL; + } } /* No way to set this via kame pfkey */ t->aalgos = t->ealgos = t->calgos = ~0; @@ -1388,28 +1574,54 @@ return 0; } -static struct sk_buff * pfkey_xfrm_policy2msg(struct xfrm_policy *xp, int dir) +static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp) +{ + int sockaddr_size = pfkey_sockaddr_size(xp->family); + int socklen = (xp->family == AF_INET ? + sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6)); + + return sizeof(struct sadb_msg) + + (sizeof(struct sadb_lifetime) * 3) + + (sizeof(struct sadb_address) * 2) + + (sockaddr_size * 2) + + sizeof(struct sadb_x_policy) + + (xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) + + (socklen * 2))); +} + +static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp) { struct sk_buff *skb; + int size; + + size = pfkey_xfrm_policy2msg_size(xp); + + skb = alloc_skb(size + 16, GFP_ATOMIC); + if (skb == NULL) + return ERR_PTR(-ENOBUFS); + + return skb; +} + +static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, int dir) +{ struct sadb_msg *hdr; struct sadb_address *addr; struct sadb_lifetime *lifetime; struct sadb_x_policy *pol; struct sockaddr_in *sin; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; +#endif int i; int size; + int sockaddr_size = pfkey_sockaddr_size(xp->family); + int socklen = (xp->family == AF_INET ? + sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6)); - size = sizeof(struct sadb_msg) + - sizeof(struct sadb_lifetime) * 3 + - sizeof(struct sadb_address)*2 + - sizeof(struct sockaddr_in)*2 + /* XXX */ - sizeof(struct sadb_x_policy) + - xp->xfrm_nr*(sizeof(struct sadb_x_ipsecrequest) + - sizeof(struct sockaddr_in)*2); - - skb = alloc_skb(size + 16, GFP_ATOMIC); - if (skb == NULL) - return ERR_PTR(-ENOBUFS); + size = pfkey_xfrm_policy2msg_size(xp); /* call should fill header later */ hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg)); @@ -1417,35 +1629,66 @@ /* src address */ addr = (struct sadb_address*) skb_put(skb, - sizeof(struct sadb_address)+sizeof(struct sockaddr_in)); + sizeof(struct sadb_address)+sockaddr_size); addr->sadb_address_len = - (sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/ + (sizeof(struct sadb_address)+sockaddr_size)/ sizeof(uint64_t); addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); addr->sadb_address_prefixlen = xp->selector.prefixlen_s; addr->sadb_address_reserved = 0; /* src address */ - sin = (struct sockaddr_in*)(addr + 1); - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = xp->selector.saddr.xfrm4_addr; - sin->sin_port = xp->selector.sport; - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + if (xp->family == AF_INET) { + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = xp->selector.saddr.xfrm4_addr; + sin->sin_port = xp->selector.sport; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (xp->family == AF_INET6) { + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = xp->selector.sport; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, xp->selector.saddr.a6, + sizeof(struct in6_addr));; + sin6->sin6_scope_id = 0; + } +#endif + else + BUG(); + /* dst address */ addr = (struct sadb_address*) skb_put(skb, - sizeof(struct sadb_address)+sizeof(struct sockaddr_in)); + sizeof(struct sadb_address)+sockaddr_size); addr->sadb_address_len = - (sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/ + (sizeof(struct sadb_address)+sockaddr_size)/ sizeof(uint64_t); addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); addr->sadb_address_prefixlen = xp->selector.prefixlen_d; addr->sadb_address_reserved = 0; - sin = (struct sockaddr_in*)(addr + 1); - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = xp->selector.daddr.xfrm4_addr; - sin->sin_port = xp->selector.dport; - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + if (xp->family == AF_INET) { + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = xp->selector.daddr.xfrm4_addr; + sin->sin_port = xp->selector.dport; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (xp->family == AF_INET6) { + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = xp->selector.dport; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, xp->selector.daddr.a6, + sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else + BUG(); /* hard time */ lifetime = (struct sadb_lifetime *) skb_put(skb, @@ -1498,9 +1741,9 @@ req_size = sizeof(struct sadb_x_ipsecrequest); if (t->mode) - req_size += 2*sizeof(struct sockaddr_in); - else - size -= 2*sizeof(struct sockaddr_in); + req_size += 2*socklen; + else + size -= 2*socklen; rq = (void*)skb_put(skb, req_size); pol->sadb_x_policy_len += req_size/8; rq->sadb_x_ipsecrequest_len = req_size; @@ -1513,21 +1756,45 @@ rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE; rq->sadb_x_ipsecrequest_reqid = t->reqid; if (t->mode) { - sin = (void*)(rq+1); - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = t->saddr.xfrm4_addr; - sin->sin_port = 0; - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); - sin++; - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = t->id.daddr.xfrm4_addr; - sin->sin_port = 0; - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + switch (xp->family) { + case AF_INET: + sin = (void*)(rq+1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = t->saddr.xfrm4_addr; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + sin++; + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = t->id.daddr.xfrm4_addr; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + break; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + sin6 = (void*)(rq+1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, t->saddr.a6, + sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + + sin6++; + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, t->id.daddr.a6, + sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + break; +#endif + default: + break; + } } } hdr->sadb_msg_len = size / sizeof(uint64_t); hdr->sadb_msg_reserved = atomic_read(&xp->refcnt); - return skb; } static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) @@ -1559,10 +1826,14 @@ XFRM_POLICY_BLOCK : XFRM_POLICY_ALLOW); sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1], - pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.saddr); + xp->family = pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.saddr); + if (!xp->family) { + err = -EINVAL; + goto out; + } xp->selector.prefixlen_s = sa->sadb_address_prefixlen; xp->selector.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto); - xp->selector.sport = ((struct sockaddr_in*)(sa+1))->sin_port; + xp->selector.sport = ((struct sockaddr_in *)(sa+1))->sin_port; if (xp->selector.sport) xp->selector.sport_mask = ~0; @@ -1575,7 +1846,7 @@ */ xp->selector.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto); - xp->selector.dport = ((struct sockaddr_in*)(sa+1))->sin_port; + xp->selector.dport = ((struct sockaddr_in *)(sa+1))->sin_port; if (xp->selector.dport) xp->selector.dport_mask = ~0; @@ -1600,7 +1871,7 @@ (err = parse_ipsecrequests(xp, pol)) < 0) goto out; - out_skb = pfkey_xfrm_policy2msg(xp, pol->sadb_x_policy_dir-1); + out_skb = pfkey_xfrm_policy2msg_prep(xp); if (IS_ERR(out_skb)) { err = PTR_ERR(out_skb); goto out; @@ -1613,6 +1884,8 @@ goto out; } + pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1); + xfrm_pol_put(xp); out_hdr = (struct sadb_msg *) out_skb->data; @@ -1655,7 +1928,7 @@ pfkey_sadb_addr2xfrm_addr(sa, &sel.saddr); sel.prefixlen_s = sa->sadb_address_prefixlen; sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto); - sel.sport = ((struct sockaddr_in*)(sa+1))->sin_port; + sel.sport = ((struct sockaddr_in *)(sa+1))->sin_port; if (sel.sport) sel.sport_mask = ~0; @@ -1663,7 +1936,7 @@ pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr); sel.prefixlen_d = sa->sadb_address_prefixlen; sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto); - sel.dport = ((struct sockaddr_in*)(sa+1))->sin_port; + sel.dport = ((struct sockaddr_in *)(sa+1))->sin_port; if (sel.dport) sel.dport_mask = ~0; @@ -1673,11 +1946,12 @@ err = 0; - out_skb = pfkey_xfrm_policy2msg(xp, pol->sadb_x_policy_dir-1); + out_skb = pfkey_xfrm_policy2msg_prep(xp); if (IS_ERR(out_skb)) { err = PTR_ERR(out_skb); goto out; } + pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1); out_hdr = (struct sadb_msg *) out_skb->data; out_hdr->sadb_msg_version = hdr->sadb_msg_version; @@ -1715,11 +1989,12 @@ err = 0; - out_skb = pfkey_xfrm_policy2msg(xp, pol->sadb_x_policy_dir-1); + out_skb = pfkey_xfrm_policy2msg_prep(xp); if (IS_ERR(out_skb)) { err = PTR_ERR(out_skb); goto out; } + pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1); out_hdr = (struct sadb_msg *) out_skb->data; out_hdr->sadb_msg_version = hdr->sadb_msg_version; @@ -1746,10 +2021,12 @@ struct sk_buff *out_skb; struct sadb_msg *out_hdr; - out_skb = pfkey_xfrm_policy2msg(xp, dir); + out_skb = pfkey_xfrm_policy2msg_prep(xp); if (IS_ERR(out_skb)) return PTR_ERR(out_skb); + pfkey_xfrm_policy2msg(out_skb, xp, dir); + out_hdr = (struct sadb_msg *) out_skb->data; out_hdr->sadb_msg_version = data->hdr->sadb_msg_version; out_hdr->sadb_msg_type = SADB_X_SPDDUMP; @@ -2023,12 +2300,21 @@ struct sadb_msg *hdr; struct sadb_address *addr; struct sadb_x_policy *pol; + struct sockaddr_in *sin; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; +#endif + int sockaddr_size; int size; + sockaddr_size = pfkey_sockaddr_size(x->props.family); + if (!sockaddr_size) + return -EINVAL; + size = sizeof(struct sadb_msg) + - sizeof(struct sadb_address)*2 + - sizeof(struct sockaddr_in)*2 + /* XXX */ - sizeof(struct sadb_x_policy); + (sizeof(struct sadb_address) * 2) + + (sockaddr_size * 2) + + sizeof(struct sadb_x_policy); if (x->id.proto == IPPROTO_AH) size += count_ah_combs(t); @@ -2051,33 +2337,71 @@ /* src address */ addr = (struct sadb_address*) skb_put(skb, - sizeof(struct sadb_address)+sizeof(struct sockaddr_in)); + sizeof(struct sadb_address)+sockaddr_size); addr->sadb_address_len = - (sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/ + (sizeof(struct sadb_address)+sockaddr_size)/ sizeof(uint64_t); addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; addr->sadb_address_proto = 0; - addr->sadb_address_prefixlen = 32; addr->sadb_address_reserved = 0; - ((struct sockaddr_in*)(addr + 1))->sin_family = AF_INET; - ((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr = - x->props.saddr.xfrm4_addr; - ((struct sockaddr_in*)(addr + 1))->sin_port = 0; + if (x->props.family == AF_INET) { + addr->sadb_address_prefixlen = 32; + + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = x->props.saddr.xfrm4_addr; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (x->props.family == AF_INET6) { + addr->sadb_address_prefixlen = 128; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, + x->props.saddr.a6, sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else + BUG(); /* dst address */ addr = (struct sadb_address*) skb_put(skb, - sizeof(struct sadb_address)+sizeof(struct sockaddr_in)); + sizeof(struct sadb_address)+sockaddr_size); addr->sadb_address_len = - (sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/ + (sizeof(struct sadb_address)+sockaddr_size)/ sizeof(uint64_t); addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; addr->sadb_address_proto = 0; - addr->sadb_address_prefixlen = 32; addr->sadb_address_reserved = 0; - ((struct sockaddr_in*)(addr + 1))->sin_family = AF_INET; - ((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr = - x->id.daddr.xfrm4_addr; - ((struct sockaddr_in*)(addr + 1))->sin_port = 0; + if (x->props.family == AF_INET) { + addr->sadb_address_prefixlen = 32; + + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = x->id.daddr.xfrm4_addr; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (x->props.family == AF_INET6) { + addr->sadb_address_prefixlen = 128; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, + x->id.daddr.a6, sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else + BUG(); pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy)); pol->sadb_x_policy_len = sizeof(struct sadb_x_policy)/sizeof(uint64_t); diff -Nru a/net/netsyms.c b/net/netsyms.c --- a/net/netsyms.c Fri Feb 14 00:27:28 2003 +++ b/net/netsyms.c Fri Feb 14 00:27:28 2003 @@ -324,6 +324,11 @@ EXPORT_SYMBOL(xfrm_policy_flush); EXPORT_SYMBOL(xfrm_policy_byid); EXPORT_SYMBOL(xfrm_policy_list); +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +EXPORT_SYMBOL(xfrm6_state_lookup); +EXPORT_SYMBOL(xfrm6_find_acq); +EXPORT_SYMBOL(xfrm6_alloc_spi); +#endif EXPORT_SYMBOL_GPL(xfrm_probe_algs); EXPORT_SYMBOL_GPL(xfrm_count_auth_supported); diff -Nru a/net/rxrpc/internal.h b/net/rxrpc/internal.h --- a/net/rxrpc/internal.h Fri Feb 14 00:27:27 2003 +++ b/net/rxrpc/internal.h Fri Feb 14 00:27:27 2003 @@ -55,7 +55,7 @@ siginfo_t sinfo; spin_lock_irq(¤t->sighand->siglock); - dequeue_signal(¤t->blocked,&sinfo); + dequeue_signal(current,¤t->blocked,&sinfo); spin_unlock_irq(¤t->sighand->siglock); } } diff -Nru a/net/rxrpc/krxiod.c b/net/rxrpc/krxiod.c --- a/net/rxrpc/krxiod.c Fri Feb 14 00:27:26 2003 +++ b/net/rxrpc/krxiod.c Fri Feb 14 00:27:26 2003 @@ -42,15 +42,8 @@ DECLARE_WAITQUEUE(krxiod,current); printk("Started krxiod %d\n",current->pid); - strcpy(current->comm,"krxiod"); - daemonize(); - - /* only certain signals are of interest */ - spin_lock_irq(¤t->sighand->siglock); - siginitsetinv(¤t->blocked,0); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + daemonize("krxiod"); /* loop around waiting for work to do */ do { diff -Nru a/net/rxrpc/krxsecd.c b/net/rxrpc/krxsecd.c --- a/net/rxrpc/krxsecd.c Fri Feb 14 00:27:27 2003 +++ b/net/rxrpc/krxsecd.c Fri Feb 14 00:27:27 2003 @@ -54,15 +54,8 @@ int die; printk("Started krxsecd %d\n",current->pid); - strcpy(current->comm,"krxsecd"); - daemonize(); - - /* only certain signals are of interest */ - spin_lock_irq(¤t->sighand->siglock); - siginitsetinv(¤t->blocked,0); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + daemonize("krxsecd"); /* loop around waiting for work to do */ do { diff -Nru a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c --- a/net/rxrpc/krxtimod.c Fri Feb 14 00:27:27 2003 +++ b/net/rxrpc/krxtimod.c Fri Feb 14 00:27:27 2003 @@ -70,17 +70,10 @@ rxrpc_timer_t *timer; printk("Started krxtimod %d\n",current->pid); - strcpy(current->comm,"krxtimod"); - daemonize(); + daemonize("krxtimod"); complete(&krxtimod_alive); - - /* only certain signals are of interest */ - spin_lock_irq(¤t->sighand->siglock); - siginitsetinv(¤t->blocked,0); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); /* loop around looking for things to attend to */ loop: diff -Nru a/net/sched/sch_gred.c b/net/sched/sch_gred.c --- a/net/sched/sch_gred.c Fri Feb 14 00:27:29 2003 +++ b/net/sched/sch_gred.c Fri Feb 14 00:27:29 2003 @@ -116,7 +116,7 @@ } - if ( ((skb->tc_index&0xf) > t->DPs) || !(q=t->tab[skb->tc_index&0xf])) { + if ( ((skb->tc_index&0xf) > (t->DPs -1)) || !(q=t->tab[skb->tc_index&0xf])) { printk("GRED: setting to default (%d)\n ",t->def); if (!(q=t->tab[t->def])) { DPRINTK("GRED: setting to default FAILED! dropping!! " diff -Nru a/net/sctp/Kconfig b/net/sctp/Kconfig --- a/net/sctp/Kconfig Fri Feb 14 00:27:27 2003 +++ b/net/sctp/Kconfig Fri Feb 14 00:27:27 2003 @@ -6,7 +6,7 @@ depends on INET && EXPERIMENTAL config IPV6_SCTP__ - bool + tristate default y if IPV6=n default IPV6 if IPV6 diff -Nru a/net/sctp/Makefile b/net/sctp/Makefile --- a/net/sctp/Makefile Fri Feb 14 00:27:30 2003 +++ b/net/sctp/Makefile Fri Feb 14 00:27:30 2003 @@ -10,7 +10,7 @@ inqueue.o outqueue.o ulpqueue.o command.o \ tsnmap.o bind_addr.o socket.o primitive.o \ output.o input.o hashdriver.o sla1.o \ - debug.o + debug.o ssnmap.o ifeq ($(CONFIG_SCTP_ADLER32), y) sctp-y += adler32.o diff -Nru a/net/sctp/adler32.c b/net/sctp/adler32.c --- a/net/sctp/adler32.c Fri Feb 14 00:27:29 2003 +++ b/net/sctp/adler32.c Fri Feb 14 00:27:29 2003 @@ -1,6 +1,7 @@ /* SCTP kernel reference Implementation * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2003 International Business Machines, Corp. * * This file is part of the SCTP kernel reference Implementation * @@ -36,6 +37,7 @@ * Randall Stewart * Ken Morneau * Qiaobing Xie + * Sridhar Samudrala * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -122,7 +124,7 @@ return (s2 << 16) + s1; } -__u32 count_crc(__u8 *ptr, __u16 count) +__u32 sctp_start_cksum(__u8 *ptr, __u16 count) { /* * Update a running Adler-32 checksum with the bytes @@ -145,4 +147,16 @@ adler = update_adler32(adler, ptr, count); return adler; +} + +__u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 adler) +{ + adler = update_adler32(adler, ptr, count); + + return adler; +} + +__u32 sctp_end_cksum(__u32 adler) +{ + return adler; } diff -Nru a/net/sctp/associola.c b/net/sctp/associola.c --- a/net/sctp/associola.c Fri Feb 14 00:27:26 2003 +++ b/net/sctp/associola.c Fri Feb 14 00:27:26 2003 @@ -1,7 +1,7 @@ /* SCTP kernel reference Implementation * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001-2002 International Business Machines Corp. + * Copyright (c) 2001-2003 International Business Machines Corp. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 La Monte H.P. Yarroll * @@ -166,15 +166,10 @@ asoc->max_init_attempts = sp->initmsg.sinit_max_attempts; asoc->max_init_timeo = sp->initmsg.sinit_max_init_timeo * HZ; - /* RFC 2960 6.5 Stream Identifier and Stream Sequence Number - * - * The stream sequence number in all the streams shall start - * from 0 when the association is established. Also, when the - * stream sequence number reaches the value 65535 the next - * stream sequence number shall be set to 0. + /* Allocate storage for the ssnmap after the inbound and outbound + * streams have been negotiated during Init. */ - for (i = 0; i < SCTP_MAX_STREAM; i++) - asoc->ssn[i] = 0; + asoc->ssnmap = NULL; /* Set the local window size for receive. * This is also the rcvbuf space per association. @@ -252,15 +247,15 @@ asoc); /* Create an output queue. */ - sctp_outqueue_init(asoc, &asoc->outqueue); - sctp_outqueue_set_output_handlers(&asoc->outqueue, - sctp_packet_init, - sctp_packet_config, - sctp_packet_append_chunk, - sctp_packet_transmit_chunk, - sctp_packet_transmit); + sctp_outq_init(asoc, &asoc->outqueue); + sctp_outq_set_output_handlers(&asoc->outqueue, + sctp_packet_init, + sctp_packet_config, + sctp_packet_append_chunk, + sctp_packet_transmit_chunk, + sctp_packet_transmit); - if (NULL == sctp_ulpqueue_init(&asoc->ulpq, asoc, SCTP_MAX_STREAM)) + if (NULL == sctp_ulpq_init(&asoc->ulpq, asoc)) goto fail_init; /* Set up the tsn tracking. */ @@ -296,7 +291,7 @@ */ void sctp_association_free(sctp_association_t *asoc) { - sctp_transport_t *transport; + struct sctp_transport *transport; sctp_endpoint_t *ep; struct list_head *pos, *temp; int i; @@ -310,14 +305,17 @@ asoc->base.dead = 1; /* Dispose of any data lying around in the outqueue. */ - sctp_outqueue_free(&asoc->outqueue); + sctp_outq_free(&asoc->outqueue); /* Dispose of any pending messages for the upper layer. */ - sctp_ulpqueue_free(&asoc->ulpq); + sctp_ulpq_free(&asoc->ulpq); /* Dispose of any pending chunks on the inqueue. */ sctp_inqueue_free(&asoc->base.inqueue); + /* Free ssnmap storage. */ + sctp_ssnmap_free(asoc->ssnmap); + /* Clean up the bound address list. */ sctp_bind_addr_free(&asoc->base.bind_addr); @@ -339,7 +337,7 @@ /* Release the transport structures. */ list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { - transport = list_entry(pos, sctp_transport_t, transports); + transport = list_entry(pos, struct sctp_transport, transports); list_del(pos); sctp_transport_free(transport); } @@ -365,11 +363,11 @@ /* Add a transport address to an association. */ -sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc, - const union sctp_addr *addr, - int priority) +struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *asoc, + const union sctp_addr *addr, + int priority) { - sctp_transport_t *peer; + struct sctp_transport *peer; sctp_opt_t *sp; unsigned short port; @@ -392,8 +390,8 @@ sctp_transport_set_owner(peer, asoc); - /* Cache a route for the transport. */ - sctp_transport_route(peer, NULL, sctp_sk(asoc->base.sk)); + /* Initialize the pmtu of the transport. */ + sctp_transport_pmtu(peer); /* If this is the first transport addr on this association, * initialize the association PMTU to the peer's PMTU. @@ -478,16 +476,16 @@ } /* Lookup a transport by address. */ -sctp_transport_t *sctp_assoc_lookup_paddr(const sctp_association_t *asoc, +struct sctp_transport *sctp_assoc_lookup_paddr(const sctp_association_t *asoc, const union sctp_addr *address) { - sctp_transport_t *t; + struct sctp_transport *t; struct list_head *pos; /* Cycle through all transports searching for a peer address. */ list_for_each(pos, &asoc->peer.transport_addr_list) { - t = list_entry(pos, sctp_transport_t, transports); + t = list_entry(pos, struct sctp_transport, transports); if (sctp_cmp_addr_exact(address, &t->ipaddr)) return t; } @@ -500,13 +498,13 @@ * Select and update the new active and retran paths. */ void sctp_assoc_control_transport(sctp_association_t *asoc, - sctp_transport_t *transport, + struct sctp_transport *transport, sctp_transport_cmd_t command, sctp_sn_error_t error) { - sctp_transport_t *t = NULL; - sctp_transport_t *first; - sctp_transport_t *second; + struct sctp_transport *t = NULL; + struct sctp_transport *first; + struct sctp_transport *second; sctp_ulpevent_t *event; struct list_head *pos; int spc_state = 0; @@ -524,7 +522,7 @@ break; default: - BUG(); + return; }; /* Generate and send a SCTP_PEER_ADDR_CHANGE notification to the @@ -534,7 +532,7 @@ (struct sockaddr_storage *) &transport->ipaddr, 0, spc_state, error, GFP_ATOMIC); if (event) - sctp_ulpqueue_tail_event(&asoc->ulpq, event); + sctp_ulpq_tail_event(&asoc->ulpq, event); /* Select new active and retran paths. */ @@ -547,7 +545,7 @@ first = NULL; second = NULL; list_for_each(pos, &asoc->peer.transport_addr_list) { - t = list_entry(pos, sctp_transport_t, transports); + t = list_entry(pos, struct sctp_transport, transports); if (!t->active) continue; @@ -631,11 +629,6 @@ return retval; } -/* Fetch the next Stream Sequence Number for stream number 'sid'. */ -__u16 __sctp_association_get_next_ssn(sctp_association_t *asoc, __u16 sid) -{ - return asoc->ssn[sid]++; -} /* Compare two addresses to see if they match. Wildcard addresses * only match themselves. @@ -695,12 +688,12 @@ /* * Find which transport this TSN was sent on. */ -sctp_transport_t *sctp_assoc_lookup_tsn(sctp_association_t *asoc, __u32 tsn) +struct sctp_transport *sctp_assoc_lookup_tsn(sctp_association_t *asoc, __u32 tsn) { - sctp_transport_t *active; - sctp_transport_t *match; + struct sctp_transport *active; + struct sctp_transport *match; struct list_head *entry, *pos; - sctp_transport_t *transport; + struct sctp_transport *transport; sctp_chunk_t *chunk; __u32 key = htonl(tsn); @@ -734,7 +727,7 @@ /* If not found, go search all the other transports. */ list_for_each(pos, &asoc->peer.transport_addr_list) { - transport = list_entry(pos, sctp_transport_t, transports); + transport = list_entry(pos, struct sctp_transport, transports); if (transport == active) break; @@ -752,11 +745,11 @@ } /* Is this the association we are looking for? */ -sctp_transport_t *sctp_assoc_is_match(sctp_association_t *asoc, - const union sctp_addr *laddr, - const union sctp_addr *paddr) +struct sctp_transport *sctp_assoc_is_match(sctp_association_t *asoc, + const union sctp_addr *laddr, + const union sctp_addr *paddr) { - sctp_transport_t *transport; + struct sctp_transport *transport; sctp_read_lock(&asoc->base.addr_lock); @@ -852,8 +845,6 @@ /* Update an association (possibly from unexpected COOKIE-ECHO processing). */ void sctp_assoc_update(sctp_association_t *asoc, sctp_association_t *new) { - int i; - /* Copy in new parameters of peer. */ asoc->c = new->c; asoc->peer.rwnd = new->peer.rwnd; @@ -872,23 +863,28 @@ /* If the case is A (association restart), use * initial_tsn as next_tsn. If the case is B, use - * current next_tsn in case there is data sent to peer + * current next_tsn in case data sent to peer * has been discarded and needs retransmission. */ if (SCTP_STATE_ESTABLISHED == asoc->state) { + asoc->next_tsn = new->next_tsn; asoc->ctsn_ack_point = new->ctsn_ack_point; /* Reinitialize SSN for both local streams * and peer's streams. */ - for (i = 0; i < SCTP_MAX_STREAM; i++) { - asoc->ssn[i] = 0; - asoc->ulpq.ssn[i] = 0; - } + sctp_ssnmap_clear(asoc->ssnmap); + } else { asoc->ctsn_ack_point = asoc->next_tsn - 1; + if (!asoc->ssnmap) { + /* Move the ssnmap. */ + asoc->ssnmap = new->ssnmap; + new->ssnmap = NULL; + } } + } /* Choose the transport for sending a shutdown packet. @@ -896,9 +892,9 @@ * through the inactive transports as this is the next best thing * we can try. */ -sctp_transport_t *sctp_assoc_choose_shutdown_transport(sctp_association_t *asoc) +struct sctp_transport *sctp_assoc_choose_shutdown_transport(sctp_association_t *asoc) { - sctp_transport_t *t, *next; + struct sctp_transport *t, *next; struct list_head *head = &asoc->peer.transport_addr_list; struct list_head *pos; @@ -921,7 +917,7 @@ else pos = pos->next; - t = list_entry(pos, sctp_transport_t, transports); + t = list_entry(pos, struct sctp_transport, transports); /* Try to find an active transport. */ @@ -946,4 +942,137 @@ } return t; +} + +/* Update the association's pmtu and frag_point by going through all the + * transports. This routine is called when a transport's PMTU has changed. + */ +void sctp_assoc_sync_pmtu(sctp_association_t *asoc) +{ + struct sctp_transport *t; + struct list_head *pos; + __u32 pmtu = 0; + + if (!asoc) + return; + + /* Get the lowest pmtu of all the transports. */ + list_for_each(pos, &asoc->peer.transport_addr_list) { + t = list_entry(pos, struct sctp_transport, transports); + if (!pmtu || (t->pmtu < pmtu)) + pmtu = t->pmtu; + } + + if (pmtu) { + asoc->pmtu = pmtu; + asoc->frag_point = pmtu - (SCTP_IP_OVERHEAD + + sizeof(sctp_data_chunk_t)); + } + + SCTP_DEBUG_PRINTK("%s: asoc:%p, pmtu:%d, frag_point:%d\n", + __FUNCTION__, asoc, asoc->pmtu, asoc->frag_point); +} + +/* Increase asoc's rwnd by len and send any window update SACK if needed. */ +void sctp_assoc_rwnd_increase(sctp_association_t *asoc, int len) +{ + sctp_chunk_t *sack; + struct timer_list *timer; + + if (asoc->rwnd_over) { + if (asoc->rwnd_over >= len) { + asoc->rwnd_over -= len; + } else { + asoc->rwnd += (len - asoc->rwnd_over); + asoc->rwnd_over = 0; + } + } else { + asoc->rwnd += len; + } + + SCTP_DEBUG_PRINTK("%s: asoc %p rwnd increased by %d to (%u, %u) - %u\n", + __FUNCTION__, asoc, len, asoc->rwnd, asoc->rwnd_over, + asoc->a_rwnd); + + /* Send a window update SACK if the rwnd has increased by at least the + * minimum of the association's PMTU and half of the receive buffer. + * The algorithm used is similar to the one described in + * Section 4.2.3.3 of RFC 1122. + */ + if ((asoc->state == SCTP_STATE_ESTABLISHED) && + (asoc->rwnd > asoc->a_rwnd) && + ((asoc->rwnd - asoc->a_rwnd) >= + min_t(__u32, (asoc->base.sk->rcvbuf >> 1), asoc->pmtu))) { + SCTP_DEBUG_PRINTK("%s: Sending window update SACK- asoc: %p " + "rwnd: %u a_rwnd: %u\n", + __FUNCTION__, asoc, asoc->rwnd, asoc->a_rwnd); + sack = sctp_make_sack(asoc); + if (!sack) + return; + + /* Update the last advertised rwnd value. */ + asoc->a_rwnd = asoc->rwnd; + + asoc->peer.sack_needed = 0; + asoc->peer.next_dup_tsn = 0; + + sctp_outq_tail(&asoc->outqueue, sack); + + /* Stop the SACK timer. */ + timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK]; + if (timer_pending(timer) && del_timer(timer)) + sctp_association_put(asoc); + } +} + +/* Decrease asoc's rwnd by len. */ +void sctp_assoc_rwnd_decrease(sctp_association_t *asoc, int len) +{ + SCTP_ASSERT(asoc->rwnd, "rwnd zero", return); + SCTP_ASSERT(!asoc->rwnd_over, "rwnd_over not zero", return); + if (asoc->rwnd >= len) { + asoc->rwnd -= len; + } else { + asoc->rwnd_over = len - asoc->rwnd; + asoc->rwnd = 0; + } + SCTP_DEBUG_PRINTK("%s: asoc %p rwnd decreased by %d to (%u, %u)\n", + __FUNCTION__, asoc, len, asoc->rwnd, asoc->rwnd_over); +} + +/* Build the bind address list for the association based on info from the + * local endpoint and the remote peer. + */ +int sctp_assoc_set_bind_addr_from_ep(sctp_association_t *asoc, int priority) +{ + sctp_scope_t scope; + int flags; + + /* Use scoping rules to determine the subset of addresses from + * the endpoint. + */ + scope = sctp_scope(&asoc->peer.active_path->ipaddr); + flags = (PF_INET6 == asoc->base.sk->family) ? SCTP_ADDR6_ALLOWED : 0; + if (asoc->peer.ipv4_address) + flags |= SCTP_ADDR4_PEERSUPP; + if (asoc->peer.ipv6_address) + flags |= SCTP_ADDR6_PEERSUPP; + + return sctp_bind_addr_copy(&asoc->base.bind_addr, + &asoc->ep->base.bind_addr, + scope, priority, flags); +} + +/* Build the association's bind address list from the cookie. */ +int sctp_assoc_set_bind_addr_from_cookie(sctp_association_t *asoc, + sctp_cookie_t *cookie, int priority) +{ + int var_size2 = ntohs(cookie->peer_init->chunk_hdr.length); + int var_size3 = cookie->raw_addr_list_len; + __u8 *raw_addr_list = (__u8 *)cookie + sizeof(sctp_cookie_t) + + var_size2; + + return sctp_raw_to_bind_addrs(&asoc->base.bind_addr, raw_addr_list, + var_size3, asoc->ep->base.bind_addr.port, + priority); } diff -Nru a/net/sctp/command.c b/net/sctp/command.c --- a/net/sctp/command.c Fri Feb 14 00:27:29 2003 +++ b/net/sctp/command.c Fri Feb 14 00:27:29 2003 @@ -47,8 +47,8 @@ { sctp_cmd_seq_t *retval = t_new(sctp_cmd_seq_t, priority); - /* XXX Check for NULL? -DaveM */ - sctp_init_cmd_seq(retval); + if (retval) + sctp_init_cmd_seq(retval); return retval; } diff -Nru a/net/sctp/crc32c.c b/net/sctp/crc32c.c --- a/net/sctp/crc32c.c Fri Feb 14 00:27:29 2003 +++ b/net/sctp/crc32c.c Fri Feb 14 00:27:29 2003 @@ -1,6 +1,6 @@ /* SCTP kernel reference Implementation * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001 International Business Machines, Corp. + * Copyright (c) 2001-2003 International Business Machines, Corp. * * This file is part of the SCTP kernel reference Implementation * @@ -33,6 +33,7 @@ * Written or modified by: * Dinakaran Joseph * Jon Grimm + * Sridhar Samudrala * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -135,11 +136,10 @@ 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351, }; -__u32 count_crc(__u8 *buffer, __u16 length) +__u32 sctp_start_cksum(__u8 *buffer, __u16 length) { __u32 crc32 = ~(__u32) 0; - __u32 i, result; - __u8 byte0, byte1, byte2, byte3; + __u32 i; /* Optimize this routine to be SCTP specific, knowing how * to skip the checksum field of the SCTP header. @@ -157,6 +157,24 @@ for (i = sizeof(struct sctphdr); i < length ; i++) CRC32C(crc32, buffer[i]); + return crc32; +} + +__u32 sctp_update_cksum(__u8 *buffer, __u16 length, __u32 crc32) +{ + __u32 i; + + for (i = 0; i < length ; i++) + CRC32C(crc32, buffer[i]); + + return crc32; +} + +__u32 sctp_end_cksum(__u32 crc32) +{ + __u32 result; + __u8 byte0, byte1, byte2, byte3; + result = ~crc32; /* result now holds the negated polynomial remainder; @@ -183,5 +201,3 @@ byte3); return crc32; } - - diff -Nru a/net/sctp/debug.c b/net/sctp/debug.c --- a/net/sctp/debug.c Fri Feb 14 00:27:27 2003 +++ b/net/sctp/debug.c Fri Feb 14 00:27:27 2003 @@ -148,22 +148,11 @@ /* Printable forms of primitives */ static const char *sctp_primitive_tbl[SCTP_NUM_PRIMITIVE_TYPES] = { - "PRIMITIVE_INITIALIZE", "PRIMITIVE_ASSOCIATE", "PRIMITIVE_SHUTDOWN", "PRIMITIVE_ABORT", "PRIMITIVE_SEND", - "PRIMITIVE_SETPRIMARY", - "PRIMITIVE_RECEIVE", - "PRIMITIVE_STATUS", - "PRIMITIVE_CHANGEHEARTBEAT", "PRIMITIVE_REQUESTHEARTBEAT", - "PRIMITIVE_GETSRTTREPORT", - "PRIMITIVE_SETFAILURETHRESHOLD", - "PRIMITIVE_SETPROTOPARAMETERS", - "PRIMITIVE_RECEIVE_UNSENT", - "PRIMITIVE_RECEIVE_UNACKED", - "PRIMITIVE_DESTROY" }; /* Lookup primitive debug name. */ @@ -178,7 +167,6 @@ static const char *sctp_other_tbl[] = { "NO_PENDING_TSN", - "ICMP_UNREACHFRAG" }; /* Lookup "other" debug name. */ @@ -197,12 +185,10 @@ "TIMEOUT_T1_INIT", "TIMEOUT_T2_SHUTDOWN", "TIMEOUT_T3_RTX", - "TIMEOUT_T4_RTO", "TIMEOUT_T5_SHUTDOWN_GUARD", "TIMEOUT_HEARTBEAT", "TIMEOUT_SACK", "TIMEOUT_AUTOCLOSE", - "TIMEOUT_PMTU_RAISE", }; /* Lookup timer debug name. */ diff -Nru a/net/sctp/endpointola.c b/net/sctp/endpointola.c --- a/net/sctp/endpointola.c Fri Feb 14 00:27:27 2003 +++ b/net/sctp/endpointola.c Fri Feb 14 00:27:27 2003 @@ -137,7 +137,6 @@ ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = sp->rtoinfo.srto_initial; ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0; - ep->timeouts[SCTP_EVENT_TIMEOUT_T4_RTO] = 0; /* sctpimpguide-05 Section 2.12.2 * If the 'T5-shutdown-guard' timer is used, it SHOULD be set to the @@ -152,8 +151,6 @@ SCTP_DEFAULT_TIMEOUT_SACK; ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ; - ep->timeouts[SCTP_EVENT_TIMEOUT_PMTU_RAISE] = - SCTP_DEFAULT_TIMEOUT_PMTU_RAISE; /* Set up the default send/receive buffer space. */ @@ -264,7 +261,7 @@ sctp_association_t *__sctp_endpoint_lookup_assoc( const sctp_endpoint_t *endpoint, const union sctp_addr *paddr, - sctp_transport_t **transport) + struct sctp_transport **transport) { int rport; sctp_association_t *asoc; @@ -289,9 +286,10 @@ } /* Lookup association on an endpoint based on a peer address. BH-safe. */ -sctp_association_t *sctp_endpoint_lookup_assoc(const sctp_endpoint_t *ep, - const union sctp_addr *paddr, - sctp_transport_t **transport) +sctp_association_t *sctp_endpoint_lookup_assoc( + const sctp_endpoint_t *ep, + const union sctp_addr *paddr, + struct sctp_transport **transport) { sctp_association_t *asoc; @@ -333,7 +331,7 @@ { sctp_association_t *asoc; struct sock *sk; - sctp_transport_t *transport; + struct sctp_transport *transport; sctp_chunk_t *chunk; sctp_inqueue_t *inqueue; sctp_subtype_t subtype; diff -Nru a/net/sctp/input.c b/net/sctp/input.c --- a/net/sctp/input.c Fri Feb 14 00:27:26 2003 +++ b/net/sctp/input.c Fri Feb 14 00:27:26 2003 @@ -1,7 +1,7 @@ /* SCTP kernel reference Implementation * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001 International Business Machines, Corp. + * Copyright (c) 2001-2003 International Business Machines, Corp. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 La Monte H.P. Yarroll @@ -53,6 +53,9 @@ #include #include #include /* For struct timeval */ +#include +#include +#include #include #include #include @@ -63,7 +66,7 @@ sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb, const union sctp_addr *laddr, const union sctp_addr *paddr, - sctp_transport_t **transportp); + struct sctp_transport **transportp); sctp_endpoint_t *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr); @@ -72,10 +75,19 @@ { struct sctphdr *sh; __u32 cmp, val; + struct sk_buff *list = skb_shinfo(skb)->frag_list; sh = (struct sctphdr *) skb->h.raw; cmp = ntohl(sh->checksum); - val = count_crc((__u8 *)sh, skb->len); + + val = sctp_start_cksum((__u8 *)sh, skb_headlen(skb)); + + for (; list; list = list->next) + val = sctp_update_cksum((__u8 *)list->data, skb_headlen(list), + val); + + val = sctp_end_cksum(val); + if (val != cmp) { /* CRC failure, dump it. */ return -1; @@ -92,7 +104,7 @@ sctp_association_t *asoc; sctp_endpoint_t *ep = NULL; sctp_endpoint_common_t *rcvr; - sctp_transport_t *transport = NULL; + struct sctp_transport *transport = NULL; sctp_chunk_t *chunk; struct sctphdr *sh; union sctp_addr src; @@ -248,6 +260,27 @@ return 0; } +/* Handle icmp frag needed error. */ +static inline void sctp_icmp_frag_needed(struct sock *sk, + sctp_association_t *asoc, + struct sctp_transport *transport, + __u32 pmtu) +{ + if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { + printk(KERN_WARNING "%s: Reported pmtu %d too low, " + "using default minimum of %d\n", __FUNCTION__, pmtu, + SCTP_DEFAULT_MINSEGMENT); + pmtu = SCTP_DEFAULT_MINSEGMENT; + } + + if (!sock_owned_by_user(sk) && transport && (transport->pmtu != pmtu)) { + transport->pmtu = pmtu; + sctp_assoc_sync_pmtu(asoc); + sctp_retransmit(&asoc->outqueue, transport, + SCTP_RETRANSMIT_PMTU_DISCOVERY ); + } +} + /* * This routine is called by the ICMP module when it gets some * sort of error condition. If err < 0 then the socket should @@ -263,9 +296,109 @@ * is probably better. * */ -void sctp_v4_err(struct sk_buff *skb, u32 info) +void sctp_v4_err(struct sk_buff *skb, __u32 info) { - /* This should probably involve a call to SCTPhandleICMP(). */ + struct iphdr *iph = (struct iphdr *)skb->data; + struct sctphdr *sh = (struct sctphdr *)(skb->data + (iph->ihl <<2)); + int type = skb->h.icmph->type; + int code = skb->h.icmph->code; + union sctp_addr saddr, daddr; + struct inet_opt *inet; + struct sock *sk = NULL; + sctp_endpoint_t *ep = NULL; + sctp_association_t *asoc = NULL; + struct sctp_transport *transport; + int err; + + if (skb->len < ((iph->ihl << 2) + 8)) { + ICMP_INC_STATS_BH(IcmpInErrors); + return; + } + + saddr.v4.sin_family = AF_INET; + saddr.v4.sin_port = ntohs(sh->source); + memcpy(&saddr.v4.sin_addr.s_addr, &iph->saddr, sizeof(struct in_addr)); + daddr.v4.sin_family = AF_INET; + daddr.v4.sin_port = ntohs(sh->dest); + memcpy(&daddr.v4.sin_addr.s_addr, &iph->daddr, sizeof(struct in_addr)); + + /* Look for an association that matches the incoming ICMP error + * packet. + */ + asoc = __sctp_lookup_association(&saddr, &daddr, &transport); + if (!asoc) { + /* If there is no matching association, see if it matches any + * endpoint. This may happen for an ICMP error generated in + * response to an INIT_ACK. + */ + ep = __sctp_rcv_lookup_endpoint(&daddr); + if (!ep) { + ICMP_INC_STATS_BH(IcmpInErrors); + return; + } + } + + if (asoc) { + if (ntohl(sh->vtag) != asoc->c.peer_vtag) { + ICMP_INC_STATS_BH(IcmpInErrors); + goto out; + } + sk = asoc->base.sk; + } else + sk = ep->base.sk; + + sctp_bh_lock_sock(sk); + /* If too many ICMPs get dropped on busy + * servers this needs to be solved differently. + */ + if (sock_owned_by_user(sk)) + NET_INC_STATS_BH(LockDroppedIcmps); + + switch (type) { + case ICMP_PARAMETERPROB: + err = EPROTO; + break; + case ICMP_DEST_UNREACH: + if (code > NR_ICMP_UNREACH) + goto out_unlock; + + /* PMTU discovery (RFC1191) */ + if (ICMP_FRAG_NEEDED == code) { + sctp_icmp_frag_needed(sk, asoc, transport, info); + goto out_unlock; + } + + err = icmp_err_convert[code].errno; + break; + case ICMP_TIME_EXCEEDED: + /* Ignore any time exceeded errors due to fragment reassembly + * timeouts. + */ + if (ICMP_EXC_FRAGTIME == code) + goto out_unlock; + + err = EHOSTUNREACH; + break; + default: + goto out_unlock; + } + + inet = inet_sk(sk); + if (!sock_owned_by_user(sk) && inet->recverr) { + sk->err = err; + sk->error_report(sk); + } else { /* Only an error on timeout */ + sk->err_soft = err; + } + +out_unlock: + sctp_bh_unlock_sock(sk); +out: + sock_put(sk); + if (asoc) + sctp_association_put(asoc); + if (ep) + sctp_endpoint_put(ep); } /* @@ -303,17 +436,17 @@ * chunk, the receiver should silently discard the packet * and take no further action. */ - if (ch->type == SCTP_CID_SHUTDOWN_COMPLETE) + if (SCTP_CID_SHUTDOWN_COMPLETE == ch->type) goto discard; /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR * or a COOKIE ACK the SCTP Packet should be silently * discarded. */ - if (ch->type == SCTP_CID_COOKIE_ACK) + if (SCTP_CID_COOKIE_ACK == ch->type) goto discard; - if (ch->type == SCTP_CID_ERROR) { + if (SCTP_CID_ERROR == ch->type) { err = (sctp_errhdr_t *)(ch + sizeof(sctp_chunkhdr_t)); if (SCTP_ERROR_STALE_COOKIE == err->cause) goto discard; @@ -485,12 +618,12 @@ /* Look up an association. */ sctp_association_t *__sctp_lookup_association(const union sctp_addr *laddr, const union sctp_addr *paddr, - sctp_transport_t **transportp) + struct sctp_transport **transportp) { sctp_hashbucket_t *head; sctp_endpoint_common_t *epb; sctp_association_t *asoc; - sctp_transport_t *transport; + struct sctp_transport *transport; int hash; /* Optimize here for direct hit, only listening connections can @@ -521,7 +654,7 @@ /* Look up an association. BH-safe. */ sctp_association_t *sctp_lookup_association(const union sctp_addr *laddr, const union sctp_addr *paddr, - sctp_transport_t **transportp) + struct sctp_transport **transportp) { sctp_association_t *asoc; @@ -537,7 +670,7 @@ const union sctp_addr *paddr) { sctp_association_t *asoc; - sctp_transport_t *transport; + struct sctp_transport *transport; if ((asoc = sctp_lookup_association(laddr, paddr, &transport))) { sock_put(asoc->base.sk); @@ -567,7 +700,7 @@ * */ static sctp_association_t *__sctp_rcv_init_lookup(struct sk_buff *skb, - const union sctp_addr *laddr, sctp_transport_t **transportp) + const union sctp_addr *laddr, struct sctp_transport **transportp) { sctp_association_t *asoc; union sctp_addr addr; @@ -627,7 +760,7 @@ sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb, const union sctp_addr *paddr, const union sctp_addr *laddr, - sctp_transport_t **transportp) + struct sctp_transport **transportp) { sctp_association_t *asoc; diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c --- a/net/sctp/ipv6.c Fri Feb 14 00:27:28 2003 +++ b/net/sctp/ipv6.c Fri Feb 14 00:27:28 2003 @@ -98,43 +98,22 @@ } /* Based on tcp_v6_xmit() in tcp_ipv6.c. */ -static inline int sctp_v6_xmit(struct sk_buff *skb) +static inline int sctp_v6_xmit(struct sk_buff *skb, + struct sctp_transport *transport, int ipfragok) { struct sock *sk = skb->sk; struct ipv6_pinfo *np = inet6_sk(sk); struct flowi fl; struct dst_entry *dst = skb->dst; struct rt6_info *rt6 = (struct rt6_info *)dst; - struct in6_addr saddr; - int err; fl.proto = sk->protocol; - fl.fl6_dst = &rt6->rt6i_dst.addr; - /* FIXME: Currently, ip6_route_output() doesn't fill in the source - * address in the returned route entry. So we call ipv6_get_saddr() - * to get an appropriate source address. It is possible that this address - * may not be part of the bind address list of the association. - * Once ip6_route_ouput() is fixed so that it returns a route entry - * with an appropriate source address, the following if condition can - * be removed. With ip6_route_output() returning a source address filled - * route entry, sctp_transport_route() can do real source address - * selection for v6. + /* Fill in the dest address from the route entry passed with the skb + * and the source address from the transport. */ - if (ipv6_addr_any(&rt6->rt6i_src.addr)) { - err = ipv6_get_saddr(dst, fl.fl6_dst, &saddr); - - if (err) { - printk(KERN_ERR "%s: No saddr available for " - "DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - __FUNCTION__, NIP6(fl.fl6_src)); - return err; - } - - fl.fl6_src = &saddr; - } else { - fl.fl6_src = &rt6->rt6i_src.addr; - } + fl.fl6_dst = &rt6->rt6i_dst.addr; + fl.fl6_src = &transport->saddr.v6.sin6_addr; fl.fl6_flowlabel = np->flow_label; IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel); @@ -147,20 +126,26 @@ fl.nl_u.ip6_u.daddr = rt0->addr; } + SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, " + "src:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x " + "dst:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + __FUNCTION__, skb, skb->len, NIP6(fl.fl6_src), + NIP6(fl.fl6_dst)); + return ip6_xmit(sk, skb, &fl, np->opt); } /* Returns the dst cache entry for the given source and destination ip * addresses. */ -struct dst_entry *sctp_v6_get_dst(union sctp_addr *daddr, +struct dst_entry *sctp_v6_get_dst(sctp_association_t *asoc, + union sctp_addr *daddr, union sctp_addr *saddr) { struct dst_entry *dst; struct flowi fl = { .nl_u = { .ip6_u = { .daddr = &daddr->v6.sin6_addr, } } }; - SCTP_DEBUG_PRINTK("%s: DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", __FUNCTION__, NIP6(fl.fl6_dst)); @@ -181,12 +166,96 @@ NIP6(&rt->rt6i_dst.addr), NIP6(&rt->rt6i_src.addr)); } else { SCTP_DEBUG_PRINTK("NO ROUTE\n"); - return NULL; } return dst; } +/* Returns the number of consecutive initial bits that match in the 2 ipv6 + * addresses. + */ +static inline int sctp_v6_addr_match_len(union sctp_addr *s1, + union sctp_addr *s2) +{ + struct in6_addr *a1 = &s1->v6.sin6_addr; + struct in6_addr *a2 = &s2->v6.sin6_addr; + int i, j; + + for (i = 0; i < 4 ; i++) { + __u32 a1xora2; + + a1xora2 = a1->s6_addr32[i] ^ a2->s6_addr32[i]; + + if ((j = fls(ntohl(a1xora2)))) + return (i * 32 + 32 - j); + } + + return (i*32); +} + +/* Fills in the source address(saddr) based on the destination address(daddr) + * and asoc's bind address list. + */ +void sctp_v6_get_saddr(sctp_association_t *asoc, struct dst_entry *dst, + union sctp_addr *daddr, union sctp_addr *saddr) +{ + sctp_bind_addr_t *bp; + rwlock_t *addr_lock; + struct sockaddr_storage_list *laddr; + struct list_head *pos; + sctp_scope_t scope; + union sctp_addr *baddr = NULL; + __u8 matchlen = 0; + __u8 bmatchlen; + + SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p " + "daddr:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", + __FUNCTION__, asoc, dst, NIP6(&daddr->v6.sin6_addr)); + + if (!asoc) { + ipv6_get_saddr(dst, &daddr->v6.sin6_addr, &saddr->v6.sin6_addr); + SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: " + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + NIP6(&saddr->v6.sin6_addr)); + return; + } + + scope = sctp_scope(daddr); + + bp = &asoc->base.bind_addr; + addr_lock = &asoc->base.addr_lock; + + /* Go through the bind address list and find the best source address + * that matches the scope of the destination address. + */ + sctp_read_lock(addr_lock); + list_for_each(pos, &bp->address_list) { + laddr = list_entry(pos, struct sockaddr_storage_list, list); + if ((laddr->a.sa.sa_family == AF_INET6) && + (scope <= sctp_scope(&laddr->a))) { + bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); + if (!baddr || (matchlen < bmatchlen)) { + baddr = &laddr->a; + matchlen = bmatchlen; + } + } + } + + if (baddr) { + memcpy(saddr, baddr, sizeof(union sctp_addr)); + SCTP_DEBUG_PRINTK("saddr: " + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + NIP6(&saddr->v6.sin6_addr)); + } else { + printk(KERN_ERR "%s: asoc:%p Could not find a valid source " + "address for the " + "dest:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + __FUNCTION__, asoc, NIP6(&daddr->v6.sin6_addr)); + } + + sctp_read_unlock(addr_lock); +} + /* Make a copy of all potential local addresses. */ static void sctp_v6_copy_addrlist(struct list_head *addrlist, struct net_device *dev) @@ -257,10 +326,12 @@ } /* Initialize a sctp_addr from a dst_entry. */ -static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst) +static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst, + unsigned short port) { struct rt6_info *rt = (struct rt6_info *)dst; addr->sa.sa_family = AF_INET6; + addr->v6.sin6_port = port; ipv6_addr_copy(&addr->v6.sin6_addr, &rt->rt6i_src.addr); } @@ -527,10 +598,11 @@ }; static struct sctp_af sctp_ipv6_specific = { - .queue_xmit = sctp_v6_xmit, - .setsockopt = ipv6_setsockopt, + .sctp_xmit = sctp_v6_xmit, + .setsockopt = ipv6_setsockopt, .getsockopt = ipv6_getsockopt, .get_dst = sctp_v6_get_dst, + .get_saddr = sctp_v6_get_saddr, .copy_addrlist = sctp_v6_copy_addrlist, .from_skb = sctp_v6_from_skb, .from_sk = sctp_v6_from_sk, @@ -572,7 +644,7 @@ /* Register the SCTP specfic AF_INET6 functions. */ sctp_register_af(&sctp_ipv6_specific); - /* Register notifier for inet6 address additions/deletions. */ + /* Register notifier for inet6 address additions/deletions. */ register_inet6addr_notifier(&sctp_inetaddr_notifier); return 0; diff -Nru a/net/sctp/objcnt.c b/net/sctp/objcnt.c --- a/net/sctp/objcnt.c Fri Feb 14 00:27:26 2003 +++ b/net/sctp/objcnt.c Fri Feb 14 00:27:26 2003 @@ -54,6 +54,7 @@ SCTP_DBG_OBJCNT(bind_addr); SCTP_DBG_OBJCNT(chunk); SCTP_DBG_OBJCNT(addr); +SCTP_DBG_OBJCNT(ssnmap); /* An array to make it easy to pretty print the debug information * to the proc fs. @@ -66,6 +67,7 @@ SCTP_DBG_OBJCNT_ENTRY(chunk), SCTP_DBG_OBJCNT_ENTRY(bind_addr), SCTP_DBG_OBJCNT_ENTRY(addr), + SCTP_DBG_OBJCNT_ENTRY(ssnmap), }; /* Callback from procfs to read out objcount information. diff -Nru a/net/sctp/output.c b/net/sctp/output.c --- a/net/sctp/output.c Fri Feb 14 00:27:27 2003 +++ b/net/sctp/output.c Fri Feb 14 00:27:27 2003 @@ -1,7 +1,7 @@ /* SCTP kernel reference Implementation * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001 International Business Machines, Corp. + * Copyright (c) 2001-2003 International Business Machines, Corp. * * This file is part of the SCTP kernel reference Implementation * @@ -62,7 +62,6 @@ #include /* Forward declarations for private helpers. */ -__u32 count_crc(__u8 *ptr, __u16 count); static void sctp_packet_reset(sctp_packet_t *packet); static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t *chunk); @@ -81,6 +80,7 @@ packet->ecn_capable = ecn_capable; packet->get_prepend_chunk = prepend_handler; packet->has_cookie_echo = 0; + packet->ipfragok = 0; /* We might need to call the prepend_handler right away. */ if (packet_empty) @@ -90,7 +90,7 @@ /* Initialize the packet structure. */ sctp_packet_t *sctp_packet_init(sctp_packet_t *packet, - sctp_transport_t *transport, + struct sctp_transport *transport, __u16 sport, __u16 dport) { @@ -102,6 +102,7 @@ packet->ecn_capable = 0; packet->get_prepend_chunk = NULL; packet->has_cookie_echo = 0; + packet->ipfragok = 0; packet->malloced = 0; sctp_packet_reset(packet); return packet; @@ -193,6 +194,7 @@ * transmit and rely on IP * fragmentation. */ + packet->ipfragok = 1; goto append; } } else { /* !packet_empty */ @@ -228,13 +230,13 @@ } /* All packets are sent to the network through this function from - * sctp_push_outqueue(). + * sctp_outq_tail(). * * The return value is a normal kernel error return value. */ int sctp_packet_transmit(sctp_packet_t *packet) { - sctp_transport_t *transport = packet->transport; + struct sctp_transport *transport = packet->transport; sctp_association_t *asoc = transport->asoc; struct sctphdr *sh; __u32 crc32; @@ -358,22 +360,14 @@ * Note: Adler-32 is no longer applicable, as has been replaced * by CRC32-C as described in . */ - crc32 = count_crc((__u8 *)sh, nskb->len); + crc32 = sctp_start_cksum((__u8 *)sh, nskb->len); + crc32 = sctp_end_cksum(crc32); /* 3) Put the resultant value into the checksum field in the * common header, and leave the rest of the bits unchanged. */ sh->checksum = htonl(crc32); - /* FIXME: Delete the rest of this switch statement once phase 2 - * of address selection (ipv6 support) drops in. - */ - switch (transport->ipaddr.sa.sa_family) { - case AF_INET6: - SCTP_V6(inet6_sk(sk)->daddr = transport->ipaddr.v6.sin6_addr;) - break; - }; - /* IP layer ECN support * From RFC 2481 * "The ECN-Capable Transport (ECT) bit would be set by the @@ -423,8 +417,10 @@ } dst = transport->dst; - if (!dst || dst->obsolete) { + /* The 'obsolete' field of dst is set to 2 when a dst is freed. */ + if (!dst || (dst->obsolete > 1)) { sctp_transport_route(transport, NULL, sctp_sk(sk)); + sctp_assoc_sync_pmtu(asoc); } nskb->dst = dst_clone(transport->dst); @@ -433,14 +429,22 @@ SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb length %d\n", nskb->len); - (*transport->af_specific->queue_xmit)(nskb); + (*transport->af_specific->sctp_xmit)(nskb, transport, packet->ipfragok); out: packet->size = SCTP_IP_OVERHEAD; return err; no_route: kfree_skb(nskb); IP_INC_STATS_BH(IpOutNoRoutes); - err = -EHOSTUNREACH; + + /* FIXME: Returning the 'err' will effect all the associations + * associated with a socket, although only one of the paths of the + * association is unreachable. + * The real failure of a transport or association can be passed on + * to the user via notifications. So setting this error may not be + * required. + */ + /* err = -EHOSTUNREACH; */ goto out; } @@ -473,7 +477,7 @@ { sctp_xmit_t retval = SCTP_XMIT_OK; size_t datasize, rwnd, inflight; - sctp_transport_t *transport = packet->transport; + struct sctp_transport *transport = packet->transport; __u32 max_burst_bytes; /* RFC 2960 6.1 Transmission of DATA Chunks diff -Nru a/net/sctp/outqueue.c b/net/sctp/outqueue.c --- a/net/sctp/outqueue.c Fri Feb 14 00:27:27 2003 +++ b/net/sctp/outqueue.c Fri Feb 14 00:27:27 2003 @@ -2,11 +2,11 @@ * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 2001 Intel Corp. - * Copyright (c) 2001-2002 International Business Machines Corp. + * Copyright (c) 2001-2003 International Business Machines Corp. * * This file is part of the SCTP kernel reference Implementation * - * These functions implement the outqueue class. The outqueue handles + * These functions implement the sctp_outq class. The outqueue handles * bundling and queueing of outgoing SCTP chunks. * * The SCTP reference implementation is free software; @@ -47,39 +47,39 @@ */ #include -#include /* For struct list_head */ +#include /* For struct list_head */ #include #include -#include /* For skb_set_owner_w */ +#include /* For skb_set_owner_w */ #include /* Declare internal functions here. */ static int sctp_acked(sctp_sackhdr_t *sack, __u32 tsn); -static void sctp_check_transmitted(sctp_outqueue_t *q, +static void sctp_check_transmitted(struct sctp_outq *q, struct list_head *transmitted_queue, - sctp_transport_t *transport, + struct sctp_transport *transport, sctp_sackhdr_t *sack, __u32 highest_new_tsn); /* Generate a new outqueue. */ -sctp_outqueue_t *sctp_outqueue_new(sctp_association_t *asoc) +struct sctp_outq *sctp_outq_new(sctp_association_t *asoc) { - sctp_outqueue_t *q; + struct sctp_outq *q; - q = t_new(sctp_outqueue_t, GFP_KERNEL); + q = t_new(struct sctp_outq, GFP_KERNEL); if (q) { - sctp_outqueue_init(asoc, q); + sctp_outq_init(asoc, q); q->malloced = 1; } return q; } -/* Initialize an existing SCTP_outqueue. This does the boring stuff. +/* Initialize an existing sctp_outq. This does the boring stuff. * You still need to define handlers if you really want to DO * something with this structure... */ -void sctp_outqueue_init(sctp_association_t *asoc, sctp_outqueue_t *q) +void sctp_outq_init(sctp_association_t *asoc, struct sctp_outq *q) { q->asoc = asoc; skb_queue_head_init(&q->out); @@ -102,15 +102,15 @@ /* Free the outqueue structure and any related pending chunks. * FIXME: Add SEND_FAILED support. */ -void sctp_outqueue_teardown(sctp_outqueue_t *q) +void sctp_outq_teardown(struct sctp_outq *q) { - sctp_transport_t *transport; + struct sctp_transport *transport; struct list_head *lchunk, *pos, *temp; sctp_chunk_t *chunk; /* Throw away unacknowledged chunks. */ list_for_each(pos, &q->asoc->peer.transport_addr_list) { - transport = list_entry(pos, sctp_transport_t, transports); + transport = list_entry(pos, struct sctp_transport, transports); while ((lchunk = sctp_list_dequeue(&transport->transmitted))) { chunk = list_entry(lchunk, sctp_chunk_t, transmitted_list); @@ -125,35 +125,39 @@ sctp_free_chunk(chunk); } - /* Throw away any leftover chunks. */ + /* Throw away any chunks in the retransmit queue. */ + list_for_each_safe(lchunk, temp, &q->retransmit) { + list_del(lchunk); + chunk = list_entry(lchunk, sctp_chunk_t, transmitted_list); + sctp_free_chunk(chunk); + } + + /* Throw away any leftover data chunks. */ while ((chunk = (sctp_chunk_t *) skb_dequeue(&q->out))) sctp_free_chunk(chunk); + + /* Throw away any leftover control chunks. */ + while ((chunk = (sctp_chunk_t *) skb_dequeue(&q->control))) + sctp_free_chunk(chunk); } /* Free the outqueue structure and any related pending chunks. */ -void sctp_outqueue_free(sctp_outqueue_t *q) +void sctp_outq_free(struct sctp_outq *q) { /* Throw away leftover chunks. */ - sctp_outqueue_teardown(q); + sctp_outq_teardown(q); /* If we were kmalloc()'d, free the memory. */ if (q->malloced) kfree(q); } -/* Transmit any pending partial chunks. */ -void sctp_force_outqueue(sctp_outqueue_t *q) -{ - /* Do we really need this? */ - /* BUG */ -} - -/* Put a new chunk in an SCTP_outqueue. */ -int sctp_push_outqueue(sctp_outqueue_t *q, sctp_chunk_t *chunk) +/* Put a new chunk in an sctp_outq. */ +int sctp_outq_tail(struct sctp_outq *q, sctp_chunk_t *chunk) { int error = 0; - SCTP_DEBUG_PRINTK("sctp_push_outqueue(%p, %p[%s])\n", + SCTP_DEBUG_PRINTK("sctp_outq_tail(%p, %p[%s])\n", q, chunk, chunk && chunk->chunk_hdr ? sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) : "Illegal Chunk"); @@ -184,8 +188,7 @@ default: SCTP_DEBUG_PRINTK("outqueueing (%p, %p[%s])\n", - q, chunk, - chunk && chunk->chunk_hdr ? + q, chunk, chunk && chunk->chunk_hdr ? sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) : "Illegal Chunk"); @@ -193,13 +196,13 @@ q->empty = 0; break; }; - } else { + } else skb_queue_tail(&q->control, (struct sk_buff *) chunk); - } + if (error < 0) return error; - error = sctp_flush_outqueue(q, 0); + error = sctp_outq_flush(q, 0); return error; } @@ -207,7 +210,7 @@ /* Insert a chunk into the retransmit queue. Chunks on the retransmit * queue are kept in order, based on the TSNs. */ -void sctp_retransmit_insert(struct list_head *tlchunk, sctp_outqueue_t *q) +void sctp_retransmit_insert(struct list_head *tlchunk, struct sctp_outq *q) { struct list_head *rlchunk; sctp_chunk_t *tchunk, *rchunk; @@ -230,15 +233,15 @@ list_add_tail(tlchunk, &q->retransmit); } } - + /* Mark all the eligible packets on a transport for retransmission. */ -void sctp_retransmit_mark(sctp_outqueue_t *q, sctp_transport_t *transport, +void sctp_retransmit_mark(struct sctp_outq *q, + struct sctp_transport *transport, __u8 fast_retransmit) { struct list_head *lchunk, *ltemp; sctp_chunk_t *chunk; - /* Walk through the specified transmitted queue. */ list_for_each_safe(lchunk, ltemp, &transport->transmitted) { chunk = list_entry(lchunk, sctp_chunk_t, transmitted_list); @@ -246,8 +249,9 @@ /* If we are doing retransmission due to a fast retransmit, * only the chunk's that are marked for fast retransmit * should be added to the retransmit queue. If we are doing - * retransmission due to a timeout, only the chunks that are - * not yet acked should be added to the retransmit queue. + * retransmission due to a timeout or pmtu discovery, only the + * chunks that are not yet acked should be added to the + * retransmit queue. */ if ((fast_retransmit && chunk->fast_retransmit) || (!fast_retransmit && !chunk->tsn_gap_acked)) { @@ -302,20 +306,27 @@ /* Mark all the eligible packets on a transport for retransmission and force * one packet out. */ -void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport, - __u8 fast_retransmit) +void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, + sctp_retransmit_reason_t reason) { int error = 0; + __u8 fast_retransmit = 0; - if (fast_retransmit) { - sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX); - } else { + switch(reason) { + case SCTP_RETRANSMIT_T3_RTX: sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX); + break; + case SCTP_RETRANSMIT_FAST_RTX: + sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX); + fast_retransmit = 1; + break; + default: + break; } sctp_retransmit_mark(q, transport, fast_retransmit); - error = sctp_flush_outqueue(q, /* rtx_timeout */ 1); + error = sctp_outq_flush(q, /* rtx_timeout */ 1); if (error) q->asoc->base.sk->err = -error; @@ -323,18 +334,18 @@ /* * Transmit DATA chunks on the retransmit queue. Upon return from - * sctp_flush_retran_queue() the packet 'pkt' may contain chunks which + * sctp_outq_flush_rtx() the packet 'pkt' may contain chunks which * need to be transmitted by the caller. * We assume that pkt->transport has already been set. * * The return value is a normal kernel error return value. */ -static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt, - int rtx_timeout, int *start_timer) +static int sctp_outq_flush_rtx(struct sctp_outq *q, sctp_packet_t *pkt, + int rtx_timeout, int *start_timer) { struct list_head *lqueue; struct list_head *lchunk; - sctp_transport_t *transport = pkt->transport; + struct sctp_transport *transport = pkt->transport; sctp_xmit_t status; sctp_chunk_t *chunk; sctp_association_t *asoc; @@ -374,6 +385,18 @@ continue; } #endif + + /* Make sure that Gap Acked TSNs are not retransmitted. A + * simple approach is just to move such TSNs out of the + * way and into a 'transmitted' queue and skip to the + * next chunk. + */ + if (chunk->tsn_gap_acked) { + list_add_tail(lchunk, &transport->transmitted); + lchunk = sctp_list_dequeue(lqueue); + continue; + } + /* Attempt to append this chunk to the packet. */ status = (*q->append_output)(pkt, chunk); @@ -427,10 +450,10 @@ * queue. 'pos' points to the next chunk in the output queue after the * chunk that is currently in the process of fragmentation. */ -void sctp_xmit_frag(sctp_outqueue_t *q, struct sk_buff *pos, +void sctp_xmit_frag(struct sctp_outq *q, struct sk_buff *pos, sctp_packet_t *packet, sctp_chunk_t *frag, __u32 tsn) { - sctp_transport_t *transport = packet->transport; + struct sctp_transport *transport = packet->transport; struct sk_buff_head *queue = &q->out; sctp_xmit_t status; int error; @@ -503,7 +526,7 @@ * The argument 'frag' point to the first fragment and it holds the list * of all the other fragments in the 'frag_list' field. */ -void sctp_xmit_fragmented_chunks(sctp_outqueue_t *q, sctp_packet_t *packet, +void sctp_xmit_fragmented_chunks(struct sctp_outq *q, sctp_packet_t *packet, sctp_chunk_t *frag) { sctp_association_t *asoc = frag->asoc; @@ -548,6 +571,7 @@ sctp_chunk_t *first_frag, *frag; struct list_head *frag_list; int nfrags; + __u8 old_flags, flags; /* nfrags = no. of max size fragments + any smaller last fragment. */ nfrags = ((chunk_data_len / max_frag_data_len) + @@ -556,13 +580,20 @@ /* Start of the data in the chunk. */ data_ptr += sizeof(sctp_datahdr_t); + /* Are we fragmenting an already fragmented large message? */ + old_flags = chunk->chunk_hdr->flags; + if (old_flags & SCTP_DATA_FIRST_FRAG) + flags = SCTP_DATA_FIRST_FRAG; + else + flags = SCTP_DATA_MIDDLE_FRAG; + /* Make the first fragment. */ first_frag = sctp_make_datafrag(asoc, sinfo, max_frag_data_len, - data_ptr, SCTP_DATA_FIRST_FRAG, ssn); + data_ptr, flags, ssn); if (!first_frag) goto err; - + first_frag->has_ssn = 1; /* All the fragments are added to the frag_list of the first chunk. */ frag_list = &first_frag->frag_list; @@ -576,7 +607,7 @@ ssn); if (!frag) goto err; - + frag->has_ssn = 1; /* Add the middle fragment to the first fragment's * frag_list. */ @@ -586,11 +617,17 @@ data_ptr += max_frag_data_len; } + if (old_flags & SCTP_DATA_LAST_FRAG) + flags = SCTP_DATA_LAST_FRAG; + else + flags = SCTP_DATA_MIDDLE_FRAG; + /* Make the last fragment. */ frag = sctp_make_datafrag(asoc, sinfo, chunk_data_len, data_ptr, - SCTP_DATA_LAST_FRAG, ssn); + flags, ssn); if (!frag) goto err; + frag->has_ssn = 1; /* Add the last fragment to the first fragment's frag_list. */ list_add_tail(&frag->frag_list, frag_list); @@ -620,7 +657,7 @@ } /* - * sctp_flush_outqueue - Try to flush an outqueue. + * sctp_outq_flush - Try to flush an outqueue. * * Description: Send everything in q which we legally can, subject to * congestion limitations. @@ -629,7 +666,7 @@ * locking concerns must be made. Today we use the sock lock to protect * this function. */ -int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout) +int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) { sctp_packet_t *packet; sctp_packet_t singleton; @@ -642,13 +679,12 @@ sctp_packet_phandler_t *s_ecne_handler = NULL; sctp_packet_phandler_t *ecne_handler = NULL; struct sk_buff_head *queue; - sctp_transport_t *transport = NULL; - sctp_transport_t *new_transport; + struct sctp_transport *transport = NULL; + struct sctp_transport *new_transport; sctp_chunk_t *chunk; sctp_xmit_t status; int error = 0; int start_timer = 0; - sctp_ulpevent_t *event; /* These transports have chunks to send. */ struct list_head transport_list; @@ -783,10 +819,8 @@ (*q->config_output)(packet, vtag, ecn_capable, ecne_handler); retran: - error = sctp_flush_retran_queue(q, - packet, - rtx_timeout, - &start_timer); + error = sctp_outq_flush_rtx(q, packet, + rtx_timeout, &start_timer); if (start_timer) sctp_transport_reset_timers(transport); @@ -813,15 +847,14 @@ */ if (chunk->sinfo.sinfo_stream >= asoc->c.sinit_num_ostreams) { + struct sctp_ulpevent *ev; + /* Generate a SEND FAILED event. */ - event = sctp_ulpevent_make_send_failed(asoc, - chunk, SCTP_DATA_UNSENT, - SCTP_ERROR_INV_STRM, - GFP_ATOMIC); - if (event) { - sctp_ulpqueue_tail_event(&asoc->ulpq, - event); - } + ev = sctp_ulpevent_make_send_failed(asoc, + chunk, SCTP_DATA_UNSENT, + SCTP_ERROR_INV_STRM, GFP_ATOMIC); + if (ev) + sctp_ulpq_tail_event(&asoc->ulpq, ev); /* Free the chunk. This chunk is not on any * list yet, just free it. @@ -830,6 +863,12 @@ continue; } + /* Now do delayed assignment of SSN. This will + * probably change again when we start supporting + * large (> approximately 2^16) size messages. + */ + sctp_chunk_assign_ssn(chunk); + /* If there is a specified transport, use it. * Otherwise, we want to use the active path. */ @@ -878,7 +917,7 @@ /* We could not append this chunk, so put * the chunk back on the output queue. */ - SCTP_DEBUG_PRINTK("sctp_flush_outqueue: could " + SCTP_DEBUG_PRINTK("sctp_outq_flush: could " "not transmit TSN: 0x%x, status: %d\n", ntohl(chunk->subh.data_hdr->tsn), status); @@ -952,8 +991,9 @@ * --xguo */ while ((ltransport = sctp_list_dequeue(&transport_list)) != NULL ) { - sctp_transport_t *t = list_entry(ltransport, - sctp_transport_t, send_ready); + struct sctp_transport *t = list_entry(ltransport, + struct sctp_transport, + send_ready); if (t != transport) transport = t; @@ -966,12 +1006,12 @@ } /* Set the various output handling callbacks. */ -int sctp_outqueue_set_output_handlers(sctp_outqueue_t *q, - sctp_outqueue_ohandler_init_t init, - sctp_outqueue_ohandler_config_t config, - sctp_outqueue_ohandler_t append, - sctp_outqueue_ohandler_t build, - sctp_outqueue_ohandler_force_t force) +int sctp_outq_set_output_handlers(struct sctp_outq *q, + sctp_outq_ohandler_init_t init, + sctp_outq_ohandler_config_t config, + sctp_outq_ohandler_t append, + sctp_outq_ohandler_t build, + sctp_outq_ohandler_force_t force) { q->init_output = init; q->config_output = config; @@ -1005,7 +1045,7 @@ sctp_association_t *asoc) { struct list_head *ltransport, *lchunk; - sctp_transport_t *transport; + struct sctp_transport *transport; sctp_chunk_t *chunk; __u32 highest_new_tsn, tsn; struct list_head *transport_list = &asoc->peer.transport_addr_list; @@ -1013,7 +1053,7 @@ highest_new_tsn = ntohl(sack->cum_tsn_ack); list_for_each(ltransport, transport_list) { - transport = list_entry(ltransport, sctp_transport_t, + transport = list_entry(ltransport, struct sctp_transport, transports); list_for_each(lchunk, &transport->transmitted) { chunk = list_entry(lchunk, sctp_chunk_t, @@ -1028,17 +1068,17 @@ } return highest_new_tsn; -} +} /* This is where we REALLY process a SACK. * - * Process the sack against the outqueue. Mostly, this just frees + * Process the SACK against the outqueue. Mostly, this just frees * things off the transmitted queue. */ -int sctp_sack_outqueue(sctp_outqueue_t *q, sctp_sackhdr_t *sack) +int sctp_outq_sack(struct sctp_outq *q, sctp_sackhdr_t *sack) { sctp_association_t *asoc = q->asoc; - sctp_transport_t *transport; + struct sctp_transport *transport; sctp_chunk_t *tchunk; struct list_head *lchunk, *transport_list, *pos; sctp_sack_variable_t *frags = sack->variable; @@ -1053,7 +1093,7 @@ sack_ctsn = ntohl(sack->cum_tsn_ack); /* Get the highest TSN in the sack. */ - highest_tsn = sack_ctsn + + highest_tsn = sack_ctsn + ntohs(frags[ntohs(sack->num_gap_ack_blocks) - 1].gab.end); if (TSN_lt(asoc->highest_sacked, highest_tsn)) { @@ -1074,7 +1114,8 @@ * This is a MASSIVE candidate for optimization. */ list_for_each(pos, transport_list) { - transport = list_entry(pos, sctp_transport_t, transports); + transport = list_entry(pos, struct sctp_transport, + transports); sctp_check_transmitted(q, &transport->transmitted, transport, sack, highest_new_tsn); } @@ -1127,7 +1168,8 @@ goto finish; list_for_each(pos, transport_list) { - transport = list_entry(pos, sctp_transport_t, transports); + transport = list_entry(pos, struct sctp_transport, + transports); q->empty = q->empty && list_empty(&transport->transmitted); if (!q->empty) goto finish; @@ -1139,7 +1181,7 @@ } /* Is the outqueue empty? */ -int sctp_outqueue_is_empty(const sctp_outqueue_t *q) +int sctp_outq_is_empty(const struct sctp_outq *q) { return q->empty; } @@ -1161,9 +1203,9 @@ * transmitted_queue, we print a range: SACKED: TSN1-TSN2, TSN3, TSN4-TSN5. * KEPT TSN6-TSN7, etc. */ -static void sctp_check_transmitted(sctp_outqueue_t *q, +static void sctp_check_transmitted(struct sctp_outq *q, struct list_head *transmitted_queue, - sctp_transport_t *transport, + struct sctp_transport *transport, sctp_sackhdr_t *sack, __u32 highest_new_tsn_in_sack) { @@ -1494,7 +1536,7 @@ if (transport) { if (do_fast_retransmit) - sctp_retransmit(q, transport, do_fast_retransmit); + sctp_retransmit(q, transport, SCTP_RETRANSMIT_FAST_RTX); SCTP_DEBUG_PRINTK("%s: transport: %p, cwnd: %d, " "ssthresh: %d, flight_size: %d, pba: %d\n", diff -Nru a/net/sctp/primitive.c b/net/sctp/primitive.c --- a/net/sctp/primitive.c Fri Feb 14 00:27:30 2003 +++ b/net/sctp/primitive.c Fri Feb 14 00:27:30 2003 @@ -203,23 +203,3 @@ */ DECLARE_PRIMITIVE(REQUESTHEARTBEAT); - -/* COMMENT BUG. Find out where this is mentioned in the spec. */ -int sctp_other_icmp_unreachfrag(sctp_association_t *asoc, void *arg) -{ - int error = 0; - sctp_event_t event_type; - sctp_subtype_t subtype; - sctp_state_t state; - sctp_endpoint_t *ep; - - event_type = SCTP_EVENT_T_OTHER; - subtype = SCTP_ST_OTHER(SCTP_EVENT_ICMP_UNREACHFRAG); - state = asoc ? asoc->state : SCTP_STATE_CLOSED; - ep = asoc ? asoc->ep : NULL; - - error = sctp_do_sm(event_type, subtype, state, ep, - asoc, arg, GFP_ATOMIC); - - return error; -} diff -Nru a/net/sctp/protocol.c b/net/sctp/protocol.c --- a/net/sctp/protocol.c Fri Feb 14 00:27:28 2003 +++ b/net/sctp/protocol.c Fri Feb 14 00:27:28 2003 @@ -82,7 +82,7 @@ } /* Set up the proc fs entry for the SCTP protocol. */ -void sctp_proc_init(void) +__init void sctp_proc_init(void) { if (!proc_net_sctp) { struct proc_dir_entry *ent; @@ -223,37 +223,6 @@ return error; } -/* Returns the dst cache entry for the given source and destination ip - * addresses. - */ -struct dst_entry *sctp_v4_get_dst(union sctp_addr *daddr, - union sctp_addr *saddr) -{ - struct rtable *rt; - struct flowi fl; - - memset(&fl, 0x0, sizeof(struct flowi)); - fl.fl4_dst = daddr->v4.sin_addr.s_addr; - fl.proto = IPPROTO_SCTP; - - if (saddr) - fl.fl4_src = saddr->v4.sin_addr.s_addr; - - SCTP_DEBUG_PRINTK("%s: DST:%u.%u.%u.%u, SRC:%u.%u.%u.%u - ", - __FUNCTION__, NIPQUAD(fl.fl4_dst), - NIPQUAD(fl.fl4_src)); - - if (ip_route_output_key(&rt, &fl)) { - SCTP_DEBUG_PRINTK("NO ROUTE\n"); - return NULL; - } - - SCTP_DEBUG_PRINTK("rt_dst:%u.%u.%u.%u, rt_src:%u.%u.%u.%u\n", - NIPQUAD(rt->rt_src), NIPQUAD(rt->rt_dst)); - - return &rt->u.dst; -} - /* Initialize a sctp_addr from in incoming skb. */ static void sctp_v4_from_skb(union sctp_addr *addr, struct sk_buff *skb, int is_saddr) @@ -292,10 +261,12 @@ /* Initialize a sctp_addr from a dst_entry. */ -static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst) +static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst, + unsigned short port) { struct rtable *rt = (struct rtable *)dst; saddr->v4.sin_family = AF_INET; + saddr->v4.sin_port = port; saddr->v4.sin_addr.s_addr = rt->rt_src; } @@ -394,6 +365,108 @@ return retval; } +/* Returns a valid dst cache entry for the given source and destination ip + * addresses. If an association is passed, trys to get a dst entry with a + * source adddress that matches an address in the bind address list. + */ +struct dst_entry *sctp_v4_get_dst(sctp_association_t *asoc, + union sctp_addr *daddr, + union sctp_addr *saddr) +{ + struct rtable *rt; + struct flowi fl; + sctp_bind_addr_t *bp; + rwlock_t *addr_lock; + struct sockaddr_storage_list *laddr; + struct list_head *pos; + struct dst_entry *dst = NULL; + union sctp_addr dst_saddr; + + memset(&fl, 0x0, sizeof(struct flowi)); + fl.fl4_dst = daddr->v4.sin_addr.s_addr; + fl.proto = IPPROTO_SCTP; + + if (saddr) + fl.fl4_src = saddr->v4.sin_addr.s_addr; + + SCTP_DEBUG_PRINTK("%s: DST:%u.%u.%u.%u, SRC:%u.%u.%u.%u - ", + __FUNCTION__, NIPQUAD(fl.fl4_dst), + NIPQUAD(fl.fl4_src)); + + if (!ip_route_output_key(&rt, &fl)) { + dst = &rt->u.dst; + } + + /* If there is no association or if a source address is passed, no + * more validation is required. + */ + if (!asoc || saddr) + goto out; + + bp = &asoc->base.bind_addr; + addr_lock = &asoc->base.addr_lock; + + if (dst) { + /* Walk through the bind address list and look for a bind + * address that matches the source address of the returned dst. + */ + sctp_read_lock(addr_lock); + list_for_each(pos, &bp->address_list) { + laddr = list_entry(pos, struct sockaddr_storage_list, + list); + sctp_v4_dst_saddr(&dst_saddr, dst, bp->port); + if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a)) + goto out_unlock; + } + sctp_read_unlock(addr_lock); + + /* None of the bound addresses match the source address of the + * dst. So release it. + */ + dst_release(dst); + dst = NULL; + } + + /* Walk through the bind address list and try to get a dst that + * matches a bind address as the source address. + */ + sctp_read_lock(addr_lock); + list_for_each(pos, &bp->address_list) { + laddr = list_entry(pos, struct sockaddr_storage_list, list); + + if (AF_INET == laddr->a.sa.sa_family) { + fl.fl4_src = laddr->a.v4.sin_addr.s_addr; + dst = sctp_v4_get_dst(asoc, daddr, &laddr->a); + if (!ip_route_output_key(&rt, &fl)) { + dst = &rt->u.dst; + goto out_unlock; + } + } + } + +out_unlock: + sctp_read_unlock(addr_lock); +out: + if (dst) + SCTP_DEBUG_PRINTK("rt_dst:%u.%u.%u.%u, rt_src:%u.%u.%u.%u\n", + NIPQUAD(rt->rt_dst), NIPQUAD(rt->rt_src)); + else + SCTP_DEBUG_PRINTK("NO ROUTE\n"); + + return dst; +} + +/* For v4, the source address is cached in the route entry(dst). So no need + * to cache it separately and hence this is an empty routine. + */ +void sctp_v4_get_saddr(sctp_association_t *asoc, + struct dst_entry *dst, + union sctp_addr *daddr, + union sctp_addr *saddr) +{ + +} + /* Event handler for inet address addition/deletion events. * Basically, whenever there is an event, we re-build our local address list. */ @@ -545,6 +618,19 @@ return sctp_v4_available(addr); } +/* Wrapper routine that calls the ip transmit routine. */ +static inline int sctp_v4_xmit(struct sk_buff *skb, + struct sctp_transport *transport, int ipfragok) +{ + SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, " + "src:%u.%u.%u.%u, dst:%u.%u.%u.%u\n", + __FUNCTION__, skb, skb->len, + NIPQUAD(((struct rtable *)skb->dst)->rt_src), + NIPQUAD(((struct rtable *)skb->dst)->rt_dst)); + + return ip_queue_xmit(skb, ipfragok); +} + struct sctp_af sctp_ipv4_specific; static struct sctp_pf sctp_pf_inet = { @@ -601,10 +687,11 @@ /* IPv4 address related functions. */ struct sctp_af sctp_ipv4_specific = { - .queue_xmit = ip_queue_xmit, + .sctp_xmit = sctp_v4_xmit, .setsockopt = ip_setsockopt, .getsockopt = ip_getsockopt, .get_dst = sctp_v4_get_dst, + .get_saddr = sctp_v4_get_saddr, .copy_addrlist = sctp_v4_copy_addrlist, .from_skb = sctp_v4_from_skb, .from_sk = sctp_v4_from_sk, @@ -688,7 +775,7 @@ } /* Initialize the universe into something sensible. */ -int sctp_init(void) +__init int sctp_init(void) { int i; int status = 0; @@ -750,13 +837,9 @@ /* Implementation specific variables. */ - /* Initialize default stream count setup information. - * Note: today the stream accounting data structures are very - * fixed size, so one really does need to make sure that these have - * upper/lower limits when changing. - */ - sctp_proto.max_instreams = SCTP_MAX_STREAM; - sctp_proto.max_outstreams = SCTP_MAX_STREAM; + /* Initialize default stream count setup information. */ + sctp_proto.max_instreams = SCTP_DEFAULT_INSTREAMS; + sctp_proto.max_outstreams = SCTP_DEFAULT_OUTSTREAMS; /* Allocate and initialize the association hash table. */ sctp_proto.assoc_hashsize = 4096; @@ -829,6 +912,7 @@ sctp_get_local_addr_list(&sctp_proto); + __unsafe(THIS_MODULE); return 0; err_ctl_sock_init: @@ -852,7 +936,7 @@ } /* Exit handler for the SCTP protocol. */ -void sctp_exit(void) +__exit void sctp_exit(void) { /* BUG. This should probably do something useful like clean * up all the remaining associations and all that memory. @@ -889,4 +973,3 @@ MODULE_AUTHOR("Linux Kernel SCTP developers "); MODULE_DESCRIPTION("Support for the SCTP protocol (RFC2960)"); MODULE_LICENSE("GPL"); - diff -Nru a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c --- a/net/sctp/sm_make_chunk.c Fri Feb 14 00:27:27 2003 +++ b/net/sctp/sm_make_chunk.c Fri Feb 14 00:27:27 2003 @@ -82,12 +82,12 @@ /* gcc 3.2 doesn't allow initialization of zero-length arrays. So the above * structure is split and the address types array is initialized using a - * fixed length array. + * fixed length array. */ static const __u16 sat_addr_types[2] = { SCTP_PARAM_IPV4_ADDRESS, SCTP_V6(SCTP_PARAM_IPV6_ADDRESS,) -}; +}; /* RFC 2960 3.3.2 Initiation (INIT) (1) * @@ -116,8 +116,8 @@ err.cause = cause_code; len = sizeof(sctp_errhdr_t) + paylen; padlen = len % 4; - len += padlen; err.length = htons(len); + len += padlen; sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); chunk->subh.err_hdr = sctp_addto_chunk(chunk, paylen, payload); } @@ -242,35 +242,10 @@ sctp_cookie_param_t *cookie; int cookie_len; size_t chunksize; - int error; - sctp_scope_t scope; - sctp_bind_addr_t *bp = NULL; - int flags; retval = NULL; - /* Build up the bind address list for the association based on - * info from the local endpoint and the remote peer. - */ - bp = sctp_bind_addr_new(priority); - if (!bp) - goto nomem_bindaddr; - - /* Look for supported address types parameter and then build - * our address list based on that. - */ - scope = sctp_scope(&asoc->peer.active_path->ipaddr); - flags = (PF_INET6 == asoc->base.sk->family) ? SCTP_ADDR6_ALLOWED : 0; - if (asoc->peer.ipv4_address) - flags |= SCTP_ADDR4_PEERSUPP; - if (asoc->peer.ipv6_address) - flags |= SCTP_ADDR6_PEERSUPP; - error = sctp_bind_addr_copy(bp, &asoc->ep->base.bind_addr, - scope, priority, flags); - if (error) - goto nomem_copyaddr; - - addrs = sctp_bind_addrs_to_raw(bp, &addrs_len, priority); + addrs = sctp_bind_addrs_to_raw(&asoc->base.bind_addr, &addrs_len, priority); if (!addrs.v) goto nomem_rawaddr; @@ -333,9 +308,6 @@ nomem_cookie: kfree(addrs.v); nomem_rawaddr: -nomem_copyaddr: - sctp_bind_addr_free(bp); -nomem_bindaddr: return retval; } @@ -598,23 +570,9 @@ const struct sctp_sndrcvinfo *sinfo, int data_len) { - __u16 ssn; __u8 flags = SCTP_DATA_NOT_FRAG; - /* Sockets API Extensions for SCTP 5.2.2 - * MSG_UNORDERED - This flag requests the un-ordered delivery of the - * message. If this flag is clear, the datagram is considered an - * ordered send and a new ssn is generated. The flags field is set - * in the inner routine - sctp_make_datafrag_empty(). - */ - if (sinfo->sinfo_flags & MSG_UNORDERED) { - ssn = 0; - } else { - ssn = __sctp_association_get_next_ssn(asoc, - sinfo->sinfo_stream); - } - - return sctp_make_datafrag_empty(asoc, sinfo, data_len, flags, ssn); + return sctp_make_datafrag_empty(asoc, sinfo, data_len, flags, 0); } /* Create a selective ackowledgement (SACK) for the given @@ -714,6 +672,7 @@ return retval; } +/* FIXME: Comments. */ sctp_chunk_t *sctp_make_shutdown(const sctp_association_t *asoc) { sctp_chunk_t *retval; @@ -897,7 +856,7 @@ /* Make a HEARTBEAT chunk. */ sctp_chunk_t *sctp_make_heartbeat(const sctp_association_t *asoc, - const sctp_transport_t *transport, + const struct sctp_transport *transport, const void *payload, const size_t paylen) { sctp_chunk_t *retval = sctp_make_chunk(asoc, SCTP_CID_HEARTBEAT, @@ -909,7 +868,7 @@ /* Cast away the 'const', as this is just telling the chunk * what transport it belongs to. */ - retval->transport = (sctp_transport_t *) transport; + retval->transport = (struct sctp_transport *) transport; retval->subh.hbs_hdr = sctp_addto_chunk(retval, paylen, payload); nodata: @@ -1013,6 +972,7 @@ retval->asoc = (sctp_association_t *) asoc; retval->num_times_sent = 0; retval->has_tsn = 0; + retval->has_ssn = 0; retval->rtt_in_progress = 0; retval->sent_at = jiffies; retval->singleton = 1; @@ -1118,53 +1078,6 @@ SCTP_DBG_OBJCNT_DEC(chunk); } -/* Do a deep copy of a chunk. */ -sctp_chunk_t *sctp_copy_chunk(sctp_chunk_t *chunk, const int priority) -{ - sctp_chunk_t *retval; - long offset; - - retval = t_new(sctp_chunk_t, priority); - if (!retval) - goto nodata; - - /* Do the shallow copy. */ - *retval = *chunk; - - /* Make sure that the copy does NOT think it is on any lists. */ - retval->next = NULL; - retval->prev = NULL; - retval->list = NULL; - INIT_LIST_HEAD(&retval->transmitted_list); - INIT_LIST_HEAD(&retval->frag_list); - - /* Now we copy the deep structure. */ - retval->skb = skb_copy(chunk->skb, priority); - if (!retval->skb) { - kfree(retval); - goto nodata; - } - - /* Move the copy headers to point into the new skb. */ - offset = ((__u8 *)retval->skb->head) - - ((__u8 *)chunk->skb->head); - - if (retval->param_hdr.v) - retval->param_hdr.v += offset; - if (retval->subh.v) - retval->subh.v += offset; - if (retval->chunk_end) - ((__u8 *) retval->chunk_end) += offset; - if (retval->chunk_hdr) - ((__u8 *) retval->chunk_hdr) += offset; - if (retval->sctp_hdr) - ((__u8 *) retval->sctp_hdr) += offset; - SCTP_DBG_OBJCNT_INC(chunk); - return retval; - -nodata: - return NULL; -} /* Append bytes to the end of a chunk. Will panic if chunk is not big * enough. @@ -1193,7 +1106,8 @@ * chunk is not big enough. * Returns a kernel err value. */ -int sctp_user_addto_chunk(sctp_chunk_t *chunk, int len, struct iovec *data) +static int sctp_user_addto_chunk(sctp_chunk_t *chunk, int off, int len, + struct iovec *data) { __u8 *target; int err = 0; @@ -1202,7 +1116,7 @@ target = skb_put(chunk->skb, len); /* Copy data (whole iovec) into chunk */ - if ((err = memcpy_fromiovec(target, data, len))) + if ((err = memcpy_fromiovecend(target, data, off, len))) goto out; /* Adjust the chunk length field. */ @@ -1214,6 +1128,152 @@ return err; } +/* A data chunk can have a maximum payload of (2^16 - 20). Break + * down any such message into smaller chunks. Opportunistically, fragment + * the chunks down to the current MTU constraints. We may get refragmented + * later if the PMTU changes, but it is _much better_ to fragment immediately + * with a reasonable guess than always doing our fragmentation on the + * soft-interrupt. + */ + + +int sctp_datachunks_from_user(sctp_association_t *asoc, + const struct sctp_sndrcvinfo *sinfo, + struct msghdr *msg, int msg_len, + struct sk_buff_head *chunks) +{ + int max, whole, i, offset, over, err; + int len, first_len; + sctp_chunk_t *chunk; + __u8 frag; + + /* What is a reasonable fragmentation point right now? */ + max = asoc->pmtu; + if (max < SCTP_MIN_PMTU) + max = SCTP_MIN_PMTU; + max -= SCTP_IP_OVERHEAD; + + /* Make sure not beyond maximum chunk size. */ + if (max > SCTP_MAX_CHUNK_LEN) + max = SCTP_MAX_CHUNK_LEN; + + /* Subtract out the overhead of a data chunk header. */ + max -= sizeof(struct sctp_data_chunk); + + whole = 0; + first_len = max; + + /* Encourage Cookie-ECHO bundling. */ + if (asoc->state < SCTP_STATE_ESTABLISHED) { + whole = msg_len / (max - SCTP_ARBITRARY_COOKIE_ECHO_LEN); + + /* Account for the DATA to be bundled with the COOKIE-ECHO. */ + if (whole) { + first_len = max - SCTP_ARBITRARY_COOKIE_ECHO_LEN; + msg_len -= first_len; + whole = 1; + } + } + + /* How many full sized? How many bytes leftover? */ + whole += msg_len / max; + over = msg_len % max; + offset = 0; + + /* Create chunks for all the full sized DATA chunks. */ + for (i=0, len=first_len; i < whole; i++) { + frag = SCTP_DATA_MIDDLE_FRAG; + + if (0 == i) + frag |= SCTP_DATA_FIRST_FRAG; + + if ((i == (whole - 1)) && !over) + frag |= SCTP_DATA_LAST_FRAG; + + chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0); + + if (!chunk) + goto nomem; + err = sctp_user_addto_chunk(chunk, offset, len, msg->msg_iov); + if (err < 0) + goto errout; + + offset += len; + + /* Put the chunk->skb back into the form expected by send. */ + __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr + - (__u8 *)chunk->skb->data); + + __skb_queue_tail(chunks, (struct sk_buff *)chunk); + + /* The first chunk, the first chunk was likely short + * to allow bundling, so reset to full size. + */ + if (0 == i) + len = max; + } + + /* .. now the leftover bytes. */ + if (over) { + if (!whole) + frag = SCTP_DATA_NOT_FRAG; + else + frag = SCTP_DATA_LAST_FRAG; + + chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0); + + if (!chunk) + goto nomem; + + err = sctp_user_addto_chunk(chunk, offset, over, msg->msg_iov); + + /* Put the chunk->skb back into the form expected by send. */ + __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr + - (__u8 *)chunk->skb->data); + if (err < 0) + goto errout; + + __skb_queue_tail(chunks, (struct sk_buff *)chunk); + } + err = 0; + goto out; + +nomem: + err = -ENOMEM; +errout: + while ((chunk = (sctp_chunk_t *)__skb_dequeue(chunks))) + sctp_free_chunk(chunk); +out: + return err; +} + +/* Helper function to assign a TSN if needed. This assumes that both + * the data_hdr and association have already been assigned. + */ +void sctp_chunk_assign_ssn(sctp_chunk_t *chunk) +{ + __u16 ssn; + __u16 sid; + + if (chunk->has_ssn) + return; + + /* This is the last possible instant to assign a SSN. */ + if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { + ssn = 0; + } else { + sid = htons(chunk->subh.data_hdr->stream); + if (chunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG) + ssn = sctp_ssn_next(&chunk->asoc->ssnmap->out, sid); + else + ssn = sctp_ssn_peek(&chunk->asoc->ssnmap->out, sid); + ssn = htons(ssn); + } + + chunk->subh.data_hdr->ssn = ssn; + chunk->has_ssn = 1; +} + /* Helper function to assign a TSN if needed. This assumes that both * the data_hdr and association have already been assigned. */ @@ -1352,11 +1412,10 @@ sctp_signed_cookie_t *cookie; sctp_cookie_t *bear_cookie; int headersize, bodysize; - int fixed_size, var_size1, var_size2, var_size3; + int fixed_size; __u8 digest_buf[SCTP_SIGNATURE_SIZE]; int secret; sctp_scope_t scope; - __u8 *raw_addr_list; headersize = sizeof(sctp_chunkhdr_t) + SCTP_SECRET_SIZE; bodysize = ntohs(chunk->chunk_hdr->length) - headersize; @@ -1377,9 +1436,6 @@ /* Process the cookie. */ cookie = chunk->subh.cookie_hdr; bear_cookie = &cookie->c; - var_size1 = ntohs(chunk->chunk_hdr->length) - fixed_size; - var_size2 = ntohs(bear_cookie->peer_init->chunk_hdr.length); - var_size3 = bear_cookie->raw_addr_list_len; /* Check the signature. */ secret = ep->current_key; @@ -1403,6 +1459,7 @@ * for init collision case of lost COOKIE ACK. */ if (!asoc && tv_lt(bear_cookie->expiration, chunk->skb->stamp)) { + __u16 len; /* * Section 3.3.10.3 Stale Cookie Error (3) * @@ -1411,8 +1468,8 @@ * Stale Cookie Error: Indicates the receipt of a valid State * Cookie that has expired. */ - *err_chk_p = sctp_make_op_error_space(asoc, chunk, - ntohs(chunk->chunk_hdr->length)); + len = ntohs(chunk->chunk_hdr->length); + *err_chk_p = sctp_make_op_error_space(asoc, chunk, len); if (*err_chk_p) { suseconds_t usecs = (chunk->skb->stamp.tv_sec - bear_cookie->expiration.tv_sec) * 1000000L + @@ -1443,12 +1500,8 @@ /* Populate the association from the cookie. */ retval->c = *bear_cookie; - /* Build the bind address list based on the cookie. */ - raw_addr_list = (__u8 *) bear_cookie + - sizeof(sctp_cookie_t) + var_size2; - if (sctp_raw_to_bind_addrs(&retval->base.bind_addr, raw_addr_list, - var_size3, retval->base.bind_addr.port, - priority)) { + if (sctp_assoc_set_bind_addr_from_cookie(retval, bear_cookie, + GFP_ATOMIC) < 0) { *error = -SCTP_IERROR_NOMEM; goto fail; } @@ -1477,6 +1530,57 @@ * 3rd Level Abstractions ********************************************************************/ +/* + * Report a missing mandatory parameter. + */ +struct __sctp_missing { + __u32 num_missing; + __u16 type; +} __attribute__((packed));; +static int sctp_process_missing_param(const sctp_association_t *asoc, + sctp_param_t paramtype, + sctp_chunk_t *chunk, + sctp_chunk_t **err_chk_p) +{ + struct __sctp_missing report; + __u16 len; + + len = WORD_ROUND(sizeof(report)); + + /* Make an ERROR chunk, preparing enough room for + * returning multiple unknown parameters. + */ + if (!*err_chk_p) + *err_chk_p = sctp_make_op_error_space(asoc, chunk, len); + + if (*err_chk_p) { + report.num_missing = htonl(1); + report.type = paramtype; + sctp_init_cause(*err_chk_p, SCTP_ERROR_INV_PARAM, + &report, sizeof(report)); + } + + /* Stop processing this chunk. */ + return 0; +} + +/* Report an Invalid Mandatory Parameter. */ +static int sctp_process_inv_mandatory(const sctp_association_t *asoc, + sctp_chunk_t *chunk, + sctp_chunk_t **err_chk_p) +{ + /* Invalid Mandatory Parameter Error has no payload. */ + + if (!*err_chk_p) + *err_chk_p = sctp_make_op_error_space(asoc, chunk, 0); + + if (*err_chk_p) + sctp_init_cause(*err_chk_p, SCTP_ERROR_INV_PARAM, NULL, 0); + + /* Stop processing this chunk. */ + return 0; +} + /* Do not attempt to handle the HOST_NAME parm. However, do * send back an indicator to the peer. */ @@ -1487,9 +1591,7 @@ { __u16 len = ntohs(param.p->length); - /* Make an ERROR chunk, preparing enough room for - * returning multiple unknown parameters. - */ + /* Make an ERROR chunk. */ if (!*err_chk_p) *err_chk_p = sctp_make_op_error_space(asoc, chunk, len); @@ -1570,7 +1672,8 @@ } else { /* If there is no memory for generating the ERROR * report as specified, an ABORT will be triggered - * to the peer and the association won't be established. + * to the peer and the association won't be + * established. */ retval = 0; } @@ -1633,12 +1736,33 @@ sctp_chunk_t **err_chk_p) { union sctp_params param; + int has_cookie = 0; + + /* Verify stream values are non-zero. */ + if ((0 == peer_init->init_hdr.num_outbound_streams) || + (0 == peer_init->init_hdr.num_inbound_streams)) { - /* FIXME - Verify the fixed fields of the INIT chunk. Also, verify - * the mandatory parameters somewhere here and generate either the - * "Missing mandatory parameter" error or the "Invalid mandatory - * parameter" error. + sctp_process_inv_mandatory(asoc, chunk, err_chk_p); + return 0; + } + + /* Check for missing mandatory parameters. */ + sctp_walk_params(param, peer_init, init_hdr.params) { + + if (SCTP_PARAM_STATE_COOKIE == param.p->type) + has_cookie = 1; + + } /* for (loop through all parameters) */ + + /* The only missing mandatory param possible today is + * the state cookie for an INIT-ACK chunk. */ + if ((SCTP_CID_INIT_ACK == cid) && !has_cookie) { + + sctp_process_missing_param(asoc, SCTP_PARAM_STATE_COOKIE, + chunk, err_chk_p); + return 0; + } /* Find unrecognized parameters. */ @@ -1654,6 +1778,7 @@ /* Unpack the parameters in an INIT packet into an association. * Returns 0 on failure, else success. + * FIXME: This is an association method. */ int sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid, const union sctp_addr *peer_addr, @@ -1661,7 +1786,7 @@ int priority) { union sctp_params param; - sctp_transport_t *transport; + struct sctp_transport *transport; struct list_head *pos, *temp; char *cookie; @@ -1710,6 +1835,12 @@ ntohs(peer_init->init_hdr.num_inbound_streams); } + if (asoc->c.sinit_max_instreams > + ntohs(peer_init->init_hdr.num_outbound_streams)) { + asoc->c.sinit_max_instreams = + ntohs(peer_init->init_hdr.num_outbound_streams); + } + /* Copy Initiation tag from INIT to VT_peer in cookie. */ asoc->c.peer_vtag = asoc->peer.i.init_tag; @@ -1730,7 +1861,7 @@ * advertised window). */ list_for_each(pos, &asoc->peer.transport_addr_list) { - transport = list_entry(pos, sctp_transport_t, transports); + transport = list_entry(pos, struct sctp_transport, transports); transport->ssthresh = asoc->peer.i.a_rwnd; } @@ -1738,6 +1869,21 @@ sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, asoc->peer.i.initial_tsn); + /* RFC 2960 6.5 Stream Identifier and Stream Sequence Number + * + * The stream sequence number in all the streams shall start + * from 0 when the association is established. Also, when the + * stream sequence number reaches the value 65535 the next + * stream sequence number shall be set to 0. + */ + + /* Allocate storage for the negotiated streams. */ + asoc->ssnmap = sctp_ssnmap_new(asoc->peer.i.num_outbound_streams, + asoc->c.sinit_num_ostreams, + priority); + if (!asoc->ssnmap) + goto nomem_ssnmap; + /* ADDIP Section 4.1 ASCONF Chunk Procedures * * When an endpoint has an ASCONF signaled change to be sent to the @@ -1751,10 +1897,11 @@ asoc->peer.addip_serial = asoc->peer.i.initial_tsn - 1; return 1; +nomem_ssnmap: clean_up: /* Release the transport structures. */ list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { - transport = list_entry(pos, sctp_transport_t, transports); + transport = list_entry(pos, struct sctp_transport, transports); list_del(pos); sctp_transport_free(transport); } diff -Nru a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c --- a/net/sctp/sm_sideeffect.c Fri Feb 14 00:27:29 2003 +++ b/net/sctp/sm_sideeffect.c Fri Feb 14 00:27:29 2003 @@ -56,33 +56,29 @@ #include /* Do forward declarations of static functions. */ -static void sctp_do_ecn_ce_work(sctp_association_t *asoc, - __u32 lowest_tsn); +static void sctp_do_ecn_ce_work(sctp_association_t *,__u32 lowest_tsn); static sctp_chunk_t *sctp_do_ecn_ecne_work(sctp_association_t *asoc, __u32 lowest_tsn, sctp_chunk_t *); -static void sctp_do_ecn_cwr_work(sctp_association_t *asoc, - __u32 lowest_tsn); - -static void sctp_do_8_2_transport_strike(sctp_association_t *asoc, - sctp_transport_t *transport); -static void sctp_cmd_init_failed(sctp_cmd_seq_t *, sctp_association_t *asoc); -static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *, sctp_association_t *asoc, - sctp_event_t event_type, sctp_subtype_t stype, +static void sctp_do_ecn_cwr_work(sctp_association_t *,__u32 lowest_tsn); +static void sctp_do_8_2_transport_strike(sctp_association_t *, + struct sctp_transport *); +static void sctp_cmd_init_failed(sctp_cmd_seq_t *, sctp_association_t *); +static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *, sctp_association_t *, + sctp_event_t, sctp_subtype_t, sctp_chunk_t *chunk); -static int sctp_cmd_process_init(sctp_cmd_seq_t *, sctp_association_t *asoc, +static int sctp_cmd_process_init(sctp_cmd_seq_t *, sctp_association_t *, sctp_chunk_t *chunk, sctp_init_chunk_t *peer_init, int priority); static void sctp_cmd_hb_timers_start(sctp_cmd_seq_t *, sctp_association_t *); -static void sctp_cmd_hb_timers_update(sctp_cmd_seq_t *, sctp_association_t *, - sctp_transport_t *); -static void sctp_cmd_set_bind_addrs(sctp_cmd_seq_t *, sctp_association_t *, - sctp_bind_addr_t *); +static void sctp_cmd_hb_timers_stop(sctp_cmd_seq_t *, sctp_association_t *); +static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *, sctp_association_t *, + struct sctp_transport *); static void sctp_cmd_transport_reset(sctp_cmd_seq_t *, sctp_association_t *, - sctp_transport_t *); + struct sctp_transport *); static void sctp_cmd_transport_on(sctp_cmd_seq_t *, sctp_association_t *, - sctp_transport_t *, sctp_chunk_t *); + struct sctp_transport *, sctp_chunk_t *); static int sctp_cmd_process_sack(sctp_cmd_seq_t *, sctp_association_t *, sctp_sackhdr_t *); static void sctp_cmd_setup_t2(sctp_cmd_seq_t *, sctp_association_t *, @@ -264,7 +260,7 @@ struct list_head *pos; struct timer_list *timer; unsigned long timeout; - sctp_transport_t *t; + struct sctp_transport *t; sctp_sackhdr_t sackh; if(SCTP_EVENT_T_TIMEOUT != event_type) @@ -296,7 +292,7 @@ break; case SCTP_CMD_PURGE_OUTQUEUE: - sctp_outqueue_teardown(&asoc->outqueue); + sctp_outq_teardown(&asoc->outqueue); break; case SCTP_CMD_DELETE_TCB: @@ -395,9 +391,9 @@ command->obj.ptr, "ulpq:", &asoc->ulpq); - sctp_ulpqueue_tail_data(&asoc->ulpq, - command->obj.ptr, - GFP_ATOMIC); + sctp_ulpq_tail_data(&asoc->ulpq, + command->obj.ptr, + GFP_ATOMIC); break; case SCTP_CMD_EVENT_ULP: @@ -407,14 +403,14 @@ command->obj.ptr, "ulpq:", &asoc->ulpq); - sctp_ulpqueue_tail_event(&asoc->ulpq, - command->obj.ptr); + sctp_ulpq_tail_event(&asoc->ulpq, + command->obj.ptr); break; case SCTP_CMD_REPLY: /* Send a chunk to our peer. */ - error = sctp_push_outqueue(&asoc->outqueue, - command->obj.ptr); + error = sctp_outq_tail(&asoc->outqueue, + command->obj.ptr); break; case SCTP_CMD_SEND_PKT: @@ -427,12 +423,13 @@ case SCTP_CMD_RETRAN: /* Mark a transport for retransmission. */ sctp_retransmit(&asoc->outqueue, - command->obj.transport, 0); + command->obj.transport, + SCTP_RETRANSMIT_T3_RTX); break; case SCTP_CMD_TRANSMIT: /* Kick start transmission. */ - error = sctp_flush_outqueue(&asoc->outqueue, 0); + error = sctp_outq_flush(&asoc->outqueue, 0); break; case SCTP_CMD_ECN_CE: @@ -502,7 +499,7 @@ * COOKIE-ECHO we need to resend. */ list_for_each(pos, &asoc->peer.transport_addr_list) { - t = list_entry(pos, sctp_transport_t, + t = list_entry(pos, struct sctp_transport, transports); sctp_retransmit_mark(&asoc->outqueue, t, 0); } @@ -547,11 +544,6 @@ SCTP_DEBUG_PRINTK("vtag mismatch!\n"); break; - case SCTP_CMD_SET_BIND_ADDR: - sctp_cmd_set_bind_addrs(commands, asoc, - command->obj.bp); - break; - case SCTP_CMD_STRIKE: /* Mark one strike against a transport. */ sctp_do_8_2_transport_strike(asoc, @@ -572,9 +564,13 @@ sctp_cmd_hb_timers_start(commands, asoc); break; - case SCTP_CMD_HB_TIMERS_UPDATE: + case SCTP_CMD_HB_TIMER_UPDATE: t = command->obj.transport; - sctp_cmd_hb_timers_update(commands, asoc, t); + sctp_cmd_hb_timer_update(commands, asoc, t); + break; + + case SCTP_CMD_HB_TIMERS_STOP: + sctp_cmd_hb_timers_stop(commands, asoc); break; case SCTP_CMD_REPORT_ERROR: @@ -599,7 +595,7 @@ case SCTP_CMD_RTO_PENDING: t = command->obj.transport; - t->rto_pending = 1; + t->rto_pending = 1; break; default: @@ -656,7 +652,7 @@ * recent than the last response. */ if (TSN_lt(asoc->last_cwr_tsn, lowest_tsn)) { - sctp_transport_t *transport; + struct sctp_transport *transport; /* Find which transport's congestion variables * need to be adjusted. @@ -743,7 +739,7 @@ asoc->peer.sack_needed = 0; asoc->peer.next_dup_tsn = 0; - error = sctp_push_outqueue(&asoc->outqueue, sack); + error = sctp_outq_tail(&asoc->outqueue, sack); /* Stop the SACK timer. */ sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, @@ -802,7 +798,7 @@ void sctp_generate_t3_rtx_event(unsigned long peer) { int error; - sctp_transport_t *transport = (sctp_transport_t *) peer; + struct sctp_transport *transport = (struct sctp_transport *) peer; sctp_association_t *asoc = transport->asoc; /* Check whether a task is in the sock. */ @@ -917,7 +913,7 @@ void sctp_generate_heartbeat_event(unsigned long data) { int error = 0; - sctp_transport_t *transport = (sctp_transport_t *) data; + struct sctp_transport *transport = (struct sctp_transport *) data; sctp_association_t *asoc = transport->asoc; sctp_bh_lock_sock(asoc->base.sk); @@ -957,24 +953,16 @@ sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_SACK); } -void sctp_generate_pmtu_raise_event(unsigned long data) -{ - sctp_association_t *asoc = (sctp_association_t *) data; - sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_PMTU_RAISE); -} - sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = { NULL, sctp_generate_t1_cookie_event, sctp_generate_t1_init_event, sctp_generate_t2_shutdown_event, NULL, - NULL, sctp_generate_t5_shutdown_guard_event, sctp_generate_heartbeat_event, sctp_generate_sack_event, sctp_generate_autoclose_event, - sctp_generate_pmtu_raise_event, }; /******************************************************************** @@ -997,7 +985,7 @@ * */ static void sctp_do_8_2_transport_strike(sctp_association_t *asoc, - sctp_transport_t *transport) + struct sctp_transport *transport) { /* The check for association's overall error counter exceeding the * threshold is done in the state function. @@ -1095,7 +1083,7 @@ /* Process an init chunk (may be real INIT/INIT-ACK or an embedded INIT * inside the cookie. In reality, this is only used for INIT-ACK processing * since all other cases use "temporary" associations and can do all - * their work in statefuns directly. + * their work in statefuns directly. */ static int sctp_cmd_process_init(sctp_cmd_seq_t *commands, sctp_association_t *asoc, @@ -1125,7 +1113,7 @@ static void sctp_cmd_hb_timers_start(sctp_cmd_seq_t *cmds, sctp_association_t *asoc) { - sctp_transport_t *t; + struct sctp_transport *t; struct list_head *pos; /* Start a heartbeat timer for each transport on the association. @@ -1133,45 +1121,43 @@ * the needed data structures go away. */ list_for_each(pos, &asoc->peer.transport_addr_list) { - t = list_entry(pos, sctp_transport_t, transports); - if (!mod_timer(&t->hb_timer, - t->hb_interval + t->rto + jiffies)) { + t = list_entry(pos, struct sctp_transport, transports); + + if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t))) sctp_transport_hold(t); - } } } -/* Helper function to update the heartbeat timer. */ -static void sctp_cmd_hb_timers_update(sctp_cmd_seq_t *cmds, - sctp_association_t *asoc, - sctp_transport_t *t) +static void sctp_cmd_hb_timers_stop(sctp_cmd_seq_t *cmds, + sctp_association_t *asoc) { - /* Update the heartbeat timer. */ - if (!mod_timer(&t->hb_timer, t->hb_interval + t->rto + jiffies)) - sctp_transport_hold(t); -} + struct sctp_transport *t; + struct list_head *pos; + + /* Stop all heartbeat timers. */ -/* Helper function to break out SCTP_CMD_SET_BIND_ADDR handling. */ -void sctp_cmd_set_bind_addrs(sctp_cmd_seq_t *cmds, sctp_association_t *asoc, - sctp_bind_addr_t *bp) -{ - struct list_head *pos, *temp; - - list_for_each_safe(pos, temp, &bp->address_list) { - list_del_init(pos); - list_add_tail(pos, &asoc->base.bind_addr.address_list); + list_for_each(pos, &asoc->peer.transport_addr_list) { + t = list_entry(pos, struct sctp_transport, transports); + if (del_timer(&t->hb_timer)) + sctp_transport_put(t); } +} - /* Free the temporary bind addr header, otherwise - * there will a memory leak. - */ - sctp_bind_addr_free(bp); +/* Helper function to update the heartbeat timer. */ +static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds, + sctp_association_t *asoc, + struct sctp_transport *t) +{ + /* Update the heartbeat timer. */ + if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t))) + sctp_transport_hold(t); } /* Helper function to handle the reception of an HEARTBEAT ACK. */ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, sctp_association_t *asoc, - sctp_transport_t *t, sctp_chunk_t *chunk) + struct sctp_transport *t, + sctp_chunk_t *chunk) { sctp_sender_hb_info_t *hbinfo; @@ -1203,7 +1189,7 @@ */ static void sctp_cmd_transport_reset(sctp_cmd_seq_t *cmds, sctp_association_t *asoc, - sctp_transport_t *t) + struct sctp_transport *t) { sctp_transport_lower_cwnd(t, SCTP_LOWER_CWND_INACTIVE); @@ -1218,7 +1204,7 @@ { int err; - if (sctp_sack_outqueue(&asoc->outqueue, sackh)) { + if (sctp_outq_sack(&asoc->outqueue, sackh)) { /* There are no more TSNs awaiting SACK. */ err = sctp_do_sm(SCTP_EVENT_T_OTHER, SCTP_ST_OTHER(SCTP_EVENT_NO_PENDING_TSN), @@ -1228,7 +1214,7 @@ /* Windows may have opened, so we need * to check if we have DATA to transmit */ - err = sctp_flush_outqueue(&asoc->outqueue, 0); + err = sctp_outq_flush(&asoc->outqueue, 0); } return err; @@ -1240,7 +1226,7 @@ static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds, sctp_association_t *asoc, sctp_chunk_t *chunk) { - sctp_transport_t *t; + struct sctp_transport *t; t = sctp_assoc_choose_shutdown_transport(asoc); asoc->shutdown_last_sent_to = t; diff -Nru a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c --- a/net/sctp/sm_statefuns.c Fri Feb 14 00:27:26 2003 +++ b/net/sctp/sm_statefuns.c Fri Feb 14 00:27:26 2003 @@ -191,7 +191,7 @@ int len; /* If the packet is an OOTB packet which is temporarily on the - * control endpoint, responding with an ABORT. + * control endpoint, respond with an ABORT. */ if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) return sctp_sf_ootb(ep, asoc, type, arg, commands); @@ -262,6 +262,9 @@ len = ntohs(err_chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); + if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) + goto nomem_ack; + repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); if (!repl) goto nomem_ack; @@ -506,7 +509,7 @@ sctp_chunk_t *err_chk_p; /* If the packet is an OOTB packet which is temporarily on the - * control endpoint, responding with an ABORT. + * control endpoint, respond with an ABORT. */ if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) return sctp_sf_ootb(ep, asoc, type, arg, commands); @@ -678,7 +681,7 @@ void *arg, sctp_cmd_seq_t *commands) { - sctp_transport_t *transport = (sctp_transport_t *) arg; + struct sctp_transport *transport = (struct sctp_transport *) arg; sctp_chunk_t *reply; sctp_sender_hb_info_t hbinfo; size_t paylen = 0; @@ -711,7 +714,7 @@ void *arg, sctp_cmd_seq_t *commands) { - sctp_transport_t *transport = (sctp_transport_t *) arg; + struct sctp_transport *transport = (struct sctp_transport *) arg; if (asoc->overall_error_count >= asoc->overall_error_threshold) { /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ @@ -737,7 +740,7 @@ sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET, SCTP_TRANSPORT(transport)); } - sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_UPDATE, + sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE, SCTP_TRANSPORT(transport)); return SCTP_DISPOSITION_CONSUME; @@ -842,7 +845,7 @@ { sctp_chunk_t *chunk = arg; union sctp_addr from_addr; - sctp_transport_t *link; + struct sctp_transport *link; sctp_sender_hb_info_t *hbinfo; unsigned long max_interval; @@ -944,7 +947,7 @@ sctp_chunk_t *init, sctp_cmd_seq_t *commands) { - sctp_transport_t *new_addr, *addr; + struct sctp_transport *new_addr, *addr; struct list_head *pos, *pos2; int found; @@ -963,10 +966,11 @@ found = 0; list_for_each(pos, &new_asoc->peer.transport_addr_list) { - new_addr = list_entry(pos, sctp_transport_t, transports); + new_addr = list_entry(pos, struct sctp_transport, transports); found = 0; list_for_each(pos2, &asoc->peer.transport_addr_list) { - addr = list_entry(pos2, sctp_transport_t, transports); + addr = list_entry(pos2, struct sctp_transport, + transports); if (sctp_cmp_addr_exact(&new_addr->ipaddr, &addr->ipaddr)) { found = 1; @@ -1048,20 +1052,17 @@ (asoc->c.peer_vtag == new_asoc->c.peer_ttag)) return 'A'; - /* Collision case D. - * Note: Test case D first, otherwise it may be incorrectly - * identified as second case of B if the value of the Tie_tag is - * not filled into the state cookie. - */ - if ((asoc->c.my_vtag == new_asoc->c.my_vtag) && - (asoc->c.peer_vtag == new_asoc->c.peer_vtag)) - return 'D'; - /* Collision case B. */ if ((asoc->c.my_vtag == new_asoc->c.my_vtag) && ((asoc->c.peer_vtag != new_asoc->c.peer_vtag) || - (!new_asoc->c.my_ttag && !new_asoc->c.peer_ttag))) + (0 == asoc->c.peer_vtag))) { return 'B'; + } + + /* Collision case D. */ + if ((asoc->c.my_vtag == new_asoc->c.my_vtag) && + (asoc->c.peer_vtag == new_asoc->c.peer_vtag)) + return 'D'; /* Collision case C. */ if ((asoc->c.my_vtag != new_asoc->c.my_vtag) && @@ -1070,7 +1071,8 @@ (0 == new_asoc->c.peer_ttag)) return 'C'; - return 'E'; /* No such case available. */ + /* No match to any of the special cases; discard this packet. */ + return 'E'; } /* Common helper routine for both duplicate and simulataneous INIT @@ -1182,6 +1184,10 @@ len = ntohs(err_chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); } + + if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) + goto nomem; + repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); if (!repl) goto nomem; @@ -1337,7 +1343,7 @@ -/* Unexpected COOKIE-ECHO handlerfor peer restart (Table 2, action 'A') +/* Unexpected COOKIE-ECHO handler for peer restart (Table 2, action 'A') * * Section 5.2.4 * A) In this case, the peer may have restarted. @@ -1500,11 +1506,17 @@ sctp_ulpevent_t *ev = NULL; sctp_chunk_t *repl; - /* The local endpoint cannot use any value from the received - * state cookie and need to immediately resend a COOKIE-ACK - * and move into ESTABLISHED if it hasn't done so. + /* Clarification from Implementor's Guide: + * D) When both local and remote tags match the endpoint should + * enter the ESTABLISHED state, if it is in the COOKIE-ECHOED state. + * It should stop any cookie timer that may be running and send + * a COOKIE ACK. */ - if (SCTP_STATE_ESTABLISHED != asoc->state) { + + /* Don't accidentally move back into established state. */ + if (asoc->state < SCTP_STATE_ESTABLISHED) { + sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, + SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE)); sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, SCTP_STATE(SCTP_STATE_ESTABLISHED)); sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, @@ -1528,13 +1540,14 @@ SCTP_ULPEVENT(ev)); } sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); - + repl = sctp_make_cookie_ack(new_asoc, chunk); if (!repl) goto nomem; - + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); + return SCTP_DISPOSITION_CONSUME; nomem: @@ -1605,8 +1618,6 @@ sctp_send_stale_cookie_err(ep, asoc, chunk, commands, err_chk_p); return sctp_sf_pdiscard(ep, asoc, type, arg, commands); - - break; case -SCTP_IERROR_BAD_SIG: default: return sctp_sf_pdiscard(ep, asoc, type, arg, commands); @@ -1629,7 +1640,7 @@ new_asoc); break; - case 'C': /* Collisioun case C. */ + case 'C': /* Collision case C. */ retval = sctp_sf_do_dupcook_c(ep, asoc, chunk, commands, new_asoc); break; @@ -1639,9 +1650,8 @@ new_asoc); break; - default: /* No such case, discard it. */ - printk(KERN_WARNING "%s:unknown case\n", __FUNCTION__); - retval = SCTP_DISPOSITION_DISCARD; + default: /* Discard packet for all others. */ + retval = sctp_sf_pdiscard(ep, asoc, type, arg, commands); break; }; @@ -1799,7 +1809,7 @@ sctp_cookie_preserve_param_t bht; sctp_errhdr_t *err; struct list_head *pos; - sctp_transport_t *t; + struct sctp_transport *t; sctp_chunk_t *reply; sctp_bind_addr_t *bp; int attempts; @@ -1848,9 +1858,11 @@ sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_INC, SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR)); - /* If we've sent any data bundled with COOKIE-ECHO we need to resend. */ + /* If we've sent any data bundled with COOKIE-ECHO we need to + * resend. + */ list_for_each(pos, &asoc->peer.transport_addr_list) { - t = list_entry(pos, sctp_transport_t, transports); + t = list_entry(pos, struct sctp_transport, transports); sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN, SCTP_TRANSPORT(t)); } @@ -2030,7 +2042,7 @@ SCTP_STATE(SCTP_STATE_SHUTDOWN_RECEIVED)); disposition = SCTP_DISPOSITION_CONSUME; - if (sctp_outqueue_is_empty(&asoc->outqueue)) { + if (sctp_outq_is_empty(&asoc->outqueue)) { disposition = sctp_sf_do_9_2_shutdown_ack(ep, asoc, type, arg, commands); } @@ -3229,10 +3241,6 @@ sctp_cmd_seq_t *commands) { sctp_chunk_t *repl; - sctp_bind_addr_t *bp; - sctp_scope_t scope; - int error; - int flags; /* The comment below says that we enter COOKIE-WAIT AFTER * sending the INIT, but that doesn't actually work in our @@ -3241,35 +3249,6 @@ sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, SCTP_STATE(SCTP_STATE_COOKIE_WAIT)); - /* Build up the bind address list for the association based on - * info from the local endpoint and the remote peer. - */ - bp = sctp_bind_addr_new(GFP_ATOMIC); - if (!bp) - goto nomem; - - /* Use scoping rules to determine the subset of addresses from - * the endpoint. - */ - scope = sctp_scope(&asoc->peer.active_path->ipaddr); - flags = (PF_INET6 == asoc->base.sk->family) ? SCTP_ADDR6_ALLOWED : 0; - if (asoc->peer.ipv4_address) - flags |= SCTP_ADDR4_PEERSUPP; - if (asoc->peer.ipv6_address) - flags |= SCTP_ADDR6_PEERSUPP; - error = sctp_bind_addr_copy(bp, &ep->base.bind_addr, scope, - GFP_ATOMIC, flags); - if (error) - goto nomem; - - /* FIXME: Either move address assignment out of this function - * or else move the association allocation/init into this function. - * The association structure is brand new before calling this - * function, so would not be a sideeffect if the allocation - * moved into this function. --jgrimm - */ - sctp_add_cmd_sf(commands, SCTP_CMD_SET_BIND_ADDR, (sctp_arg_t) bp); - /* RFC 2960 5.1 Normal Establishment of an Association * * A) "A" first sends an INIT chunk to "Z". In the INIT, "A" @@ -3278,7 +3257,7 @@ * 1 to 4294967295 (see 5.3.1 for Tag value selection). ... */ - repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0); + repl = sctp_make_init(asoc, &asoc->base.bind_addr, GFP_ATOMIC, 0); if (!repl) goto nomem; @@ -3297,9 +3276,6 @@ return SCTP_DISPOSITION_CONSUME; nomem: - if (bp) - sctp_bind_addr_free(bp); - return SCTP_DISPOSITION_NOMEM; } @@ -3429,7 +3405,7 @@ SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); disposition = SCTP_DISPOSITION_CONSUME; - if (sctp_outqueue_is_empty(&asoc->outqueue)) { + if (sctp_outq_is_empty(&asoc->outqueue)) { disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type, arg, commands); } @@ -3767,7 +3743,7 @@ void *arg, sctp_cmd_seq_t *commands) { - return sctp_sf_heartbeat(ep, asoc, type, (sctp_transport_t *)arg, + return sctp_sf_heartbeat(ep, asoc, type, (struct sctp_transport *)arg, commands); } @@ -3837,6 +3813,13 @@ sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, SCTP_STATE(SCTP_STATE_SHUTDOWN_SENT)); + /* sctp-implguide 2.10 Issues with Heartbeating and failover + * + * HEARTBEAT ... is discontinued after sending either SHUTDOWN + * or SHUTDOWN-ACK. + */ + sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL()); + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply)); return SCTP_DISPOSITION_CONSUME; @@ -3889,6 +3872,14 @@ /* Enter the SHUTDOWN-ACK-SENT state. */ sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, SCTP_STATE(SCTP_STATE_SHUTDOWN_ACK_SENT)); + + /* sctp-implguide 2.10 Issues with Heartbeating and failover + * + * HEARTBEAT ... is discontinued after sending either SHUTDOWN + * or SHUTDOWN-ACK. + */ + sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL()); + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply)); return SCTP_DISPOSITION_CONSUME; @@ -3933,7 +3924,7 @@ void *arg, sctp_cmd_seq_t *commands) { - sctp_transport_t *transport = arg; + struct sctp_transport *transport = arg; if (asoc->overall_error_count >= asoc->overall_error_threshold) { /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ @@ -4203,7 +4194,7 @@ sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); disposition = SCTP_DISPOSITION_CONSUME; - if (sctp_outqueue_is_empty(&asoc->outqueue)) { + if (sctp_outq_is_empty(&asoc->outqueue)) { disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type, arg, commands); } @@ -4333,7 +4324,7 @@ const sctp_chunk_t *chunk) { sctp_packet_t *packet; - sctp_transport_t *transport; + struct sctp_transport *transport; __u16 sport; __u16 dport; __u32 vtag; diff -Nru a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c --- a/net/sctp/sm_statetable.c Fri Feb 14 00:27:30 2003 +++ b/net/sctp/sm_statetable.c Fri Feb 14 00:27:30 2003 @@ -1,7 +1,7 @@ /* SCTP kernel reference Implementation * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001 International Business Machines, Corp. + * Copyright (c) 2001-2003 International Business Machines, Corp. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Nokia, Inc. * @@ -49,7 +49,7 @@ #include #include -sctp_sm_table_entry_t bug = { +static sctp_sm_table_entry_t bug = { .fn = sctp_sf_bug, .name = "sctp_sf_bug" }; @@ -206,7 +206,7 @@ /* SCTP_STATE_COOKIE_WAIT */ \ {.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \ /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ /* SCTP_STATE_ESTABLISHED */ \ {.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \ /* SCTP_STATE_SHUTDOWN_PENDING */ \ @@ -216,7 +216,7 @@ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ {.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ } /* TYPE_SCTP_HEARTBEAT_ACK */ #define TYPE_SCTP_ABORT { \ @@ -293,19 +293,19 @@ /* SCTP_STATE_CLOSED */ \ {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \ /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ /* SCTP_STATE_COOKIE_ECHOED */ \ {.fn = sctp_sf_cookie_echoed_err, .name = "sctp_sf_cookie_echoed_err"}, \ /* SCTP_STATE_ESTABLISHED */ \ {.fn = sctp_sf_operr_notify, .name = "sctp_sf_operr_notify"}, \ /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ + {.fn = sctp_sf_operr_notify, .name = "sctp_sf_operr_notify"}, \ /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ + {.fn = sctp_sf_operr_notify, .name = "sctp_sf_operr_notify"}, \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ } /* TYPE_SCTP_ERROR */ #define TYPE_SCTP_COOKIE_ECHO { \ @@ -504,26 +504,6 @@ {.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"}, }; /* chunk unknown */ -#define TYPE_SCTP_PRIMITIVE_INITIALIZE { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} /* TYPE_SCTP_PRIMITIVE_INITIALIZE */ #define TYPE_SCTP_PRIMITIVE_ASSOCIATE { \ /* SCTP_STATE_EMPTY */ \ @@ -619,90 +599,6 @@ {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \ } /* TYPE_SCTP_PRIMITIVE_SEND */ -#define TYPE_SCTP_PRIMITIVE_SETPRIMARY { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} /* TYPE_SCTP_PRIMITIVE_SETPRIMARY */ - -#define TYPE_SCTP_PRIMITIVE_RECEIVE { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} /* TYPE_SCTP_PRIMITIVE_RECEIVE */ - -#define TYPE_SCTP_PRIMITIVE_STATUS { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} /* TYPE_SCTP_PRIMITIVE_STATUS */ - -#define TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} /* TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT */ - #define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT { \ /* SCTP_STATE_EMPTY */ \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ @@ -731,152 +627,16 @@ .name = "sctp_sf_do_prm_requestheartbeat"}, \ } /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */ -#define TYPE_SCTP_PRIMITIVE_GETSRTTREPORT { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} /* TYPE_SCTP_PRIMITIVE_GETSRTTREPORT */ - -#define TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} /* TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD */ - -#define TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} /* TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS */ - -#define TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} /* TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT */ - -#define TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} /* TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED */ - -#define TYPE_SCTP_PRIMITIVE_DESTROY { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} /* TYPE_SCTP_PRIMITIVE_DESTROY */ /* The primary index for this table is the primitive type. * The secondary index for this table is the state. */ sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = { - TYPE_SCTP_PRIMITIVE_INITIALIZE, TYPE_SCTP_PRIMITIVE_ASSOCIATE, TYPE_SCTP_PRIMITIVE_SHUTDOWN, TYPE_SCTP_PRIMITIVE_ABORT, TYPE_SCTP_PRIMITIVE_SEND, - TYPE_SCTP_PRIMITIVE_SETPRIMARY, - TYPE_SCTP_PRIMITIVE_RECEIVE, - TYPE_SCTP_PRIMITIVE_STATUS, - TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT, TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT, - TYPE_SCTP_PRIMITIVE_GETSRTTREPORT, - TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD, - TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS, - TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT, - TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED, - TYPE_SCTP_PRIMITIVE_DESTROY, }; #define TYPE_SCTP_OTHER_NO_PENDING_TSN { \ @@ -902,30 +662,8 @@ {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ } -#define TYPE_SCTP_OTHER_ICMP_UNREACHFRAG { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} - sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_OTHER_NO_PENDING_TSN, - TYPE_SCTP_OTHER_ICMP_UNREACHFRAG, }; #define TYPE_SCTP_EVENT_TIMEOUT_NONE { \ @@ -1033,27 +771,6 @@ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ } -#define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} - #define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \ /* SCTP_STATE_EMPTY */ \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ @@ -1089,11 +806,11 @@ /* SCTP_STATE_SHUTDOWN_PENDING */ \ {.fn = sctp_sf_sendbeat_8_3, .name = "sctp_sf_sendbeat_8_3"}, \ /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ + {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ + {.fn = sctp_sf_sendbeat_8_3, .name = "sctp_sf_sendbeat_8_3"}, \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ + {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ } #define TYPE_SCTP_EVENT_TIMEOUT_SACK { \ @@ -1139,39 +856,16 @@ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ } -#define TYPE_SCTP_EVENT_TIMEOUT_PMTU_RAISE { \ - /* SCTP_STATE_EMPTY */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ - /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_COOKIE_ECHOED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_ESTABLISHED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_PENDING */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ - /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ -} - sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_EVENT_TIMEOUT_NONE, TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE, TYPE_SCTP_EVENT_TIMEOUT_T1_INIT, TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN, TYPE_SCTP_EVENT_TIMEOUT_T3_RTX, - TYPE_SCTP_EVENT_TIMEOUT_T4_RTO, TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD, TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT, TYPE_SCTP_EVENT_TIMEOUT_SACK, TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE, - TYPE_SCTP_EVENT_TIMEOUT_PMTU_RAISE, }; sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, sctp_state_t state) diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c --- a/net/sctp/socket.c Fri Feb 14 00:27:30 2003 +++ b/net/sctp/socket.c Fri Feb 14 00:27:30 2003 @@ -1,7 +1,7 @@ /* Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001-2002 International Business Machines, Corp. - * Copyright (c) 2001-2002 Intel Corp. + * Copyright (c) 2001-2003 International Business Machines, Corp. + * Copyright (c) 2001-2003 Intel Corp. * Copyright (c) 2001-2002 Nokia, Inc. * Copyright (c) 2001 La Monte H.P. Yarroll * @@ -47,6 +47,7 @@ * Daisy Chang * Sridhar Samudrala * Inaky Perez-Gonzalez + * Ardelle Fan * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -131,7 +132,7 @@ static long sctp_get_port_local(struct sock *, union sctp_addr *); /* Verify this is a valid sockaddr. */ -static struct sctp_af *sctp_sockaddr_af(struct sctp_opt *opt, +static struct sctp_af *sctp_sockaddr_af(struct sctp_opt *opt, union sctp_addr *addr, int len) { struct sctp_af *af; @@ -716,7 +717,7 @@ sctp_opt_t *sp; sctp_endpoint_t *ep; sctp_association_t *new_asoc=NULL, *asoc=NULL; - sctp_transport_t *transport; + struct sctp_transport *transport; sctp_chunk_t *chunk = NULL; union sctp_addr to; struct sockaddr *msg_name = NULL; @@ -729,6 +730,7 @@ sctp_scope_t scope; long timeo; __u16 sinfo_flags = 0; + struct sk_buff_head chunks; SCTP_DEBUG_PRINTK("sctp_sendmsg(sk: %p, msg: %p, msg_len: %d)\n", sk, msg, msg_len); @@ -754,8 +756,8 @@ */ if ((SCTP_SOCKET_UDP_HIGH_BANDWIDTH != sp->type) && msg->msg_name) { int msg_namelen = msg->msg_namelen; - - err = sctp_verify_addr(sk, (union sctp_addr *)msg->msg_name, + + err = sctp_verify_addr(sk, (union sctp_addr *)msg->msg_name, msg_namelen); if (err) return err; @@ -806,7 +808,7 @@ asoc = sctp_endpoint_lookup_assoc(ep, &to, &transport); if (!asoc) { /* If we could not find a matching association on the - * endpoint, make sure that there is no peeled-off + * endpoint, make sure that there is no peeled-off * association on another socket. */ if (sctp_endpoint_is_peeled_off(ep, &to)) { @@ -868,13 +870,6 @@ goto out_unlock; } } else { - /* Check against the defaults. */ - if (sinfo->sinfo_stream >= - sp->initmsg.sinit_num_ostreams) { - err = -EINVAL; - goto out_unlock; - } - /* Check against the requested. */ if (sinfo->sinfo_stream >= sinit->sinit_num_ostreams) { @@ -915,14 +910,8 @@ sinit->sinit_num_ostreams; } if (sinit->sinit_max_instreams) { - if (sinit->sinit_max_instreams <= - SCTP_MAX_STREAM) { - asoc->c.sinit_max_instreams = - sinit->sinit_max_instreams; - } else { - asoc->c.sinit_max_instreams = - SCTP_MAX_STREAM; - } + asoc->c.sinit_max_instreams = + sinit->sinit_max_instreams; } if (sinit->sinit_max_attempts) { asoc->max_init_attempts @@ -936,6 +925,15 @@ /* Prime the peer's transport structures. */ transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL); + if (!transport) { + err = -ENOMEM; + goto out_free; + } + err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL); + if (err < 0) { + err = -ENOMEM; + goto out_free; + } } /* ASSERT: we have a valid association at this point. */ @@ -949,19 +947,6 @@ goto out_free; } - /* FIXME: In the current implementation, a single chunk is created - * for the entire message initially, even if it has to be fragmented - * later. As the length field in the chunkhdr is used to set - * the chunk length, the maximum size of the chunk and hence the - * message is limited by its type(__u16). - * The real fix is to fragment the message before creating the chunks. - */ - if (msg_len > ((__u16)(~(__u16)0) - - WORD_ROUND(sizeof(sctp_data_chunk_t)+1))) { - err = -EMSGSIZE; - goto out_free; - } - /* If fragmentation is disabled and the message length exceeds the * association fragmentation point, return EMSGSIZE. The I-D * does not specify what this error is, but this looks like @@ -994,13 +979,6 @@ goto out_free; } - /* Get enough memory for the whole message. */ - chunk = sctp_make_data_empty(asoc, sinfo, msg_len); - if (!chunk) { - err = -ENOMEM; - goto out_free; - } - #if 0 /* FIXME: This looks wrong so I'll comment out. * We should be able to use this same technique for @@ -1016,20 +994,13 @@ } #endif /* 0 */ - /* Copy the message from the user. */ - err = sctp_user_addto_chunk(chunk, msg_len, msg->msg_iov); - if (err < 0) + /* Break the message into multiple chunks of maximum size. */ + skb_queue_head_init(&chunks); + err = sctp_datachunks_from_user(asoc, sinfo, msg, msg_len, &chunks); + if (err) goto out_free; - SCTP_DEBUG_PRINTK("Copied message to chunk: %p.\n", chunk); - - /* Put the chunk->skb back into the form expected by send. */ - __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr - - (__u8 *)chunk->skb->data); - - /* Do accounting for the write space. */ - sctp_set_owner_w(chunk); - + /* Auto-connect, if we aren't connected already. */ if (SCTP_STATE_CLOSED == asoc->state) { err = sctp_primitive_ASSOCIATE(asoc, NULL); if (err < 0) @@ -1037,18 +1008,22 @@ SCTP_DEBUG_PRINTK("We associated primitively.\n"); } - /* Send it to the lower layers. */ - err = sctp_primitive_SEND(asoc, chunk); + /* Now send the (possibly) fragmented message. */ + while ((chunk = (sctp_chunk_t *)__skb_dequeue(&chunks))) { - SCTP_DEBUG_PRINTK("We sent primitively.\n"); + /* Do accounting for the write space. */ + sctp_set_owner_w(chunk); + /* Send it to the lower layers. */ + sctp_primitive_SEND(asoc, chunk); + SCTP_DEBUG_PRINTK("We sent primitively.\n"); + } - /* BUG: SCTP_CHECK_TIMER(sk); */ if (!err) { err = msg_len; goto out_unlock; } /* If we are already past ASSOCIATE, the lower - * layers are responsible for its cleanup. + * layers are responsible for association cleanup. */ goto out_free_chunk; @@ -1086,23 +1061,30 @@ * frag_list. len specifies the total amount of data that needs to be removed. * when 'len' bytes could be removed from the skb, it returns 0. * If 'len' exceeds the total skb length, it returns the no. of bytes that - * could not be removed. - */ + * could not be removed. + */ static int sctp_skb_pull(struct sk_buff *skb, int len) { struct sk_buff *list; + int skb_len = skb_headlen(skb); + int rlen; - if (len <= skb->len) { + if (len <= skb_len) { __skb_pull(skb, len); return 0; } - len -= skb->len; - __skb_pull(skb, skb->len); + len -= skb_len; + __skb_pull(skb, skb_len); for (list = skb_shinfo(skb)->frag_list; list; list = list->next) { - len = sctp_skb_pull(list, len); - if (!len) + rlen = sctp_skb_pull(list, len); + skb->len -= (len-rlen); + skb->data_len -= (len-rlen); + + if (!rlen) return 0; + + len = rlen; } return len; @@ -1130,7 +1112,7 @@ { sctp_ulpevent_t *event = NULL; sctp_opt_t *sp = sctp_sk(sk); - struct sk_buff *skb, *list; + struct sk_buff *skb; int copied; int err = 0; int skb_len; @@ -1152,10 +1134,8 @@ /* Get the total length of the skb including any skb's in the * frag_list. - */ + */ skb_len = skb->len; - for (list = skb_shinfo(skb)->frag_list; list; list = list->next) - skb_len += list->len; copied = skb_len; if (copied > len) @@ -1190,14 +1170,20 @@ /* If skb's length exceeds the user's buffer, update the skb and * push it back to the receive_queue so that the next call to * recvmsg() will return the remaining data. Don't set MSG_EOR. - * Otherwise, set MSG_EOR indicating the end of a message. + * Otherwise, set MSG_EOR indicating the end of a message. */ if (skb_len > copied) { msg->msg_flags &= ~MSG_EOR; if (flags & MSG_PEEK) - goto out_free; + goto out_free; sctp_skb_pull(skb, copied); skb_queue_head(&sk->receive_queue, skb); + /* When only partial message is copied to the user, increase + * rwnd by that amount. If all the data in the skb is read, + * rwnd is updated when the skb's destructor is called via + * sctp_ulpevent_free(). + */ + sctp_assoc_rwnd_increase(event->asoc, copied); goto out; } else { msg->msg_flags |= MSG_EOR; @@ -1260,7 +1246,7 @@ struct sctp_paddrparams params; sctp_association_t *asoc; union sctp_addr *addr; - sctp_transport_t *trans; + struct sctp_transport *trans; int error; if (optlen != sizeof(struct sctp_paddrparams)) @@ -1449,7 +1435,7 @@ sctp_opt_t *sp; sctp_endpoint_t *ep; sctp_association_t *asoc; - sctp_transport_t *transport; + struct sctp_transport *transport; union sctp_addr to; sctp_scope_t scope; long timeo; @@ -1463,7 +1449,7 @@ sp = sctp_sk(sk); ep = sp->ep; - /* connect() cannot be done on a peeled-off socket. */ + /* connect() cannot be done on a peeled-off socket. */ if (SCTP_SOCKET_UDP_HIGH_BANDWIDTH == sp->type) { err = -EISCONN; goto out_unlock; @@ -1471,7 +1457,7 @@ err = sctp_verify_addr(sk, (union sctp_addr *)uaddr, addr_len); if (err) - goto out_unlock; + goto out_unlock; memcpy(&to, uaddr, addr_len); to.v4.sin_port = ntohs(to.v4.sin_port); @@ -1479,7 +1465,7 @@ asoc = sctp_endpoint_lookup_assoc(ep, &to, &transport); if (asoc) { if (asoc->state >= SCTP_STATE_ESTABLISHED) - err = -EISCONN; + err = -EISCONN; else err = -EALREADY; goto out_unlock; @@ -1514,10 +1500,19 @@ /* Prime the peer's transport structures. */ transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL); + if (!transport) { + sctp_association_free(asoc); + goto out_unlock; + } + err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL); + if (err < 0) { + sctp_association_free(asoc); + goto out_unlock; + } err = sctp_primitive_ASSOCIATE(asoc, NULL); if (err < 0) { - sctp_association_free(asoc); + sctp_association_free(asoc); goto out_unlock; } @@ -1666,7 +1661,7 @@ struct sctp_status status; sctp_endpoint_t *ep; sctp_association_t *assoc = NULL; - sctp_transport_t *transport; + struct sctp_transport *transport; sctp_assoc_t associd; int retval = 0; @@ -1885,7 +1880,7 @@ struct sctp_paddrparams params; sctp_association_t *asoc; union sctp_addr *addr; - sctp_transport_t *trans; + struct sctp_transport *trans; if (len != sizeof(struct sctp_paddrparams)) return -EINVAL; @@ -1915,7 +1910,7 @@ * before this address shall be considered unreachable. */ params.spp_pathmaxrxt = trans->error_threshold; - + if (copy_to_user(optval, ¶ms, len)) return -EFAULT; *optlen = len; @@ -1932,6 +1927,166 @@ return 0; } +static inline int sctp_getsockopt_get_peer_addrs_num(struct sock *sk, int len, + char *optval, int *optlen) +{ + sctp_assoc_t id; + sctp_association_t *asoc; + struct list_head *pos; + int cnt = 0; + + if (len != sizeof(sctp_assoc_t)) + return -EINVAL; + + if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) + return -EFAULT; + + /* + * For UDP-style sockets, id specifies the association to query. + */ + asoc = sctp_id2assoc(sk, id); + if (!asoc) + return -EINVAL; + + list_for_each(pos, &asoc->peer.transport_addr_list) { + cnt ++; + } + if (copy_to_user(optval, &cnt, sizeof(int))) + return -EFAULT; + + return 0; +} + +static inline int sctp_getsockopt_get_peer_addrs(struct sock *sk, int len, + char *optval, int *optlen) +{ + sctp_association_t *asoc; + struct list_head *pos; + int cnt = 0; + struct sctp_getaddrs getaddrs; + struct sctp_transport *from; + struct sockaddr_storage *to; + + if (len != sizeof(struct sctp_getaddrs)) + return -EINVAL; + + if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs))) + return -EFAULT; + + if (getaddrs.addr_num <= 0) return -EINVAL; + /* + * For UDP-style sockets, id specifies the association to query. + */ + asoc = sctp_id2assoc(sk, getaddrs.assoc_id); + if (!asoc) + return -EINVAL; + + to = getaddrs.addrs; + list_for_each(pos, &asoc->peer.transport_addr_list) { + from = list_entry(pos, struct sctp_transport, transports); + if (copy_to_user(to, &from->ipaddr, sizeof(from->ipaddr))) + return -EFAULT; + to ++; + cnt ++; + if (cnt >= getaddrs.addr_num) break; + } + getaddrs.addr_num = cnt; + if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs))) + return -EFAULT; + + return 0; +} + +static inline int sctp_getsockopt_get_local_addrs_num(struct sock *sk, int len, + char *optval, int *optlen) +{ + sctp_assoc_t id; + sctp_bind_addr_t *bp; + sctp_association_t *asoc; + struct list_head *pos; + int cnt = 0; + + if (len != sizeof(sctp_assoc_t)) + return -EINVAL; + + if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) + return -EFAULT; + + /* + * For UDP-style sockets, id specifies the association to query. + * If the id field is set to the value '0' then the locally bound + * addresses are returned without regard to any particular + * association. + */ + if (0 == id) { + bp = &sctp_sk(sk)->ep->base.bind_addr; + } else { + asoc = sctp_id2assoc(sk, id); + if (!asoc) + return -EINVAL; + bp = &asoc->base.bind_addr; + } + + list_for_each(pos, &bp->address_list) { + cnt ++; + } + if (copy_to_user(optval, &cnt, sizeof(int))) + return -EFAULT; + + return 0; +} + +static inline int sctp_getsockopt_get_local_addrs(struct sock *sk, int len, + char *optval, int *optlen) +{ + sctp_bind_addr_t *bp; + sctp_association_t *asoc; + struct list_head *pos; + int cnt = 0; + struct sctp_getaddrs getaddrs; + struct sockaddr_storage_list *from; + struct sockaddr_storage *to; + + if (len != sizeof(struct sctp_getaddrs)) + return -EINVAL; + + if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs))) + return -EFAULT; + + if (getaddrs.addr_num <= 0) return -EINVAL; + /* + * For UDP-style sockets, id specifies the association to query. + * If the id field is set to the value '0' then the locally bound + * addresses are returned without regard to any particular + * association. + */ + if (0 == getaddrs.assoc_id) { + bp = &sctp_sk(sk)->ep->base.bind_addr; + } else { + asoc = sctp_id2assoc(sk, getaddrs.assoc_id); + if (!asoc) + return -EINVAL; + bp = &asoc->base.bind_addr; + } + + to = getaddrs.addrs; + list_for_each(pos, &bp->address_list) { + from = list_entry(pos, + struct sockaddr_storage_list, + list); + if (copy_to_user(to, &from->a, sizeof(from->a))) + return -EFAULT; + to ++; + cnt ++; + if (cnt >= getaddrs.addr_num) break; + } + getaddrs.addr_num = cnt; + if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs))) + return -EFAULT; + + return 0; +} + SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen) { @@ -1989,6 +2144,26 @@ retval = sctp_getsockopt_initmsg(sk, len, optval, optlen); break; + case SCTP_GET_PEER_ADDRS_NUM: + retval = sctp_getsockopt_get_peer_addrs_num(sk, len, optval, + optlen); + break; + + case SCTP_GET_LOCAL_ADDRS_NUM: + retval = sctp_getsockopt_get_local_addrs_num(sk, len, optval, + optlen); + break; + + case SCTP_GET_PEER_ADDRS: + retval = sctp_getsockopt_get_peer_addrs(sk, len, optval, + optlen); + break; + + case SCTP_GET_LOCAL_ADDRS: + retval = sctp_getsockopt_get_local_addrs(sk, len, optval, + optlen); + break; + default: retval = -ENOPROTOOPT; break; @@ -2029,7 +2204,7 @@ sctp_protocol_t *sctp = sctp_get_protocol(); unsigned short snum; int ret; - + /* NOTE: Remember to put this back to net order. */ addr->v4.sin_port = ntohs(addr->v4.sin_port); snum = addr->v4.sin_port; @@ -2098,7 +2273,7 @@ } } - + if (pp != NULL && pp->sk != NULL) { /* We had a port hash table hit - there is an * available port (pp != NULL) and it is being @@ -2129,7 +2304,7 @@ if (sk_reuse && sk2->reuse) continue; - + if (sctp_bind_addr_match(&ep2->base.bind_addr, addr, sctp_sk(sk))) goto found; @@ -2187,7 +2362,7 @@ } /* Assign a 'snum' port to the socket. If snum == 0, an ephemeral - * port is requested. + * port is requested. */ static int sctp_get_port(struct sock *sk, unsigned short snum) { @@ -2657,10 +2832,10 @@ return -EINVAL; /* Is this a valid SCTP address? */ - if (!af->addr_valid((union sctp_addr *)addr)) + if (!af->addr_valid((union sctp_addr *)addr)) return -EINVAL; - return 0; + return 0; } /* Get the sndbuf space available at the time on the association. */ diff -Nru a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/sctp/ssnmap.c Fri Feb 14 00:27:30 2003 @@ -0,0 +1,113 @@ +/* SCTP kernel reference Implementation + * Copyright (c) 2003 International Business Machines, Corp. + * + * This file is part of the SCTP kernel reference Implementation + * + * These functions manipulate sctp SSN tracker. + * + * The SCTP reference implementation is free software; + * you can redistribute it and/or modify it under the terms of + * the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * The SCTP reference implementation is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * ************************ + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU CC; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Please send any bug reports or fixes you make to the + * email address(es): + * lksctp developers + * + * Or submit a bug report through the following website: + * http://www.sf.net/projects/lksctp + * + * Written or modified by: + * Jon Grimm + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorporated into the next SCTP release. + */ + +#include +#include +#include + + +/* Storage size needed for map includes 2 headers and then the + * specific needs of in or out streams. + */ +static inline size_t sctp_ssnmap_size(__u16 in, __u16 out) +{ + return sizeof(struct sctp_ssnmap) + (in + out) * sizeof(__u16); +} + + +/* Create a new sctp_ssnmap. + * Allocate room to store at least 'len' contiguous TSNs. + */ +struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int priority) +{ + struct sctp_ssnmap *retval; + + retval = kmalloc(sctp_ssnmap_size(in, out), priority); + + if (!retval) + goto fail; + + if (!sctp_ssnmap_init(retval, in, out)) + goto fail_map; + + retval->malloced = 1; + SCTP_DBG_OBJCNT_INC(ssnmap); + + return retval; + +fail_map: + kfree(retval); +fail: + return NULL; +} + + +/* Initialize a block of memory as a ssnmap. */ +struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in, + __u16 out) +{ + memset(map, 0x00, sctp_ssnmap_size(in, out)); + + /* Start 'in' stream just after the map header. */ + map->in.ssn = (__u16 *)&map[1]; + map->in.len = in; + + /* Start 'out' stream just after 'in'. */ + map->out.ssn = &map->in.ssn[in]; + map->out.len = out; + + return map; +} + +/* Clear out the ssnmap streams. */ +void sctp_ssnmap_clear(struct sctp_ssnmap *map) +{ + size_t size; + + size = (map->in.len + map->out.len) * sizeof(__u16); + memset(map->in.ssn, 0x00, size); +} + +/* Dispose of a ssnmap. */ +void sctp_ssnmap_free(struct sctp_ssnmap *map) +{ + if (map && map->malloced) { + kfree(map); + SCTP_DBG_OBJCNT_DEC(ssnmap); + } +} diff -Nru a/net/sctp/sysctl.c b/net/sctp/sysctl.c --- a/net/sctp/sysctl.c Fri Feb 14 00:27:27 2003 +++ b/net/sctp/sysctl.c Fri Feb 14 00:27:27 2003 @@ -45,53 +45,131 @@ extern sctp_protocol_t sctp_proto; static ctl_table sctp_table[] = { - { NET_SCTP_RTO_INITIAL, "rto_initial", - &sctp_proto.rto_initial, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies }, - { NET_SCTP_RTO_MIN, "rto_min", - &sctp_proto.rto_min, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies }, - { NET_SCTP_RTO_MAX, "rto_max", - &sctp_proto.rto_max, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies }, - { NET_SCTP_VALID_COOKIE_LIFE, "valid_cookie_life", - &sctp_proto.valid_cookie_life, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies }, - { NET_SCTP_MAX_BURST, "max_burst", - &sctp_proto.max_burst, sizeof(int), 0644, NULL, - &proc_dointvec }, - { NET_SCTP_ASSOCIATION_MAX_RETRANS, "association_max_retrans", - &sctp_proto.max_retrans_association, sizeof(int), 0644, NULL, - &proc_dointvec }, - { NET_SCTP_PATH_MAX_RETRANS, "path_max_retrans", - &sctp_proto.max_retrans_path, sizeof(int), 0644, NULL, - &proc_dointvec }, - { NET_SCTP_MAX_INIT_RETRANSMITS, "max_init_retransmits", - &sctp_proto.max_retrans_init, sizeof(int), 0644, NULL, - &proc_dointvec }, - { NET_SCTP_HB_INTERVAL, "hb_interval", - &sctp_proto.hb_interval, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies }, - { NET_SCTP_PRESERVE_ENABLE, "cookie_preserve_enable", - &sctp_proto.cookie_preserve_enable, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies }, - { NET_SCTP_RTO_ALPHA, "rto_alpha_exp_divisor", - &sctp_proto.rto_alpha, sizeof(int), 0644, NULL, - &proc_dointvec }, - { NET_SCTP_RTO_BETA, "rto_beta_exp_divisor", - &sctp_proto.rto_beta, sizeof(int), 0644, NULL, - &proc_dointvec }, - { 0 } + { + .ctl_name = NET_SCTP_RTO_INITIAL, + .procname = "rto_initial", + .data = &sctp_proto.rto_initial, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_SCTP_RTO_MIN, + .procname = "rto_min", + .data = &sctp_proto.rto_min, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_SCTP_RTO_MAX, + .procname = "rto_max", + .data = &sctp_proto.rto_max, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_SCTP_VALID_COOKIE_LIFE, + .procname = "valid_cookie_life", + .data = &sctp_proto.valid_cookie_life, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_SCTP_MAX_BURST, + .procname = "max_burst", + .data = &sctp_proto.max_burst, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_SCTP_ASSOCIATION_MAX_RETRANS, + .procname = "association_max_retrans", + .data = &sctp_proto.max_retrans_association, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_SCTP_PATH_MAX_RETRANS, + .procname = "path_max_retrans", + .data = &sctp_proto.max_retrans_path, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_SCTP_MAX_INIT_RETRANSMITS, + .procname = "max_init_retransmits", + .data = &sctp_proto.max_retrans_init, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_SCTP_HB_INTERVAL, + .procname = "hb_interval", + .data = &sctp_proto.hb_interval, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_SCTP_PRESERVE_ENABLE, + .procname = "cookie_preserve_enable", + .data = &sctp_proto.cookie_preserve_enable, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_SCTP_RTO_ALPHA, + .procname = "rto_alpha_exp_divisor", + .data = &sctp_proto.rto_alpha, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_SCTP_RTO_BETA, + .procname = "rto_beta_exp_divisor", + .data = &sctp_proto.rto_beta, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { .ctl_name = 0 } }; static ctl_table sctp_net_table[] = { - { NET_SCTP, "sctp", NULL, 0, 0555, sctp_table }, - { 0 } + { + .ctl_name = NET_SCTP, + .procname = "sctp", + .maxlen = 0, + .mode = 0555, + .child = sctp_table + }, + { .ctl_name = 0 } }; static ctl_table sctp_root_table[] = { - { CTL_NET, "net", NULL, 0, 0555, sctp_net_table }, - { 0 } + { + .ctl_name = CTL_NET, + .procname = "net", + .maxlen = 0, + .mode = 0555, + .child = sctp_net_table + }, + { .ctl_name = 0 } }; static struct ctl_table_header * sctp_sysctl_header; diff -Nru a/net/sctp/transport.c b/net/sctp/transport.c --- a/net/sctp/transport.c Fri Feb 14 00:27:27 2003 +++ b/net/sctp/transport.c Fri Feb 14 00:27:27 2003 @@ -1,7 +1,7 @@ /* SCTP kernel reference Implementation * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001 International Business Machines Corp. + * Copyright (c) 2001-2003 International Business Machines Corp. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 La Monte H.P. Yarroll * @@ -42,6 +42,7 @@ * Xingang Guo * Hui Huang * Sridhar Samudrala + * Ardelle Fan * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -53,11 +54,12 @@ /* 1st Level Abstractions. */ /* Allocate and initialize a new transport. */ -sctp_transport_t *sctp_transport_new(const union sctp_addr *addr, int priority) +struct sctp_transport *sctp_transport_new(const union sctp_addr *addr, + int priority) { - sctp_transport_t *transport; + struct sctp_transport *transport; - transport = t_new(sctp_transport_t, priority); + transport = t_new(struct sctp_transport, priority); if (!transport) goto fail; @@ -77,9 +79,9 @@ } /* Intialize a new transport from provided memory. */ -sctp_transport_t *sctp_transport_init(sctp_transport_t *peer, - const union sctp_addr *addr, - int priority) +struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, + const union sctp_addr *addr, + int priority) { sctp_protocol_t *proto = sctp_get_protocol(); @@ -88,6 +90,9 @@ peer->af_specific = sctp_get_af_specific(addr->sa.sa_family); peer->asoc = NULL; + peer->dst = NULL; + memset(&peer->saddr, 0, sizeof(union sctp_addr)); + /* From 6.3.1 RTO Calculation: * * C1) Until an RTT measurement has been made for a packet sent to the @@ -139,7 +144,7 @@ /* This transport is no longer needed. Free up if possible, or * delay until it last reference count. */ -void sctp_transport_free(sctp_transport_t *transport) +void sctp_transport_free(struct sctp_transport *transport) { transport->dead = 1; @@ -153,7 +158,7 @@ /* Destroy the transport data structure. * Assumes there are no more users of this structure. */ -void sctp_transport_destroy(sctp_transport_t *transport) +void sctp_transport_destroy(struct sctp_transport *transport) { SCTP_ASSERT(transport->dead, "Transport is not dead", return); @@ -168,7 +173,7 @@ /* Start T3_rtx timer if it is not already running and update the heartbeat * timer. This routine is called everytime a DATA chunk is sent. */ -void sctp_transport_reset_timers(sctp_transport_t *transport) +void sctp_transport_reset_timers(struct sctp_transport *transport) { /* RFC 2960 6.3.2 Retransmission Timer Rules * @@ -177,96 +182,61 @@ * start it running so that it will expire after the RTO of that * address. */ - if (!timer_pending(&transport->T3_rtx_timer)) { + + if (!timer_pending(&transport->T3_rtx_timer)) if (!mod_timer(&transport->T3_rtx_timer, jiffies + transport->rto)) sctp_transport_hold(transport); - } /* When a data chunk is sent, reset the heartbeat interval. */ if (!mod_timer(&transport->hb_timer, - transport->hb_interval + transport->rto + jiffies)) - sctp_transport_hold(transport); + sctp_transport_timeout(transport))) + sctp_transport_hold(transport); } /* This transport has been assigned to an association. * Initialize fields from the association or from the sock itself. * Register the reference count in the association. */ -void sctp_transport_set_owner(sctp_transport_t *transport, +void sctp_transport_set_owner(struct sctp_transport *transport, sctp_association_t *asoc) { transport->asoc = asoc; sctp_association_hold(asoc); } -/* Caches the dst entry for a transport's destination address and an optional - * souce address. - */ -void sctp_transport_route(sctp_transport_t *transport, union sctp_addr *saddr, - struct sctp_opt *opt) +/* Initialize the pmtu of a transport. */ +void sctp_transport_pmtu(struct sctp_transport *transport) { - sctp_association_t *asoc = transport->asoc; - struct sctp_af *af = transport->af_specific; - union sctp_addr *daddr = &transport->ipaddr; - sctp_bind_addr_t *bp; - rwlock_t *addr_lock; - struct sockaddr_storage_list *laddr; - struct list_head *pos; struct dst_entry *dst; - union sctp_addr dst_saddr; - - dst = af->get_dst(daddr, saddr); - - /* If there is no association or if a source address is passed, - * no more validation is required. - */ - if (!asoc || saddr) - goto out; - if (SCTP_STATE_ESTABLISHED == asoc->state) { - bp = &asoc->base.bind_addr; - addr_lock = &asoc->base.addr_lock; - } else { - bp = &asoc->ep->base.bind_addr; - addr_lock = &asoc->ep->base.addr_lock; - } + dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL); if (dst) { - /* Walk through the bind address list and look for a bind - * address that matches the source address of the returned dst. - */ - sctp_read_lock(addr_lock); - list_for_each(pos, &bp->address_list) { - laddr = list_entry(pos, struct sockaddr_storage_list, - list); - af->dst_saddr(&dst_saddr, dst); - if (opt->pf->cmp_addr(&dst_saddr, &laddr->a, opt)) - goto out_unlock; - } - sctp_read_unlock(addr_lock); - - /* None of the bound addresses match the source address of the - * dst. So release it. - */ + transport->pmtu = dst_pmtu(dst); dst_release(dst); - } + } else + transport->pmtu = SCTP_DEFAULT_MAXSEGMENT; +} - /* Walk through the bind address list and try to get a dst that - * matches a bind address as the source address. - */ - sctp_read_lock(addr_lock); - list_for_each(pos, &bp->address_list) { - laddr = list_entry(pos, struct sockaddr_storage_list, list); - - dst = af->get_dst(daddr, &laddr->a); - if (dst) - goto out_unlock; - } +/* Caches the dst entry and source address for a transport's destination + * address. + */ +void sctp_transport_route(struct sctp_transport *transport, + union sctp_addr *saddr, struct sctp_opt *opt) +{ + sctp_association_t *asoc = transport->asoc; + struct sctp_af *af = transport->af_specific; + union sctp_addr *daddr = &transport->ipaddr; + struct dst_entry *dst; + + dst = af->get_dst(asoc, daddr, saddr); + + if (saddr) + memcpy(&transport->saddr, saddr, sizeof(union sctp_addr)); + else + af->get_saddr(asoc, dst, daddr, &transport->saddr); -out_unlock: - sctp_read_unlock(addr_lock); -out: transport->dst = dst; if (dst) transport->pmtu = dst_pmtu(dst); @@ -275,7 +245,7 @@ } /* Hold a reference to a transport. */ -void sctp_transport_hold(sctp_transport_t *transport) +void sctp_transport_hold(struct sctp_transport *transport) { atomic_inc(&transport->refcnt); } @@ -283,14 +253,14 @@ /* Release a reference to a transport and clean up * if there are no more references. */ -void sctp_transport_put(sctp_transport_t *transport) +void sctp_transport_put(struct sctp_transport *transport) { if (atomic_dec_and_test(&transport->refcnt)) sctp_transport_destroy(transport); } /* Update transport's RTO based on the newly calculated RTT. */ -void sctp_transport_update_rto(sctp_transport_t *tp, __u32 rtt) +void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) { sctp_protocol_t *proto = sctp_get_protocol(); @@ -330,7 +300,7 @@ if (tp->rttvar == 0) tp->rttvar = SCTP_CLOCK_GRANULARITY; - /* 6.3.1 C3) After the computation, update RTO <- SRTT + 4 * RTTVAR. */ + /* 6.3.1 C3) After the computation, update RTO <- SRTT + 4 * RTTVAR. */ tp->rto = tp->srtt + (tp->rttvar << 2); /* 6.3.1 C6) Whenever RTO is computed, if it is less than RTO.Min @@ -360,8 +330,8 @@ /* This routine updates the transport's cwnd and partial_bytes_acked * parameters based on the bytes acked in the received SACK. */ -void sctp_transport_raise_cwnd(sctp_transport_t *transport, __u32 sack_ctsn, - __u32 bytes_acked) +void sctp_transport_raise_cwnd(struct sctp_transport *transport, + __u32 sack_ctsn, __u32 bytes_acked) { __u32 cwnd, ssthresh, flight_size, pba, pmtu; @@ -389,8 +359,8 @@ * two conditions are met can the cwnd be increased otherwise * the cwnd MUST not be increased. If these conditions are met * then cwnd MUST be increased by at most the lesser of - * 1) the total size of the previously outstanding DATA chunk(s) - * acknowledged, and 2) the destination's path MTU. + * 1) the total size of the previously outstanding DATA + * chunk(s) acknowledged, and 2) the destination's path MTU. */ if (bytes_acked > pmtu) cwnd += pmtu; @@ -403,18 +373,18 @@ transport, bytes_acked, cwnd, ssthresh, flight_size, pba); } else { - /* RFC 2960 7.2.2 Whenever cwnd is greater than ssthresh, upon - * each SACK arrival that advances the Cumulative TSN Ack Point, - * increase partial_bytes_acked by the total number of bytes of - * all new chunks acknowledged in that SACK including chunks - * acknowledged by the new Cumulative TSN Ack and by Gap Ack - * Blocks. + /* RFC 2960 7.2.2 Whenever cwnd is greater than ssthresh, + * upon each SACK arrival that advances the Cumulative TSN Ack + * Point, increase partial_bytes_acked by the total number of + * bytes of all new chunks acknowledged in that SACK including + * chunks acknowledged by the new Cumulative TSN Ack and by + * Gap Ack Blocks. * - * When partial_bytes_acked is equal to or greater than cwnd and - * before the arrival of the SACK the sender had cwnd or more - * bytes of data outstanding (i.e., before arrival of the SACK, - * flightsize was greater than or equal to cwnd), increase cwnd - * by MTU, and reset partial_bytes_acked to + * When partial_bytes_acked is equal to or greater than cwnd + * and before the arrival of the SACK the sender had cwnd or + * more bytes of data outstanding (i.e., before arrival of the + * SACK, flightsize was greater than or equal to cwnd), + * increase cwnd by MTU, and reset partial_bytes_acked to * (partial_bytes_acked - cwnd). */ pba += bytes_acked; @@ -437,7 +407,7 @@ /* This routine is used to lower the transport's cwnd when congestion is * detected. */ -void sctp_transport_lower_cwnd(sctp_transport_t *transport, +void sctp_transport_lower_cwnd(struct sctp_transport *transport, sctp_lower_cwnd_t reason) { switch (reason) { @@ -513,4 +483,13 @@ "%d ssthresh: %d\n", __FUNCTION__, transport, reason, transport->cwnd, transport->ssthresh); +} + +/* What is the next timeout value for this transport? */ +unsigned long sctp_transport_timeout(struct sctp_transport *t) +{ + unsigned long timeout; + timeout = t->hb_interval + t->rto + sctp_jitter(t->rto); + timeout += jiffies; + return timeout; } diff -Nru a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c --- a/net/sctp/ulpevent.c Fri Feb 14 00:27:27 2003 +++ b/net/sctp/ulpevent.c Fri Feb 14 00:27:27 2003 @@ -606,9 +606,9 @@ sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc, sctp_chunk_t *chunk, int priority) { - sctp_ulpevent_t *event; + sctp_ulpevent_t *event, *levent; struct sctp_sndrcvinfo *info; - struct sk_buff *skb; + struct sk_buff *skb, *list; size_t padding, len; /* Clone the original skb, sharing the data. */ @@ -647,6 +647,16 @@ event->malloced = 1; + for (list = skb_shinfo(skb)->frag_list; list; list = list->next) { + sctp_ulpevent_set_owner_r(list, asoc); + /* Initialize event with flags 0. */ + levent = sctp_ulpevent_init(event, skb, 0); + if (!levent) + goto fail_init; + + levent->malloced = 1; + } + info = (struct sctp_sndrcvinfo *) &event->sndrcvinfo; /* Sockets API Extensions for SCTP @@ -762,8 +772,6 @@ { sctp_association_t *asoc; sctp_ulpevent_t *event; - sctp_chunk_t *sack; - struct timer_list *timer; /* Current stack structures assume that the rcv buffer is * per socket. For UDP style sockets this is not true as @@ -773,50 +781,7 @@ */ event = (sctp_ulpevent_t *) skb->cb; asoc = event->asoc; - if (asoc->rwnd_over) { - if (asoc->rwnd_over >= skb->len) { - asoc->rwnd_over -= skb->len; - } else { - asoc->rwnd += (skb->len - asoc->rwnd_over); - asoc->rwnd_over = 0; - } - } else { - asoc->rwnd += skb->len; - } - - SCTP_DEBUG_PRINTK("rwnd increased by %d to (%u, %u) - %u\n", - skb->len, asoc->rwnd, asoc->rwnd_over, asoc->a_rwnd); - - /* Send a window update SACK if the rwnd has increased by at least the - * minimum of the association's PMTU and half of the receive buffer. - * The algorithm used is similar to the one described in Section 4.2.3.3 - * of RFC 1122. - */ - if ((asoc->state == SCTP_STATE_ESTABLISHED) && - (asoc->rwnd > asoc->a_rwnd) && - ((asoc->rwnd - asoc->a_rwnd) >= - min_t(__u32, (asoc->base.sk->rcvbuf >> 1), asoc->pmtu))) { - SCTP_DEBUG_PRINTK("Sending window update SACK- rwnd: %u " - "a_rwnd: %u\n", asoc->rwnd, asoc->a_rwnd); - sack = sctp_make_sack(asoc); - if (!sack) - goto out; - - /* Update the last advertised rwnd value. */ - asoc->a_rwnd = asoc->rwnd; - - asoc->peer.sack_needed = 0; - asoc->peer.next_dup_tsn = 0; - - sctp_push_outqueue(&asoc->outqueue, sack); - - /* Stop the SACK timer. */ - timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK]; - if (timer_pending(timer) && del_timer(timer)) - sctp_association_put(asoc); - } - -out: + sctp_assoc_rwnd_increase(asoc, skb_headlen(skb)); sctp_association_put(asoc); } @@ -838,16 +803,7 @@ skb->destructor = sctp_rcvmsg_rfree; - SCTP_ASSERT(asoc->rwnd, "rwnd zero", return); - SCTP_ASSERT(!asoc->rwnd_over, "rwnd_over not zero", return); - if (asoc->rwnd >= skb->len) { - asoc->rwnd -= skb->len; - } else { - asoc->rwnd_over = skb->len - asoc->rwnd; - asoc->rwnd = 0; - } - SCTP_DEBUG_PRINTK("rwnd decreased by %d to (%u, %u)\n", - skb->len, asoc->rwnd, asoc->rwnd_over); + sctp_assoc_rwnd_decrease(asoc, skb_headlen(skb)); } /* A simple destructor to give up the reference to the association. */ diff -Nru a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c --- a/net/sctp/ulpqueue.c Fri Feb 14 00:27:30 2003 +++ b/net/sctp/ulpqueue.c Fri Feb 14 00:27:30 2003 @@ -1,7 +1,7 @@ /* SCTP kernel reference Implementation * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001-2002 International Business Machines, Corp. + * Copyright (c) 2001-2003 International Business Machines, Corp. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 La Monte H.P. Yarroll @@ -49,51 +49,39 @@ #include /* Forward declarations for internal helpers. */ -static inline sctp_ulpevent_t * sctp_ulpqueue_reasm(sctp_ulpqueue_t *ulpq, - sctp_ulpevent_t *event); -static inline sctp_ulpevent_t *sctp_ulpqueue_order(sctp_ulpqueue_t *ulpq, - sctp_ulpevent_t *event); +static inline struct sctp_ulpevent * sctp_ulpq_reasm(struct sctp_ulpq *ulpq, + struct sctp_ulpevent *); +static inline struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *, + struct sctp_ulpevent *); /* 1st Level Abstractions */ /* Create a new ULP queue. */ -sctp_ulpqueue_t *sctp_ulpqueue_new(sctp_association_t *asoc, - __u16 inbound, int priority) +struct sctp_ulpq *sctp_ulpq_new(sctp_association_t *asoc, int priority) { - sctp_ulpqueue_t *ulpq; - size_t size; + struct sctp_ulpq *ulpq; - /* Today, there is only a fixed size of storage needed for - * stream support, but make the interfaces acceptable for - * the future. - */ - size = sizeof(sctp_ulpqueue_t)+sctp_ulpqueue_storage_size(inbound); - ulpq = kmalloc(size, priority); + ulpq = kmalloc(sizeof(struct sctp_ulpq), priority); if (!ulpq) goto fail; - if (!sctp_ulpqueue_init(ulpq, asoc, inbound)) + if (!sctp_ulpq_init(ulpq, asoc)) goto fail_init; ulpq->malloced = 1; return ulpq; fail_init: kfree(ulpq); - fail: return NULL; } /* Initialize a ULP queue from a block of memory. */ -sctp_ulpqueue_t *sctp_ulpqueue_init(sctp_ulpqueue_t *ulpq, - sctp_association_t *asoc, - __u16 inbound) -{ - memset(ulpq, - sizeof(sctp_ulpqueue_t) + sctp_ulpqueue_storage_size(inbound), - 0x00); +struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *ulpq, + sctp_association_t *asoc) +{ + memset(ulpq, sizeof(struct sctp_ulpq), 0x00); ulpq->asoc = asoc; - spin_lock_init(&ulpq->lock); skb_queue_head_init(&ulpq->reasm); skb_queue_head_init(&ulpq->lobby); ulpq->malloced = 0; @@ -101,38 +89,39 @@ return ulpq; } + /* Flush the reassembly and ordering queues. */ -void sctp_ulpqueue_flush(sctp_ulpqueue_t *ulpq) +void sctp_ulpq_flush(struct sctp_ulpq *ulpq) { struct sk_buff *skb; - sctp_ulpevent_t *event; + struct sctp_ulpevent *event; while ((skb = skb_dequeue(&ulpq->lobby))) { - event = (sctp_ulpevent_t *) skb->cb; + event = (struct sctp_ulpevent *) skb->cb; sctp_ulpevent_free(event); } while ((skb = skb_dequeue(&ulpq->reasm))) { - event = (sctp_ulpevent_t *) skb->cb; + event = (struct sctp_ulpevent *) skb->cb; sctp_ulpevent_free(event); } } /* Dispose of a ulpqueue. */ -void sctp_ulpqueue_free(sctp_ulpqueue_t *ulpq) +void sctp_ulpq_free(struct sctp_ulpq *ulpq) { - sctp_ulpqueue_flush(ulpq); + sctp_ulpq_flush(ulpq); if (ulpq->malloced) kfree(ulpq); } /* Process an incoming DATA chunk. */ -int sctp_ulpqueue_tail_data(sctp_ulpqueue_t *ulpq, sctp_chunk_t *chunk, +int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, sctp_chunk_t *chunk, int priority) { struct sk_buff_head temp; sctp_data_chunk_t *hdr; - sctp_ulpevent_t *event; + struct sctp_ulpevent *event; hdr = (sctp_data_chunk_t *) chunk->chunk_hdr; @@ -147,7 +136,7 @@ return -ENOMEM; /* Do reassembly if needed. */ - event = sctp_ulpqueue_reasm(ulpq, event); + event = sctp_ulpq_reasm(ulpq, event); /* Do ordering if needed. */ if (event) { @@ -155,18 +144,18 @@ skb_queue_head_init(&temp); skb_queue_tail(&temp, event->parent); - event = sctp_ulpqueue_order(ulpq, event); + event = sctp_ulpq_order(ulpq, event); } /* Send event to the ULP. */ if (event) - sctp_ulpqueue_tail_event(ulpq, event); + sctp_ulpq_tail_event(ulpq, event); return 0; } /* Add a new event for propogation to the ULP. */ -int sctp_ulpqueue_tail_event(sctp_ulpqueue_t *ulpq, sctp_ulpevent_t *event) +int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event) { struct sock *sk = ulpq->asoc->base.sk; @@ -202,20 +191,18 @@ /* 2nd Level Abstractions */ /* Helper function to store chunks that need to be reassembled. */ -static inline void sctp_ulpqueue_store_reasm(sctp_ulpqueue_t *ulpq, sctp_ulpevent_t *event) +static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq, + struct sctp_ulpevent *event) { struct sk_buff *pos, *tmp; - sctp_ulpevent_t *cevent; + struct sctp_ulpevent *cevent; __u32 tsn, ctsn; - unsigned long flags __attribute ((unused)); tsn = event->sndrcvinfo.sinfo_tsn; - sctp_spin_lock_irqsave(&ulpq->reasm.lock, flags); - /* Find the right place in this list. We store them by TSN. */ sctp_skb_for_each(pos, &ulpq->reasm, tmp) { - cevent = (sctp_ulpevent_t *)pos->cb; + cevent = (struct sctp_ulpevent *)pos->cb; ctsn = cevent->sndrcvinfo.sinfo_tsn; if (TSN_lt(tsn, ctsn)) @@ -227,29 +214,45 @@ __skb_insert(event->parent, pos->prev, pos, &ulpq->reasm); else __skb_queue_tail(&ulpq->reasm, event->parent); - - sctp_spin_unlock_irqrestore(&ulpq->reasm.lock, flags); } /* Helper function to return an event corresponding to the reassembled * datagram. + * This routine creates a re-assembled skb given the first and last skb's + * as stored in the reassembly queue. The skb's may be non-linear if the sctp + * payload was fragmented on the way and ip had to reassemble them. + * We add the rest of skb's to the first skb's fraglist. */ -static inline sctp_ulpevent_t *sctp_make_reassembled_event(struct sk_buff *f_frag, struct sk_buff *l_frag) +static inline struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff *f_frag, struct sk_buff *l_frag) { struct sk_buff *pos; - sctp_ulpevent_t *event; - struct sk_buff *pnext; + struct sctp_ulpevent *event; + struct sk_buff *pnext, *last; + struct sk_buff *list = skb_shinfo(f_frag)->frag_list; + /* Store the pointer to the 2nd skb */ pos = f_frag->next; - /* Set the first fragment's frag_list to point to the 2nd fragment. */ - skb_shinfo(f_frag)->frag_list = pos; + /* Get the last skb in the f_frag's frag_list if present. */ + for (last = list; list; last = list, list = list->next); + + /* Add the list of remaining fragments to the first fragments + * frag_list. + */ + if (last) + last->next = pos; + else + skb_shinfo(f_frag)->frag_list = pos; /* Remove the first fragment from the reassembly queue. */ __skb_unlink(f_frag, f_frag->list); do { pnext = pos->next; + /* Update the len and data_len fields of the first fragment. */ + f_frag->len += pos->len; + f_frag->data_len += pos->len; + /* Remove the fragment from the reassembly queue. */ __skb_unlink(pos, pos->list); @@ -269,13 +272,12 @@ /* Helper function to check if an incoming chunk has filled up the last * missing fragment in a SCTP datagram and return the corresponding event. */ -static inline sctp_ulpevent_t *sctp_ulpqueue_retrieve_reassembled(sctp_ulpqueue_t *ulpq) +static inline sctp_ulpevent_t *sctp_ulpq_retrieve_reassembled(struct sctp_ulpq *ulpq) { struct sk_buff *pos, *tmp; sctp_ulpevent_t *cevent; struct sk_buff *first_frag = NULL; __u32 ctsn, next_tsn; - unsigned long flags __attribute ((unused)); sctp_ulpevent_t *retval = NULL; /* Initialized to 0 just to avoid compiler warning message. Will @@ -284,8 +286,6 @@ */ next_tsn = 0; - sctp_spin_lock_irqsave(&ulpq->reasm.lock, flags); - /* The chunks are held in the reasm queue sorted by TSN. * Walk through the queue sequentially and look for a sequence of * fragmented chunks that complete a datagram. @@ -327,7 +327,6 @@ if (retval) break; } - sctp_spin_unlock_irqrestore(&ulpq->reasm.lock, flags); return retval; } @@ -335,7 +334,7 @@ /* Helper function to reassemble chunks. Hold chunks on the reasm queue that * need reassembling. */ -static inline sctp_ulpevent_t *sctp_ulpqueue_reasm(sctp_ulpqueue_t *ulpq, +static inline sctp_ulpevent_t *sctp_ulpq_reasm(struct sctp_ulpq *ulpq, sctp_ulpevent_t *event) { sctp_ulpevent_t *retval = NULL; @@ -350,8 +349,8 @@ if (SCTP_DATA_NOT_FRAG == (event->chunk_flags & SCTP_DATA_FRAG_MASK)) return event; - sctp_ulpqueue_store_reasm(ulpq, event); - retval = sctp_ulpqueue_retrieve_reassembled(ulpq); + sctp_ulpq_store_reasm(ulpq, event); + retval = sctp_ulpq_retrieve_reassembled(ulpq); return retval; } @@ -359,20 +358,20 @@ /* Helper function to gather skbs that have possibly become * ordered by an an incoming chunk. */ -static inline void sctp_ulpqueue_retrieve_ordered(sctp_ulpqueue_t *ulpq, - sctp_ulpevent_t *event) +static inline void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq, + sctp_ulpevent_t *event) { struct sk_buff *pos, *tmp; - sctp_ulpevent_t *cevent; + struct sctp_ulpevent *cevent; + struct sctp_stream *in; __u16 sid, csid; __u16 ssn, cssn; - unsigned long flags __attribute ((unused)); sid = event->sndrcvinfo.sinfo_stream; ssn = event->sndrcvinfo.sinfo_ssn; + in = &ulpq->asoc->ssnmap->in; /* We are holding the chunks by stream, by SSN. */ - sctp_spin_lock_irqsave(&ulpq->lobby.lock, flags); sctp_skb_for_each(pos, &ulpq->lobby, tmp) { cevent = (sctp_ulpevent_t *) pos->cb; csid = cevent->sndrcvinfo.sinfo_stream; @@ -386,32 +385,31 @@ if (csid < sid) continue; - if (cssn != ulpq->ssn[sid]) + if (cssn != sctp_ssn_peek(in, sid)) break; - ulpq->ssn[sid]++; + /* Found it, so mark in the ssnmap. */ + sctp_ssn_next(in, sid); + __skb_unlink(pos, pos->list); /* Attach all gathered skbs to the event. */ __skb_queue_tail(event->parent->list, pos); } - sctp_spin_unlock_irqrestore(&ulpq->lobby.lock, flags); } /* Helper function to store chunks needing ordering. */ -static inline void sctp_ulpqueue_store_ordered(sctp_ulpqueue_t *ulpq, - sctp_ulpevent_t *event) +static inline void sctp_ulpq_store_ordered(struct sctp_ulpq *ulpq, + sctp_ulpevent_t *event) { struct sk_buff *pos, *tmp; sctp_ulpevent_t *cevent; __u16 sid, csid; __u16 ssn, cssn; - unsigned long flags __attribute ((unused)); sid = event->sndrcvinfo.sinfo_stream; ssn = event->sndrcvinfo.sinfo_ssn; - sctp_spin_lock_irqsave(&ulpq->lobby.lock, flags); /* Find the right place in this list. We store them by * stream ID and then by SSN. @@ -432,14 +430,13 @@ __skb_insert(event->parent, pos->prev, pos, &ulpq->lobby); else __skb_queue_tail(&ulpq->lobby, event->parent); - - sctp_spin_unlock_irqrestore(&ulpq->lobby.lock, flags); } -static inline sctp_ulpevent_t *sctp_ulpqueue_order(sctp_ulpqueue_t *ulpq, - sctp_ulpevent_t *event) +static inline sctp_ulpevent_t *sctp_ulpq_order(struct sctp_ulpq *ulpq, + sctp_ulpevent_t *event) { __u16 sid, ssn; + struct sctp_stream *in; /* FIXME: We should be using some new chunk structure here * instead of carrying chunk fields in the event structure. @@ -454,23 +451,24 @@ /* Note: The stream ID must be verified before this routine. */ sid = event->sndrcvinfo.sinfo_stream; ssn = event->sndrcvinfo.sinfo_ssn; + in = &ulpq->asoc->ssnmap->in; /* Is this the expected SSN for this stream ID? */ - if (ssn != ulpq->ssn[sid]) { + if (ssn != sctp_ssn_peek(in, sid)) { /* We've received something out of order, so find where it * needs to be placed. We order by stream and then by SSN. */ - sctp_ulpqueue_store_ordered(ulpq, event); + sctp_ulpq_store_ordered(ulpq, event); return NULL; } /* Mark that the next chunk has been found. */ - ulpq->ssn[sid]++; + sctp_ssn_next(in, sid); /* Go find any other chunks that were waiting for * ordering. */ - sctp_ulpqueue_retrieve_ordered(ulpq, event); + sctp_ulpq_retrieve_ordered(ulpq, event); return event; } diff -Nru a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c --- a/net/sunrpc/clnt.c Fri Feb 14 00:27:28 2003 +++ b/net/sunrpc/clnt.c Fri Feb 14 00:27:28 2003 @@ -63,6 +63,32 @@ static u32 * call_verify(struct rpc_task *task); +static int +rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) +{ + static uint32_t clntid; + int maxlen = sizeof(clnt->cl_pathname); + int error; + + if (dir_name == NULL) + return 0; + for (;;) { + snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname), + "%s/clnt%x", dir_name, + (unsigned int)clntid++); + clnt->cl_pathname[sizeof(clnt->cl_pathname) - 1] = '\0'; + clnt->cl_dentry = rpc_mkdir(clnt->cl_pathname, clnt); + if (!IS_ERR(clnt->cl_dentry)) + return 0; + error = PTR_ERR(clnt->cl_dentry); + if (error != -EEXIST) { + printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n", + clnt->cl_pathname, error); + return error; + } + } +} + /* * Create an RPC client * FIXME: This should also take a flags argument (as in task->tk_flags). @@ -109,14 +135,9 @@ rpc_init_rtt(&clnt->cl_rtt, xprt->timeout.to_initval); - snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname), - "/%s/clnt%p", clnt->cl_protname, clnt); - clnt->cl_dentry = rpc_mkdir(clnt->cl_pathname, clnt); - if (IS_ERR(clnt->cl_dentry)) { - printk(KERN_INFO "RPC: Couldn't create pipefs entry %s\n", - clnt->cl_pathname); + if (rpc_setup_pipedir(clnt, program->pipe_dir_name) < 0) goto out_no_path; - } + if (!rpcauth_create(flavor, clnt)) { printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n", flavor); diff -Nru a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c --- a/net/sunrpc/rpc_pipe.c Fri Feb 14 00:27:27 2003 +++ b/net/sunrpc/rpc_pipe.c Fri Feb 14 00:27:27 2003 @@ -476,54 +476,58 @@ * FIXME: This probably has races. */ static void -rpc_depopulate(struct dentry *dir) +rpc_depopulate(struct dentry *parent) { + struct inode *dir = parent->d_inode; LIST_HEAD(head); struct list_head *pos, *next; struct dentry *dentry; - down(&dir->d_inode->i_sem); + down(&dir->i_sem); spin_lock(&dcache_lock); - list_for_each_safe(pos, next, &dir->d_subdirs) { + list_for_each_safe(pos, next, &parent->d_subdirs) { dentry = list_entry(pos, struct dentry, d_child); if (!d_unhashed(dentry)) { dget_locked(dentry); - list_del(&dentry->d_hash); + __d_drop(dentry); list_add(&dentry->d_hash, &head); } } spin_unlock(&dcache_lock); while (!list_empty(&head)) { dentry = list_entry(head.next, struct dentry, d_hash); - list_del_init(&dentry->d_hash); + /* Private list, so no dcache_lock needed and use __d_drop */ + __d_drop(dentry); if (dentry->d_inode) { rpc_inode_setowner(dentry->d_inode, NULL); - simple_unlink(dir->d_inode, dentry); + simple_unlink(dir, dentry); } dput(dentry); } - up(&dir->d_inode->i_sem); + up(&dir->i_sem); } static int -rpc_populate(struct dentry *dir, +rpc_populate(struct dentry *parent, struct rpc_filelist *files, int start, int eof) { - void *private = RPC_I(dir->d_inode)->private; + struct inode *inode, *dir = parent->d_inode; + void *private = RPC_I(dir)->private; struct qstr name; struct dentry *dentry; - struct inode *inode; int mode, i; + + down(&dir->i_sem); for (i = start; i < eof; i++) { name.name = files[i].name; name.len = strlen(name.name); name.hash = full_name_hash(name.name, name.len); - dentry = d_alloc(dir, &name); + dentry = d_alloc(parent, &name); if (!dentry) goto out_bad; mode = files[i].mode; - inode = rpc_get_inode(dir->d_inode->i_sb, mode); + inode = rpc_get_inode(dir->i_sb, mode); if (!inode) { dput(dentry); goto out_bad; @@ -534,13 +538,15 @@ if (private) rpc_inode_setowner(inode, private); if (S_ISDIR(mode)) - dir->d_inode->i_nlink++; + dir->i_nlink++; d_add(dentry, inode); } + up(&dir->i_sem); return 0; out_bad: + up(&dir->i_sem); printk(KERN_WARNING "%s: %s failed to populate directory %s\n", - __FILE__, __FUNCTION__, dir->d_name.name); + __FILE__, __FUNCTION__, parent->d_name.name); return -ENOMEM; } @@ -569,6 +575,7 @@ { int error; + shrink_dcache_parent(dentry); rpc_inode_setowner(dentry->d_inode, NULL); if ((error = simple_rmdir(dir, dentry)) != 0) return error; diff -Nru a/net/sunrpc/sched.c b/net/sunrpc/sched.c --- a/net/sunrpc/sched.c Fri Feb 14 00:27:28 2003 +++ b/net/sunrpc/sched.c Fri Feb 14 00:27:28 2003 @@ -962,14 +962,8 @@ rpciod_pid = current->pid; up(&rpciod_running); - daemonize(); - - spin_lock_irq(¤t->sighand->siglock); - siginitsetinv(¤t->blocked, sigmask(SIGKILL)); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - strcpy(current->comm, "rpciod"); + daemonize("rpciod"); + allow_signal(SIGKILL); dprintk("RPC: rpciod starting (pid %d)\n", rpciod_pid); while (rpciod_users) { diff -Nru a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c --- a/net/sunrpc/sysctl.c Fri Feb 14 00:27:26 2003 +++ b/net/sunrpc/sysctl.c Fri Feb 14 00:27:26 2003 @@ -116,23 +116,51 @@ return 0; } -#define DIRENTRY(nam1, nam2, child) \ - {CTL_##nam1, #nam2, NULL, 0, 0555, child } -#define DBGENTRY(nam1, nam2) \ - {CTL_##nam1##DEBUG, #nam2 "_debug", &nam2##_debug, sizeof(int),\ - 0644, NULL, &proc_dodebug} - -static ctl_table debug_table[] = { - DBGENTRY(RPC, rpc), - DBGENTRY(NFS, nfs), - DBGENTRY(NFSD, nfsd), - DBGENTRY(NLM, nlm), - {0} +static ctl_table debug_table[] = { + { + .ctl_name = CTL_RPCDEBUG, + .procname = "rpc_debug", + .data = &rpc_debug, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dodebug + }, + { + .ctl_name = CTL_NFSDEBUG, + .procname = "nfs_debug", + .data = &nfs_debug, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dodebug + }, + { + .ctl_name = CTL_NFSDDEBUG, + .procname = "nfsd_debug", + .data = &nfsd_debug, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dodebug + }, + { + .ctl_name = CTL_NLMDEBUG, + .procname = "nlm_debug", + .data = &nlm_debug, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dodebug + }, + { .ctl_name = 0 } }; -static ctl_table sunrpc_table[] = { - DIRENTRY(SUNRPC, sunrpc, debug_table), - {0} +static ctl_table sunrpc_table[] = { + { + .ctl_name = CTL_SUNRPC, + .procname = "sunrpc", + .maxlen = 0, + .mode = 0555, + .child = debug_table + }, + { .ctl_name = 0 } }; #endif diff -Nru a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c --- a/net/sunrpc/xprt.c Fri Feb 14 00:27:29 2003 +++ b/net/sunrpc/xprt.c Fri Feb 14 00:27:29 2003 @@ -1273,25 +1273,41 @@ } /* + * Allocate a 'unique' XID + */ +static u32 +xprt_alloc_xid(void) +{ + static spinlock_t xid_lock = SPIN_LOCK_UNLOCKED; + static int need_init = 1; + static u32 xid; + u32 ret; + + spin_lock(&xid_lock); + if (unlikely(need_init)) { + xid = get_seconds() << 12; + need_init = 0; + } + ret = xid++; + spin_unlock(&xid_lock); + return ret; +} + +/* * Initialize RPC request */ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt) { struct rpc_rqst *req = task->tk_rqstp; - static u32 xid = 0; - - if (!xid) - xid = get_seconds() << 12; - dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid, req, xid); req->rq_timeout = xprt->timeout; req->rq_task = task; req->rq_xprt = xprt; - req->rq_xid = xid++; - if (!xid) - xid++; + req->rq_xid = xprt_alloc_xid(); INIT_LIST_HEAD(&req->rq_list); + dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid, + req, req->rq_xid); } /* diff -Nru a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c --- a/net/unix/sysctl_net_unix.c Fri Feb 14 00:27:28 2003 +++ b/net/unix/sysctl_net_unix.c Fri Feb 14 00:27:28 2003 @@ -15,20 +15,37 @@ extern int sysctl_unix_max_dgram_qlen; ctl_table unix_table[] = { - {NET_UNIX_MAX_DGRAM_QLEN, "max_dgram_qlen", - &sysctl_unix_max_dgram_qlen, sizeof(int), 0600, NULL, - &proc_dointvec }, - {0} + { + .ctl_name = NET_UNIX_MAX_DGRAM_QLEN, + .procname = "max_dgram_qlen", + .data = &sysctl_unix_max_dgram_qlen, + .maxlen = sizeof(int), + .mode = 0600, + .proc_handler = &proc_dointvec + }, + { .ctl_name = 0 } }; static ctl_table unix_net_table[] = { - {NET_UNIX, "unix", NULL, 0, 0555, unix_table}, - {0} + { + .ctl_name = NET_UNIX, + .procname = "unix", + .maxlen = 0, + .mode = 0555, + .child = unix_table + }, + { .ctl_name = 0 } }; static ctl_table unix_root_table[] = { - {CTL_NET, "net", NULL, 0, 0555, unix_net_table}, - {0} + { + .ctl_name = CTL_NET, + .procname = "net", + .maxlen = 0, + .mode = 0555, + .child = unix_net_table + }, + { .ctl_name = 0 } }; static struct ctl_table_header * unix_sysctl_header; diff -Nru a/net/x25/x25_link.c b/net/x25/x25_link.c --- a/net/x25/x25_link.c Fri Feb 14 00:27:26 2003 +++ b/net/x25/x25_link.c Fri Feb 14 00:27:26 2003 @@ -218,8 +218,9 @@ dptr = skb_put(skb, X25_STD_MIN_LEN + 2); - *dptr++ = ((lci >> 8) & 0x0F) | nb->extended ? X25_GFI_EXTSEQ : - X25_GFI_STDSEQ; + *dptr++ = ((lci >> 8) & 0x0F) | (nb->extended ? + X25_GFI_EXTSEQ : + X25_GFI_STDSEQ); *dptr++ = (lci >> 0) & 0xFF; *dptr++ = X25_CLEAR_REQUEST; *dptr++ = cause; diff -Nru a/scripts/Makefile.build b/scripts/Makefile.build --- a/scripts/Makefile.build Fri Feb 14 00:27:29 2003 +++ b/scripts/Makefile.build Fri Feb 14 00:27:29 2003 @@ -94,7 +94,7 @@ else \ $(CPP) -D__GENKSYMS__ $(c_flags) $< \ | $(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) \ - | sed -n 's/\#define __ver_\(\w*\)\W*\(\w*\)/__crc_\1 = 0x\2 ;/gp' \ + | sed -n 's/\#define __ver_\([^ ]*\)[ ]*\([^ ]*\)/__crc_\1 = 0x\2 ;/gp' \ > $(@D)/.tmp_$(@F:.o=.ver); \ \ $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ diff -Nru a/scripts/Makefile.lib b/scripts/Makefile.lib --- a/scripts/Makefile.lib Fri Feb 14 00:27:28 2003 +++ b/scripts/Makefile.lib Fri Feb 14 00:27:28 2003 @@ -165,7 +165,7 @@ # --------------------------------------------------------------------------- quiet_cmd_objcopy = OBJCOPY $@ -cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $< $@ +cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ # Gzip # --------------------------------------------------------------------------- @@ -178,14 +178,16 @@ # =========================================================================== # function to only execute the passed command if necessary +# >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file +# note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars if_changed = $(if $(strip $? \ $(filter-out $(cmd_$(1)),$(cmd_$@))\ $(filter-out $(cmd_$@),$(cmd_$(1)))),\ @set -e; \ - $(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';) \ + $(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';) \ $(cmd_$(1)); \ - echo 'cmd_$@ := $(cmd_$(1))' > $(@D)/.$(@F).cmd) + echo 'cmd_$@ := $(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).cmd) # execute the command and also postprocess generated .d dependencies @@ -195,9 +197,9 @@ $(filter-out $(cmd_$(1)),$(cmd_$@))\ $(filter-out $(cmd_$@),$(cmd_$(1)))),\ @set -e; \ - $(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';) \ + $(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';) \ $(cmd_$(1)); \ - scripts/fixdep $(depfile) $@ '$(cmd_$(1))' > $(@D)/.$(@F).tmp; \ + scripts/fixdep $(depfile) $@ '$(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \ rm -f $(depfile); \ mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd) diff -Nru a/scripts/Makefile.modver b/scripts/Makefile.modver --- a/scripts/Makefile.modver Fri Feb 14 00:27:28 2003 +++ b/scripts/Makefile.modver Fri Feb 14 00:27:28 2003 @@ -9,11 +9,12 @@ # -__modules := $(shell cd $(MODVERDIR); cat *.mod) +__modules := $(shell cat /dev/null $(wildcard $(MODVERDIR)/*.mod)) modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o))) ifneq ($(filter-out $(modules),$(__modules)),) - $(warning *** Uh-oh, you have stale module entries. You messed with SUBDIRS, don't complain if something goes wrong.) + $(warning *** Uh-oh, you have stale module entries. You messed with SUBDIRS,) + $(warning do not complain if something goes wrong.) endif __modversions: $(modules) diff -Nru a/scripts/fixdep.c b/scripts/fixdep.c --- a/scripts/fixdep.c Fri Feb 14 00:27:28 2003 +++ b/scripts/fixdep.c Fri Feb 14 00:27:28 2003 @@ -277,6 +277,8 @@ parse_config_file(map, st.st_size); munmap(map, st.st_size); + + close(fd); } void parse_dep_file(void *map, size_t len) @@ -346,6 +348,8 @@ parse_dep_file(map, st.st_size); munmap(map, st.st_size); + + close(fd); } void traps(void) diff -Nru a/sound/oss/ad1848.c b/sound/oss/ad1848.c --- a/sound/oss/ad1848.c Fri Feb 14 00:27:29 2003 +++ b/sound/oss/ad1848.c Fri Feb 14 00:27:29 2003 @@ -209,15 +209,12 @@ static int ad_read(ad1848_info * devc, int reg) { - unsigned long flags; int x; int timeout = 900000; while (timeout > 0 && inb(devc->base) == 0x80) /*Are we initializing */ timeout--; - spin_lock_irqsave(&devc->lock,flags); - if(reg < 32) { outb(((unsigned char) (reg & 0xff) | devc->MCE_bit), io_Index_Addr(devc)); @@ -233,21 +230,17 @@ outb(((unsigned char) (xra & 0xff)), io_Indexed_Data(devc)); x = inb(io_Indexed_Data(devc)); } - spin_unlock_irqrestore(&devc->lock,flags); return x; } static void ad_write(ad1848_info * devc, int reg, int data) { - unsigned long flags; int timeout = 900000; while (timeout > 0 && inb(devc->base) == 0x80) /* Are we initializing */ timeout--; - spin_lock_irqsave(&devc->lock,flags); - if(reg < 32) { outb(((unsigned char) (reg & 0xff) | devc->MCE_bit), io_Index_Addr(devc)); @@ -263,7 +256,6 @@ outb(((unsigned char) (xra & 0xff)), io_Indexed_Data(devc)); outb((unsigned char) (data & 0xff), io_Indexed_Data(devc)); } - spin_unlock_irqrestore(&devc->lock,flags); } static void wait_for_calibration(ad1848_info * devc) @@ -319,37 +311,29 @@ static void ad_enter_MCE(ad1848_info * devc) { - unsigned long flags; int timeout = 1000; unsigned short prev; while (timeout > 0 && inb(devc->base) == 0x80) /*Are we initializing */ timeout--; - spin_lock_irqsave(&devc->lock,flags); - devc->MCE_bit = 0x40; prev = inb(io_Index_Addr(devc)); if (prev & 0x40) { - spin_unlock_irqrestore(&devc->lock,flags); return; } outb((devc->MCE_bit), io_Index_Addr(devc)); - spin_unlock_irqrestore(&devc->lock,flags); } static void ad_leave_MCE(ad1848_info * devc) { - unsigned long flags; unsigned char prev, acal; int timeout = 1000; while (timeout > 0 && inb(devc->base) == 0x80) /*Are we initializing */ timeout--; - spin_lock_irqsave(&devc->lock,flags); - acal = ad_read(devc, 9); devc->MCE_bit = 0x00; @@ -358,19 +342,18 @@ if ((prev & 0x40) == 0) /* Not in MCE mode */ { - spin_unlock_irqrestore(&devc->lock,flags); return; } outb((0x00), io_Index_Addr(devc)); /* Clear the MCE bit */ if (acal & 0x08) /* Auto calibration is enabled */ wait_for_calibration(devc); - spin_unlock_irqrestore(&devc->lock,flags); } static int ad1848_set_recmask(ad1848_info * devc, int mask) { unsigned char recdev; int i, n; + unsigned long flags; mask &= devc->supported_rec_devices; @@ -392,6 +375,7 @@ if (mask & (1 << i)) n++; + spin_lock_irqsave(&devc->lock,flags); if (!soundpro) { if (n == 0) mask = SOUND_MASK_MIC; @@ -460,6 +444,7 @@ } } } + spin_unlock_irqrestore(&devc->lock,flags); /* Rename the mixer bits back if necessary */ for (i = 0; i < 32; i++) @@ -527,6 +512,7 @@ { int regoffs, muteregoffs; unsigned char val, muteval; + unsigned long flags; regoffs = devc->mix_devices[dev][channel].regno; muteregoffs = devc->mix_devices[dev][channel].mutereg; @@ -539,12 +525,14 @@ else change_bits(devc, &val, &val, dev, channel, value); + spin_lock_irqsave(&devc->lock,flags); ad_write(devc, regoffs, val); devc->saved_regs[regoffs] = val; if (muteregoffs != regoffs) { ad_write(devc, muteregoffs, muteval); devc->saved_regs[muteregoffs] = muteval; } + spin_unlock_irqrestore(&devc->lock,flags); } static int ad1848_mixer_set(ad1848_info * devc, int dev, int value) @@ -600,6 +588,7 @@ { int i; char name[32]; + unsigned long flags; devc->mix_devices = &(ad1848_mix_devices[0]); @@ -666,6 +655,7 @@ devc->mixer_output_port = devc->levels[31] | AUDIO_HEADPHONE | AUDIO_LINE_OUT; + spin_lock_irqsave(&devc->lock,flags); if (!soundpro) { if (devc->mixer_output_port & AUDIO_SPEAKER) ad_write(devc, 26, ad_read(devc, 26) & ~0x40); /* Unmute mono out */ @@ -679,6 +669,7 @@ /* Enable surround mode and SB16 mixer */ ad_write(devc, 16, 0x60); } + spin_unlock_irqrestore(&devc->lock,flags); } static int ad1848_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg) @@ -693,14 +684,17 @@ if (val != 0xffff) { + unsigned long flags; val &= (AUDIO_SPEAKER | AUDIO_HEADPHONE | AUDIO_LINE_OUT); devc->mixer_output_port = val; val |= AUDIO_HEADPHONE | AUDIO_LINE_OUT; /* Always on */ devc->mixer_output_port = val; + spin_lock_irqsave(&devc->lock,flags); if (val & AUDIO_SPEAKER) ad_write(devc, 26, ad_read(devc, 26) & ~0x40); /* Unmute mono out */ else ad_write(devc, 26, ad_read(devc, 26) | 0x40); /* Mute mono out */ + spin_unlock_irqrestore(&devc->lock,flags); } val = devc->mixer_output_port; return put_user(val, (int *)arg); @@ -985,10 +979,11 @@ devc = (ad1848_info *) audio_devs[dev]->devc; portc = (ad1848_port_info *) audio_devs[dev]->portc; - spin_lock_irqsave(&devc->lock,flags); + /* here we don't have to protect against intr */ + spin_lock(&devc->lock); if (portc->open_mode || (devc->open_mode & mode)) { - spin_unlock_irqrestore(&devc->lock,flags); + spin_unlock(&devc->lock); return -EBUSY; } devc->dual_dma = 0; @@ -1001,17 +996,19 @@ devc->audio_mode = 0; devc->open_mode |= mode; portc->open_mode = mode; + spin_unlock(&devc->lock); ad1848_trigger(dev, 0); if (mode & OPEN_READ) devc->record_dev = dev; if (mode & OPEN_WRITE) devc->playback_dev = dev; - spin_unlock_irqrestore(&devc->lock,flags); /* * Mute output until the playback really starts. This decreases clicking (hope so). */ + spin_lock_irqsave(&devc->lock,flags); ad_mute(devc); + spin_unlock_irqrestore(&devc->lock,flags); return 0; } @@ -1024,11 +1021,11 @@ DEB(printk("ad1848_close(void)\n")); - spin_lock_irqsave(&devc->lock,flags); - devc->intr_active = 0; ad1848_halt(dev); + spin_lock_irqsave(&devc->lock,flags); + devc->audio_mode = 0; devc->open_mode &= ~portc->open_mode; portc->open_mode = 0; @@ -1585,6 +1582,7 @@ printk(KERN_ERR "ad1848.c: Port %x not free.\n", io_base); return 0; } + spin_lock_init(&devc->lock); devc->base = io_base; devc->irq_ok = 0; devc->timer_running = 0; @@ -1969,7 +1967,6 @@ ad1848_port_info *portc = NULL; - spin_lock_init(&devc->lock); devc->irq = (irq > 0) ? irq : 0; devc->open_mode = 0; devc->timer_ticks = 0; @@ -2112,6 +2109,7 @@ int ad1848_control(int cmd, int arg) { ad1848_info *devc; + unsigned long flags; if (nr_ad1848_devs < 1) return -ENODEV; @@ -2123,9 +2121,11 @@ case AD1848_SET_XTAL: /* Change clock frequency of AD1845 (only ) */ if (devc->model != MD_1845 || devc->model != MD_1845_SSCAPE) return -EINVAL; + spin_lock_irqsave(&devc->lock,flags); ad_enter_MCE(devc); ad_write(devc, 29, (ad_read(devc, 29) & 0x1f) | (arg << 5)); ad_leave_MCE(devc); + spin_unlock_irqrestore(&devc->lock,flags); break; case AD1848_MIXER_REROUTE: @@ -2253,8 +2253,10 @@ } else if (devc->model != MD_1848) { + spin_lock(&devc->lock); alt_stat = ad_read(devc, 24); ad_write(devc, 24, ad_read(devc, 24) & ~alt_stat); /* Selective ack */ + spin_unlock(&devc->lock); } if ((devc->open_mode & OPEN_READ) && (devc->audio_mode & PCM_ENABLE_INPUT) && (alt_stat & 0x20)) @@ -2831,11 +2833,8 @@ static int ad1848_resume(ad1848_info *devc) { - unsigned long flags; int mixer_levels[32], i; - spin_lock_irqsave(&devc->lock,flags); - /* Thinkpad is a bit more of PITA than normal. The BIOS tends to restore it in a different config to the one we use. Need to fix this somehow */ @@ -2851,7 +2850,7 @@ if (!devc->subtype) { static signed char interrupt_bits[12] = { -1, -1, -1, -1, -1, 0x00, -1, 0x08, -1, 0x10, 0x18, 0x20 }; static char dma_bits[4] = { 1, 2, 0, 3 }; - + unsigned long flags; signed char bits; char dma2_bit = 0; @@ -2860,10 +2859,11 @@ bits = interrupt_bits[devc->irq]; if (bits == -1) { printk(KERN_ERR "MSS: Bad IRQ %d\n", devc->irq); - spin_unlock_irqrestore(&devc->lock,flags); return -1; } + spin_lock_irqsave(&devc->lock,flags); + outb((bits | 0x40), config_port); if (devc->dma2 != -1 && devc->dma2 != devc->dma1) @@ -2873,9 +2873,9 @@ dma2_bit = 0x04; outb((bits | dma_bits[devc->dma1] | dma2_bit), config_port); + spin_unlock_irqrestore(&devc->lock,flags); } - spin_unlock_irqrestore(&devc->lock,flags); return 0; } diff -Nru a/sound/oss/es1370.c b/sound/oss/es1370.c --- a/sound/oss/es1370.c Fri Feb 14 00:27:30 2003 +++ b/sound/oss/es1370.c Fri Feb 14 00:27:30 2003 @@ -2669,7 +2669,8 @@ } set_fs(fs); /* register gameport */ - gameport_register_port(&s->gameport); + if (s->gameport.io) + gameport_register_port(&s->gameport); /* store it in the driver field */ pci_set_drvdata(pcidev, s); diff -Nru a/sound/oss/es1371.c b/sound/oss/es1371.c --- a/sound/oss/es1371.c Fri Feb 14 00:27:29 2003 +++ b/sound/oss/es1371.c Fri Feb 14 00:27:29 2003 @@ -2963,7 +2963,8 @@ /* turn on S/PDIF output driver if requested */ outl(cssr, s->io+ES1371_REG_STATUS); /* register gameport */ - gameport_register_port(&s->gameport); + if (s->gameport.io) + gameport_register_port(&s->gameport); /* store it in the driver field */ pci_set_drvdata(pcidev, s); /* put it into driver list */ diff -Nru a/sound/oss/nec_vrc5477.c b/sound/oss/nec_vrc5477.c --- a/sound/oss/nec_vrc5477.c Fri Feb 14 00:27:29 2003 +++ b/sound/oss/nec_vrc5477.c Fri Feb 14 00:27:29 2003 @@ -6,6 +6,8 @@ * AC97 sound dirver for NEC Vrc5477 chip (an integrated, * multi-function controller chip for MIPS CPUs) * + * VRA support Copyright 2001 Bradley D. LaRonde + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -78,22 +80,31 @@ #include #include #include +#include #include #include #include #include -#include +/* -------------------debug macros -------------------------------------- */ +/* #undef VRC5477_AC97_DEBUG */ +#define VRC5477_AC97_DEBUG #undef VRC5477_AC97_VERBOSE_DEBUG +/* #define VRC5477_AC97_VERBOSE_DEBUG */ -/* one must turn on CONFIG_LL_DEBUG before VERBOSE_DEBUG is turned */ #if defined(VRC5477_AC97_VERBOSE_DEBUG) -#if !defined(CONFIG_LL_DEBUG) -#error "You must turn CONFIG_LL_DEBUG" -#endif +#define VRC5477_AC97_DEBUG #endif +#if defined(VRC5477_AC97_DEBUG) +#include +#define ASSERT(x) if (!(x)) { \ + panic("assertion failed at %s:%d: %s\n", __FILE__, __LINE__, #x); } +#else +#define ASSERT(x) +#endif /* VRC5477_AC97_DEBUG */ + #if defined(VRC5477_AC97_VERBOSE_DEBUG) static u16 inTicket=0; /* check sync between intr & write */ static u16 outTicket=0; @@ -179,16 +190,17 @@ unsigned long io; unsigned int irq; -#ifdef CONFIG_LL_DEBUG +#ifdef VRC5477_AC97_DEBUG /* debug /proc entry */ struct proc_dir_entry *ps; struct proc_dir_entry *ac97_ps; -#endif /* CONFIG_LL_DEBUG */ +#endif /* VRC5477_AC97_DEBUG */ struct ac97_codec codec; unsigned dacChannels, adcChannels; unsigned short dacRate, adcRate; + unsigned short extended_status; spinlock_t lock; struct semaphore open_sem; @@ -226,7 +238,7 @@ /* --------------------------------------------------------------------- */ -extern inline unsigned ld2(unsigned int x) +static inline unsigned ld2(unsigned int x) { unsigned r = 0; @@ -275,7 +287,7 @@ (VRC5477_CODEC_RD_RRDYA | VRC5477_CODEC_RD_RRDYD) ) { /* we get either addr or data, or both */ if (result & VRC5477_CODEC_RD_RRDYA) { - MIPS_ASSERT(addr == ((result >> 16) & 0x7f) ); + ASSERT(addr == ((result >> 16) & 0x7f) ); } if (result & VRC5477_CODEC_RD_RRDYD) { break; @@ -315,6 +327,43 @@ while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000); } +static int ac97_codec_not_present(struct ac97_codec *codec) +{ + struct vrc5477_ac97_state *s = + (struct vrc5477_ac97_state *)codec->private_data; + unsigned long flags; + unsigned short count = 0xffff; + + spin_lock_irqsave(&s->lock, flags); + + /* wait until we can access codec registers */ + do { + if (!(inl(s->io + VRC5477_CODEC_WR) & 0x80000000)) + break; + } while (--count); + + if (count == 0) { + spin_unlock_irqrestore(&s->lock, flags); + return -1; + } + + /* write 0 to reset */ + outl((AC97_RESET << 16) | 0, s->io + VRC5477_CODEC_WR); + + /* test whether we get a response from ac97 chip */ + count = 0xffff; + do { + if (!(inl(s->io + VRC5477_CODEC_WR) & 0x80000000)) + break; + } while (--count); + + if (count == 0) { + spin_unlock_irqrestore(&s->lock, flags); + return -1; + } + spin_unlock_irqrestore(&s->lock, flags); + return 0; +} /* --------------------------------------------------------------------- */ @@ -345,14 +394,16 @@ static void set_dac_rate(struct vrc5477_ac97_state *s, unsigned rate) { + if(s->extended_status & AC97_EXTSTAT_VRA) { wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, rate); - s->dacRate = rate; + s->dacRate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE); + } } /* --------------------------------------------------------------------- */ -extern inline void +static inline void stop_dac(struct vrc5477_ac97_state *s) { struct dmabuf* db = &s->dma_dac; @@ -408,7 +459,7 @@ } /* we should have some data to do the DMA trasnfer */ - MIPS_ASSERT(db->count >= db->fragSize); + ASSERT(db->count >= db->fragSize); /* clear pending fales interrupts */ outl(VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END, @@ -442,12 +493,12 @@ outl (temp, s->io + VRC5477_CTRL); /* it is time to setup next dma transfer */ - MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP); - MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP); + ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP); + ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP); temp = db->nextOut + db->fragSize; if (temp >= db->fragTotalSize) { - MIPS_ASSERT(temp == db->fragTotalSize); + ASSERT(temp == db->fragTotalSize); temp = 0; } @@ -463,14 +514,14 @@ #if defined(VRC5477_AC97_VERBOSE_DEBUG) outTicket = *(u16*)(db->lbuf+db->nextOut); if (db->count > db->fragSize) { - MIPS_ASSERT((u16)(outTicket+1) == *(u16*)(db->lbuf+temp)); + ASSERT((u16)(outTicket+1) == *(u16*)(db->lbuf+temp)); } #endif spin_unlock_irqrestore(&s->lock, flags); } -extern inline void stop_adc(struct vrc5477_ac97_state *s) +static inline void stop_adc(struct vrc5477_ac97_state *s) { struct dmabuf* db = &s->dma_adc; unsigned long flags; @@ -521,7 +572,7 @@ } /* we should at least have some free space in the buffer */ - MIPS_ASSERT(db->count < db->fragTotalSize - db->fragSize * 2); + ASSERT(db->count < db->fragTotalSize - db->fragSize * 2); /* clear pending ones */ outl(VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END, @@ -553,7 +604,7 @@ /* it is time to setup next dma transfer */ temp = db->nextIn + db->fragSize; if (temp >= db->fragTotalSize) { - MIPS_ASSERT(temp == db->fragTotalSize); + ASSERT(temp == db->fragTotalSize); temp = 0; } outl(db->lbufDma + temp, s->io + VRC5477_ADC1_BADDR); @@ -569,11 +620,11 @@ #define DMABUF_DEFAULTORDER (16-PAGE_SHIFT) #define DMABUF_MINORDER 1 -extern inline void dealloc_dmabuf(struct vrc5477_ac97_state *s, +static inline void dealloc_dmabuf(struct vrc5477_ac97_state *s, struct dmabuf *db) { if (db->lbuf) { - MIPS_ASSERT(db->rbuf); + ASSERT(db->rbuf); pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder, db->lbuf, db->lbufDma); pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder, @@ -592,7 +643,7 @@ unsigned bufsize; if (!db->lbuf) { - MIPS_ASSERT(!db->rbuf); + ASSERT(!db->rbuf); db->ready = 0; for (order = DMABUF_DEFAULTORDER; @@ -606,7 +657,7 @@ &db->rbufDma); if (db->lbuf && db->rbuf) break; if (db->lbuf) { - MIPS_ASSERT(!db->rbuf); + ASSERT(!db->rbuf); pci_free_consistent(s->dev, PAGE_SIZE << order, db->lbuf, @@ -614,7 +665,7 @@ } } if (!db->lbuf) { - MIPS_ASSERT(!db->rbuf); + ASSERT(!db->rbuf); return -ENOMEM; } @@ -643,13 +694,13 @@ return 0; } -extern inline int prog_dmabuf_adc(struct vrc5477_ac97_state *s) +static inline int prog_dmabuf_adc(struct vrc5477_ac97_state *s) { stop_adc(s); return prog_dmabuf(s, &s->dma_adc, s->adcRate); } -extern inline int prog_dmabuf_dac(struct vrc5477_ac97_state *s) +static inline int prog_dmabuf_dac(struct vrc5477_ac97_state *s) { stop_dac(s); return prog_dmabuf(s, &s->dma_dac, s->dacRate); @@ -677,7 +728,7 @@ /* set the base addr for next DMA transfer */ temp = adc->nextIn + 2*adc->fragSize; if (temp >= adc->fragTotalSize) { - MIPS_ASSERT( (temp == adc->fragTotalSize) || + ASSERT( (temp == adc->fragTotalSize) || (temp == adc->fragTotalSize + adc->fragSize) ); temp -= adc->fragTotalSize; } @@ -687,7 +738,7 @@ /* adjust nextIn */ adc->nextIn += adc->fragSize; if (adc->nextIn >= adc->fragTotalSize) { - MIPS_ASSERT(adc->nextIn == adc->fragTotalSize); + ASSERT(adc->nextIn == adc->fragTotalSize); adc->nextIn = 0; } @@ -706,13 +757,13 @@ unsigned temp; /* next DMA transfer should already started */ - MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP); - MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP); + // ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP); + // ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP); /* let us set for next next DMA transfer */ temp = dac->nextOut + dac->fragSize*2; if (temp >= dac->fragTotalSize) { - MIPS_ASSERT( (temp == dac->fragTotalSize) || + ASSERT( (temp == dac->fragTotalSize) || (temp == dac->fragTotalSize + dac->fragSize) ); temp -= dac->fragTotalSize; } @@ -728,35 +779,35 @@ printk("assert fail: - %d vs %d\n", *(u16*)(dac->lbuf + dac->nextOut), outTicket); - MIPS_ASSERT(1 == 0); + ASSERT(1 == 0); } #endif /* adjust nextOut pointer */ dac->nextOut += dac->fragSize; if (dac->nextOut >= dac->fragTotalSize) { - MIPS_ASSERT(dac->nextOut == dac->fragTotalSize); + ASSERT(dac->nextOut == dac->fragTotalSize); dac->nextOut = 0; } /* adjust count */ dac->count -= dac->fragSize; if (dac->count <=0 ) { - MIPS_ASSERT(dac->count == 0); - MIPS_ASSERT(dac->nextIn == dac->nextOut); /* buffer under run */ + dac->count = 0; + dac->nextIn = dac->nextOut; stop_dac(s); } #if defined(VRC5477_AC97_VERBOSE_DEBUG) if (dac->count) { outTicket ++; - MIPS_ASSERT(*(u16*)(dac->lbuf + dac->nextOut) == outTicket); + ASSERT(*(u16*)(dac->lbuf + dac->nextOut) == outTicket); } #endif /* we cannot have both under run and someone is waiting on us */ - MIPS_ASSERT(! (waitqueue_active(&dac->wait) && (dac->count <= 0)) ); + ASSERT(! (waitqueue_active(&dac->wait) && (dac->count <= 0)) ); /* wake up anybody listening */ if (waitqueue_active(&dac->wait)) @@ -905,7 +956,7 @@ copyCount -= count; bufStart += count; - MIPS_ASSERT(bufStart <= db->fragTotalSize); + ASSERT(bufStart <= db->fragTotalSize); buffer += count *2; } return 0; @@ -937,12 +988,12 @@ } if (copyCount + db->nextOut > db->fragTotalSize) { copyCount = db->fragTotalSize - db->nextOut; - MIPS_ASSERT((copyCount % db->fragSize) == 0); + ASSERT((copyCount % db->fragSize) == 0); } copyFragCount = (copyCount-1) >> db->fragShift; copyFragCount = (copyFragCount+1) << db->fragShift; - MIPS_ASSERT(copyFragCount >= copyCount); + ASSERT(copyFragCount >= copyCount); /* we copy differently based on adc channels */ if (s->adcChannels == 1) { @@ -965,12 +1016,12 @@ db->nextOut += copyFragCount; if (db->nextOut >= db->fragTotalSize) { - MIPS_ASSERT(db->nextOut == db->fragTotalSize); + ASSERT(db->nextOut == db->fragTotalSize); db->nextOut = 0; } - MIPS_ASSERT((copyFragCount % db->fragSize) == 0); - MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount)); + ASSERT((copyFragCount % db->fragSize) == 0); + ASSERT( (count == 0) || (copyCount == copyFragCount)); } spin_lock_irqsave(&s->lock, flags); @@ -999,7 +1050,7 @@ if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; - MIPS_ASSERT(db->ready); + ASSERT(db->ready); while (count > 0) { // wait for samples in capture buffer @@ -1024,7 +1075,7 @@ } } while (avail <= 0); - MIPS_ASSERT( (avail % db->fragSize) == 0); + ASSERT( (avail % db->fragSize) == 0); copyCount = copy_adc_to_user(s, buffer, count, avail); if (copyCount <=0 ) { if (!ret) ret = -EFAULT; @@ -1047,7 +1098,7 @@ struct dmabuf *db = &s->dma_dac; int bufStart = db->nextIn; - MIPS_ASSERT(db->ready); + ASSERT(db->ready); for (; copyCount > 0; ) { int i; @@ -1065,7 +1116,7 @@ copyCount -= count; bufStart += count; - MIPS_ASSERT(bufStart <= db->fragTotalSize); + ASSERT(bufStart <= db->fragTotalSize); buffer += count *2; } return 0; @@ -1101,13 +1152,11 @@ } if (copyCount + db->nextIn > db->fragTotalSize) { copyCount = db->fragTotalSize - db->nextIn; - MIPS_ASSERT((copyCount % db->fragSize) == 0); - MIPS_ASSERT(copyCount > 0); + ASSERT(copyCount > 0); } - copyFragCount = (copyCount-1) >> db->fragShift; - copyFragCount = (copyFragCount+1) << db->fragShift; - MIPS_ASSERT(copyFragCount >= copyCount); + copyFragCount = copyCount; + ASSERT(copyFragCount >= copyCount); /* we copy differently based on the number channels */ if (s->dacChannels == 1) { @@ -1147,12 +1196,11 @@ db->nextIn += copyFragCount; if (db->nextIn >= db->fragTotalSize) { - MIPS_ASSERT(db->nextIn == db->fragTotalSize); + ASSERT(db->nextIn == db->fragTotalSize); db->nextIn = 0; } - MIPS_ASSERT((copyFragCount % db->fragSize) == 0); - MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount)); + ASSERT( (count == 0) || (copyCount == copyFragCount)); } spin_lock_irqsave(&s->lock, flags); @@ -1162,7 +1210,7 @@ } /* nextIn should not be equal to nextOut unless we are full */ - MIPS_ASSERT( ( (db->count == db->fragTotalSize) && + ASSERT( ( (db->count == db->fragTotalSize) && (db->nextIn == db->nextOut) ) || ( (db->count < db->fragTotalSize) && (db->nextIn != db->nextOut) ) ); @@ -1210,7 +1258,6 @@ } } while (avail <= 0); - MIPS_ASSERT( (avail % db->fragSize) == 0); copyCount = copy_dac_from_user(s, buffer, count, avail); if (copyCount < 0) { if (!ret) ret = -EFAULT; @@ -1251,7 +1298,7 @@ return mask; } -#ifdef CONFIG_LL_DEBUG +#ifdef VRC5477_AC97_DEBUG static struct ioctl_str_t { unsigned int cmd; const char* str; @@ -1302,7 +1349,7 @@ int count; int val, ret; -#ifdef CONFIG_LL_DEBUG +#ifdef VRC5477_AC97_DEBUG for (count=0; count> 16) & 0x7f) ); - return result & 0xffff; -} - -void mywrcodec(u8 addr, u16 data) -{ - /* wait until we can access codec registers */ - while (myinl(VRC5477_CODEC_WR) & 0x80000000); - - /* write the address and value to codec */ - myoutl((addr << 16) | data, VRC5477_CODEC_WR); - -} - - -void jsun_ac97_test(struct vrc5477_ac97_state *s) -{ - int i; - - /* reset codec */ - /* - wrcodec(&s->codec, 0, 0); - while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000); - */ - mywrcodec(0, 0); - while (myinl(VRC5477_CODEC_WR) & 0x80000000); - - for (i=0; i< 0x40; i+=4) { - MIPS_ASSERT(inl(s->io+i) == myinl(i)); - } - - printk("codec registers : "); - for (i=0; i<= 0x3a; i+=2) { - if ( (i%0x10) == 0) { - printk("\n%02x\t", i); - } - // printk("%04x\t", rdcodec(&s->codec, i)); - printk("%04x\t", myrdcodec(i)); - } - printk("\n\n"); - printk("codec registers : "); - for (i=0; i<= 0x3a; i+=2) { - if ( (i%0x10) == 0) { - printk("\n%02x\t", i); - } - printk("%04x\t", rdcodec(&s->codec, i)); - } - printk("\n\n"); -} - static int __devinit vrc5477_ac97_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) { struct vrc5477_ac97_state *s; +#ifdef VRC5477_AC97_DEBUG char proc_str[80]; - - MIPS_DEBUG(printk("vrc5477_ac97_probe() invoked\n")); +#endif if (pcidev->irq == 0) return -1; @@ -1883,6 +1855,13 @@ * no persistent state across file opens. */ + /* test if get response from ac97, if not return */ + if (ac97_codec_not_present(&(s->codec))) { + printk(KERN_ERR PFX "no ac97 codec\n"); + goto err_region; + + } + if (!request_region(s->io, pci_resource_len(pcidev,0), VRC5477_AC97_MODULE_NAME)) { printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n", @@ -1904,37 +1883,27 @@ register_sound_mixer(&vrc5477_ac97_mixer_fops, -1)) < 0) goto err_dev2; -#ifdef CONFIG_LL_DEBUG +#ifdef VRC5477_AC97_DEBUG /* intialize the debug proc device */ s->ps = create_proc_read_entry(VRC5477_AC97_MODULE_NAME, 0, NULL, proc_vrc5477_ac97_dump, NULL); -#endif /* CONFIG_LL_DEBUG */ +#endif /* VRC5477_AC97_DEBUG */ /* enable pci io and bus mastering */ if (pci_enable_device(pcidev)) goto err_dev3; pci_set_master(pcidev); -/* -jsun_scan_pci_bus(); -vrc5477_show_pci_regs(); -vrc5477_show_pdar_regs(); -*/ - /* cold reset the AC97 */ outl(VRC5477_ACLINK_CTRL_RST_ON | VRC5477_ACLINK_CTRL_RST_TIME, s->io + VRC5477_ACLINK_CTRL); while (inl(s->io + VRC5477_ACLINK_CTRL) & VRC5477_ACLINK_CTRL_RST_ON); -/* -jsun_ac97_test(s); -*/ - /* codec init */ if (!ac97_probe_codec(&s->codec)) goto err_dev3; -#ifdef CONFIG_LL_DEBUG +#ifdef VRC5477_AC97_DEBUG sprintf(proc_str, "driver/%s/%d/ac97", VRC5477_AC97_MODULE_NAME, s->codec.id); s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL, @@ -1942,16 +1911,28 @@ /* TODO : why this proc file does not show up? */ #endif + /* Try to enable variable rate audio mode. */ + wrcodec(&s->codec, AC97_EXTENDED_STATUS, + rdcodec(&s->codec, AC97_EXTENDED_STATUS) | AC97_EXTSTAT_VRA); + /* Did we enable it? */ + if(rdcodec(&s->codec, AC97_EXTENDED_STATUS) & AC97_EXTSTAT_VRA) + s->extended_status |= AC97_EXTSTAT_VRA; + else { + s->dacRate = 48000; + printk(KERN_INFO PFX "VRA mode not enabled; rate fixed at %d.", + s->dacRate); + } + /* let us get the default volumne louder */ - wrcodec(&s->codec, 0x2, 0); - wrcodec(&s->codec, 0x18, 0x0707); - /* mute line in loopback to line out */ - wrcodec(&s->codec, 0x10, 0x8000); + wrcodec(&s->codec, 0x2, 0x1010); /* master volume, middle */ + wrcodec(&s->codec, 0xc, 0x10); /* phone volume, middle */ + // wrcodec(&s->codec, 0xe, 0x10); /* misc volume, middle */ + wrcodec(&s->codec, 0x10, 0x8000); /* line-in 2 line-out disable */ + wrcodec(&s->codec, 0x18, 0x0707); /* PCM out (line out) middle */ + /* by default we select line in the input */ wrcodec(&s->codec, 0x1a, 0x0404); - /* pick middle value for record gain */ - // wrcodec(&s->codec, 0x1c, 0x0707); wrcodec(&s->codec, 0x1c, 0x0f0f); wrcodec(&s->codec, 0x1e, 0x07); @@ -1989,10 +1970,12 @@ if (!s) return; list_del(&s->devs); -#ifdef CONFIG_LL_DEBUG + +#ifdef VRC5477_AC97_DEBUG if (s->ps) remove_proc_entry(VRC5477_AC97_MODULE_NAME, NULL); -#endif /* CONFIG_LL_DEBUG */ +#endif /* VRC5477_AC97_DEBUG */ + synchronize_irq(s->irq); free_irq(s->irq, s); release_region(s->io, pci_resource_len(dev,0)); @@ -2003,8 +1986,6 @@ } -#define PCI_VENDOR_ID_NEC 0x1033 -#define PCI_DEVICE_ID_NEC_VRC5477_AC97 0x00A6 static struct pci_device_id id_table[] __devinitdata = { { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC5477_AC97, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, @@ -2024,7 +2005,7 @@ { if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk("Vrc5477 AC97 driver: version v0.1 time " __TIME__ " " __DATE__ " by Jun Sun\n"); + printk("Vrc5477 AC97 driver: version v0.2 time " __TIME__ " " __DATE__ " by Jun Sun\n"); return pci_module_init(&vrc5477_ac97_driver); } diff -Nru a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c --- a/sound/oss/rme96xx.c Fri Feb 14 00:27:27 2003 +++ b/sound/oss/rme96xx.c Fri Feb 14 00:27:27 2003 @@ -10,6 +10,17 @@ * 11 May 2001: 0.4 fixed for SMP, included into kernel source tree * 17 May 2001: 0.5 draining code didn't work on new cards * 18 May 2001: 0.6 remove synchronize_irq() call + * 17 Jul 2001: 0.7 updated xrmectrl to make it work for newer cards + * 2 feb 2002: 0.8 fixed pci device handling, see below for patches from Heiko (Thanks!) + Marcus Meissner + + Modifications - Heiko Purnhagen + HP20020108 fixed handling of "large" read() + HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c + HP20020118 made mixer ioctl and handling of devices>1 more safe + HP20020201 fixed handling of "large" read() properly + added REV 1.5 S/P-DIF receiver support + SNDCTL_DSP_SPEED now returns the actual speed * 10 Aug 2002: added synchronize_irq() again TODO: @@ -20,15 +31,17 @@ - mixer mmap interface - mixer ioctl - get rid of noise upon first open (why ??) - - allow multiple open(at least for read) + - allow multiple open (at least for read) - allow multiple open for non overlapping regions - recheck the multiple devices part (offsets of different devices, etc) - do decent draining in _release --- done - SMP support + - what about using fragstotal>2 for small fragsize? (HP20020118) + - add support for AFMT_S32_LE */ #ifndef RMEVERSION -#define RMEVERSION "0.6" +#define RMEVERSION "0.8" #endif #include @@ -41,6 +54,8 @@ #include #include #include +#include +#include #include #include #include @@ -134,45 +149,57 @@ #define RME96xx_F_0 0x0400000 /* 000=64kHz, 100=88.2kHz, 011=96kHz */ #define RME96xx_F_1 0x0800000 /* 111=32kHz, 110=44.1kHz, 101=48kHz, */ -#define RME96xx_F_2 0x1000000 /* od external Crystal Chip if ERF=1*/ +#define RME96xx_F_2 0x1000000 /* 001=Rev 1.5+ external Crystal Chip */ #define RME96xx_ERF 0x2000000 /* Error-Flag of SDPIF Receiver (1=No Lock)*/ #define RME96xx_buffer_id 0x4000000 /* toggles by each interrupt on rec/play */ #define RME96xx_tc_valid 0x8000000 /* 1 = a signal is detected on time-code input */ +#define RME96xx_SPDIF_READ 0x10000000 /* byte available from Rev 1.5+ SPDIF interface */ /* Status Register Fields */ #define RME96xx_lock (RME96xx_lock_0|RME96xx_lock_1|RME96xx_lock_2) -#define RME96xx_buf_pos 0x000FFC0 #define RME96xx_sync (RME96xx_sync_0|RME96xx_sync_1|RME96xx_sync_2) #define RME96xx_F (RME96xx_F_0|RME96xx_F_1|RME96xx_F_2) +#define rme96xx_decode_spdif_rate(x) ((x)>>22) +/* Bit 6..15 : h/w buffer pointer */ +#define RME96xx_buf_pos 0x000FFC0 +/* Bits 31,30,29 are bits 5,4,3 of h/w pointer position on later + Rev G EEPROMS and Rev 1.5 cards or later. +*/ +#define RME96xx_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME96xx_buf_pos)) /* Control-Register: */ /*--------------------------------------------------------------------------------*/ -#define RME96xx_start_bit 0x0001 /* start record/play */ -#define RME96xx_latency0 0x0002 /* Bit 0 - Buffer size or latency */ -#define RME96xx_latency1 0x0004 /* Bit 1 - Buffer size or latency */ -#define RME96xx_latency2 0x0008 /* Bit 2 - Buffer size or latency */ - -#define RME96xx_Master 0x0010 /* Clock Mode Master=1,Slave/Auto=0 */ -#define RME96xx_IE 0x0020 /* Interupt Enable */ -#define RME96xx_freq 0x0040 /* samplerate 0=44.1/88.2, 1=48/96 kHz*/ - - -#define RME96xx_DS 0x0100 /* Doule Speed 0=44.1/48, 1=88.2/96 Khz */ -#define RME96xx_PRO 0x0200 /* spdif 0=consumer, 1=professional Mode*/ -#define RME96xx_EMP 0x0400 /* spdif Emphasis 0=None, 1=ON */ -#define RME96xx_Dolby 0x0800 /* spdif Non-audio bit 1=set, 0=unset */ - -#define RME96xx_opt_out 0x1000 /* Use 1st optical OUT as SPDIF: 1=yes,0=no */ -#define RME96xx_wsel 0x2000 /* use Wordclock as sync (overwrites master)*/ -#define RME96xx_inp_0 0x4000 /* SPDIF-IN: 00=optical (ADAT1), */ -#define RME96xx_inp_1 0x8000 /* 01=koaxial (Cinch), 10=Internal CDROM*/ - -#define RME96xx_SyncRef0 0x10000 /* preferred sync-source in autosync */ -#define RME96xx_SyncRef1 0x20000 /* 00=ADAT1,01=ADAT2,10=ADAT3,11=SPDIF */ +#define RME96xx_start_bit 0x0001 /* start record/play */ +#define RME96xx_latency0 0x0002 /* Buffer size / latency */ +#define RME96xx_latency1 0x0004 /* buffersize = 512Bytes * 2^n */ +#define RME96xx_latency2 0x0008 /* 0=64samples ... 7=8192samples */ + +#define RME96xx_Master 0x0010 /* Clock Mode 1=Master, 0=Slave/Auto */ +#define RME96xx_IE 0x0020 /* Interupt Enable */ +#define RME96xx_freq 0x0040 /* samplerate 0=44.1/88.2, 1=48/96 kHz*/ +#define RME96xx_freq1 0x0080 /* samplerate 0=32 kHz, 1=other rates ??? (from ALSA, but may be wrong) */ +#define RME96xx_DS 0x0100 /* double speed 0=44.1/48, 1=88.2/96 Khz */ +#define RME96xx_PRO 0x0200 /* SPDIF-OUT 0=consumer, 1=professional */ +#define RME96xx_EMP 0x0400 /* SPDIF-OUT emphasis 0=off, 1=on */ +#define RME96xx_Dolby 0x0800 /* SPDIF-OUT non-audio bit 1=set, 0=unset */ + +#define RME96xx_opt_out 0x1000 /* use 1st optical OUT as SPDIF: 1=yes, 0=no */ +#define RME96xx_wsel 0x2000 /* use Wordclock as sync (overwrites master) */ +#define RME96xx_inp_0 0x4000 /* SPDIF-IN 00=optical (ADAT1), */ +#define RME96xx_inp_1 0x8000 /* 01=coaxial (Cinch), 10=internal CDROM */ + +#define RME96xx_SyncRef0 0x10000 /* preferred sync-source in autosync */ +#define RME96xx_SyncRef1 0x20000 /* 00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */ + +#define RME96xx_SPDIF_RESET (1<<18) /* Rev 1.5+: h/w SPDIF receiver */ +#define RME96xx_SPDIF_SELECT (1<<19) +#define RME96xx_SPDIF_CLOCK (1<<20) +#define RME96xx_SPDIF_WRITE (1<<21) +#define RME96xx_ADAT1_INTERNAL (1<<22) /* Rev 1.5+: if set, internal CD connector carries ADAT */ #define RME96xx_ctrl_init (RME96xx_latency0 |\ @@ -186,7 +213,9 @@ #define RME96xx_latency (RME96xx_latency0|RME96xx_latency1|RME96xx_latency2) #define RME96xx_inp (RME96xx_inp_0|RME96xx_inp_1) #define RME96xx_SyncRef (RME96xx_SyncRef0|RME96xx_SyncRef1) -/* latency = 512Bytes * 2^n, where n is made from Bit3 ... Bit0 */ +#define RME96xx_mixer_allowed (RME96xx_Master|RME96xx_PRO|RME96xx_EMP|RME96xx_Dolby|RME96xx_opt_out|RME96xx_wsel|RME96xx_inp|RME96xx_SyncRef|RME96xx_ADAT1_INTERNAL) + +/* latency = 512Bytes * 2^n, where n is made from Bit3 ... Bit1 (??? HP20020201) */ #define RME96xx_SET_LATENCY(x) (((x)&0x7)<<1) #define RME96xx_GET_LATENCY(x) (((x)>>1)&0x7) @@ -211,6 +240,7 @@ #define RME96xx_MAX_DEVS 4 /* we provide some OSS stereodevs */ +#define RME96xx_MASK_DEVS 0x3 /* RME96xx_MAX_DEVS-1 */ #define RME_MESS "rme96xx:" /*------------------------------------------------------------------------ @@ -259,8 +289,10 @@ u32 thru_bits; /* thru 1=on, 0=off channel 1=Bit1... channel 26= Bit26 */ - int open_count; + int hw_rev; /* h/w rev * 10 (i.e. 1.5 has hw_rev = 15) */ + char *card_name; /* hammerfall or hammerfall light names */ + int open_count; /* unused ??? HP20020201 */ int rate; int latency; @@ -324,6 +356,181 @@ } +inline int rme96xx_get_sample_rate_status(rme96xx_info* s) +{ + int val; + u32 status; + status = readl(s->iobase + RME96xx_status_register); + val = (status & RME96xx_fs48) ? 48000 : 44100; + if (status & RME96xx_DS_rd) + val *= 2; + return val; +} + +inline int rme96xx_get_sample_rate_ctrl(rme96xx_info* s) +{ + int val; + val = (s->control_register & RME96xx_freq) ? 48000 : 44100; + if (s->control_register & RME96xx_DS) + val *= 2; + return val; +} + + +/* code from ALSA card-rme9652.c for rev 1.5 SPDIF receiver HP 20020201 */ + +static void rme96xx_spdif_set_bit (rme96xx_info* s, int mask, int onoff) +{ + if (onoff) + s->control_register |= mask; + else + s->control_register &= ~mask; + + writel(s->control_register,s->iobase + RME96xx_control_register); +} + +static void rme96xx_spdif_write_byte (rme96xx_info* s, const int val) +{ + long mask; + long i; + + for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) { + if (val & mask) + rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 1); + else + rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 0); + + rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1); + rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0); + } +} + +static int rme96xx_spdif_read_byte (rme96xx_info* s) +{ + long mask; + long val; + long i; + + val = 0; + + for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) { + rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1); + if (readl(s->iobase + RME96xx_status_register) & RME96xx_SPDIF_READ) + val |= mask; + rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0); + } + + return val; +} + +static void rme96xx_write_spdif_codec (rme96xx_info* s, const int address, const int data) +{ + rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1); + rme96xx_spdif_write_byte (s, 0x20); + rme96xx_spdif_write_byte (s, address); + rme96xx_spdif_write_byte (s, data); + rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0); +} + + +static int rme96xx_spdif_read_codec (rme96xx_info* s, const int address) +{ + int ret; + + rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1); + rme96xx_spdif_write_byte (s, 0x20); + rme96xx_spdif_write_byte (s, address); + rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0); + rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1); + + rme96xx_spdif_write_byte (s, 0x21); + ret = rme96xx_spdif_read_byte (s); + rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0); + + return ret; +} + +static void rme96xx_initialize_spdif_receiver (rme96xx_info* s) +{ + /* XXX what unsets this ? */ + /* no idea ??? HP 20020201 */ + + s->control_register |= RME96xx_SPDIF_RESET; + + rme96xx_write_spdif_codec (s, 4, 0x40); + rme96xx_write_spdif_codec (s, 17, 0x13); + rme96xx_write_spdif_codec (s, 6, 0x02); +} + +static inline int rme96xx_spdif_sample_rate (rme96xx_info *s, int *spdifrate) +{ + unsigned int rate_bits; + + *spdifrate = 0x1; + if (readl(s->iobase + RME96xx_status_register) & RME96xx_ERF) { + return -1; /* error condition */ + } + + if (s->hw_rev == 15) { + + int x, y, ret; + + x = rme96xx_spdif_read_codec (s, 30); + + if (x != 0) + y = 48000 * 64 / x; + else + y = 0; + + if (y > 30400 && y < 33600) {ret = 32000; *spdifrate = 0x7;} + else if (y > 41900 && y < 46000) {ret = 44100; *spdifrate = 0x6;} + else if (y > 46000 && y < 50400) {ret = 48000; *spdifrate = 0x5;} + else if (y > 60800 && y < 67200) {ret = 64000; *spdifrate = 0x0;} + else if (y > 83700 && y < 92000) {ret = 88200; *spdifrate = 0x4;} + else if (y > 92000 && y < 100000) {ret = 96000; *spdifrate = 0x3;} + else {ret = 0; *spdifrate = 0x1;} + return ret; + } + + rate_bits = readl(s->iobase + RME96xx_status_register) & RME96xx_F; + + switch (*spdifrate = rme96xx_decode_spdif_rate(rate_bits)) { + case 0x7: + return 32000; + break; + + case 0x6: + return 44100; + break; + + case 0x5: + return 48000; + break; + + case 0x4: + return 88200; + break; + + case 0x3: + return 96000; + break; + + case 0x0: + return 64000; + break; + + default: + /* was an ALSA warning ... + snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n", + s->card_name, rate_bits); + */ + return 0; + break; + } +} + +/* end of code from ALSA card-rme9652.c */ + /* the hwbuf in the status register seems to have some jitter, to get rid of @@ -662,6 +869,9 @@ int rme96xx_init(rme96xx_info* s) { int i; + int status; + unsigned short rev; + DBG(printk(__FUNCTION__"\n")); numcards++; @@ -694,6 +904,56 @@ rme96xx_dmabuf_init(s,dma,2*i,2*i); } + /* code from ALSA card-rme9652.c HP 20020201 */ + /* Determine the h/w rev level of the card. This seems like + a particularly kludgy way to encode it, but its what RME + chose to do, so we follow them ... + */ + + status = readl(s->iobase + RME96xx_status_register); + if (rme96xx_decode_spdif_rate(status&RME96xx_F) == 1) { + s->hw_rev = 15; + } else { + s->hw_rev = 11; + } + + /* Differentiate between the standard Hammerfall, and the + "Light", which does not have the expansion board. This + method comes from information received from Mathhias + Clausen at RME. Display the EEPROM and h/w revID where + relevant. + */ + + pci_read_config_word(s->pcidev, PCI_CLASS_REVISION, &rev); + switch (rev & 0xff) { + case 8: /* original eprom */ + if (s->hw_rev == 15) { + s->card_name = "RME Digi9636 (Rev 1.5)"; + } else { + s->card_name = "RME Digi9636"; + } + break; + case 9: /* W36_G EPROM */ + s->card_name = "RME Digi9636 (Rev G)"; + break; + case 4: /* W52_G EPROM */ + s->card_name = "RME Digi9652 (Rev G)"; + break; + default: + case 3: /* original eprom */ + if (s->hw_rev == 15) { + s->card_name = "RME Digi9652 (Rev 1.5)"; + } else { + s->card_name = "RME Digi9652"; + } + break; + } + + printk(KERN_INFO RME_MESS" detected %s (hw_rev %d)\n",s->card_name,s->hw_rev); + + if (s->hw_rev == 15) + rme96xx_initialize_spdif_receiver (s); + s->started = 0; rme96xx_setlatency(s,7); @@ -734,7 +994,7 @@ if (pci_enable_device(pcidev)) goto err_irq; - if (request_irq(s->irq, rme96xx_interrupt, SA_SHIRQ, "es1370", s)) { + if (request_irq(s->irq, rme96xx_interrupt, SA_SHIRQ, "rme96xx", s)) { printk(KERN_ERR RME_MESS" irq %u in use\n", s->irq); goto err_irq; } @@ -836,6 +1096,7 @@ if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; printk(KERN_INFO RME_MESS" version "RMEVERSION" time " __TIME__ " " __DATE__ "\n"); + devices = ((devices-1) & RME96xx_MASK_DEVS) + 1; printk(KERN_INFO RME_MESS" reserving %d dsp device(s)\n",devices); numcards = 0; return pci_module_init(&rme96xx_driver); @@ -859,13 +1120,11 @@ ---------------------------------------------------------------------------*/ #define RME96xx_FMT (AFMT_S16_LE|AFMT_U8|AFMT_S32_BLOCKED) +/* AFTM_U8 is not (yet?) supported ... HP20020201 */ - -static int rme96xx_ioctl(struct inode *in, struct file *file, - unsigned int cmd, unsigned long arg) +static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, unsigned long arg) { - struct dmabuf * dma = (struct dmabuf *)file->private_data; rme96xx_info *s = dma->s; unsigned long flags; @@ -918,14 +1177,23 @@ case 96000: rme96xx_set_ctrl(s,RME96xx_freq); break; + /* just report current rate as default + e.g. use 0 to "select" current digital input rate default: rme96xx_unset_ctrl(s,RME96xx_freq); val = 44100; + */ } if (val > 50000) rme96xx_set_ctrl(s,RME96xx_DS); else rme96xx_unset_ctrl(s,RME96xx_DS); + /* set val to actual value HP 20020201 */ + /* NOTE: if not "Sync Master", reported rate might be not yet "updated" ... but I don't want to insert a long udelay() here */ + if ((s->control_register & RME96xx_Master) && !(s->control_register & RME96xx_wsel)) + val = rme96xx_get_sample_rate_ctrl(s); + else + val = rme96xx_get_sample_rate_status(s); s->rate = val; spin_unlock_irqrestore(&s->lock, flags); } @@ -1146,6 +1414,8 @@ return 0; case SOUND_PCM_READ_RATE: + /* HP20020201 */ + s->rate = rme96xx_get_sample_rate_status(s); return put_user(s->rate, (int *)arg); case SOUND_PCM_READ_CHANNELS: @@ -1179,28 +1449,29 @@ { int minor = minor(in->i_rdev); struct list_head *list; - int devnum = ((minor-3)/16) % devices; /* default = 0 */ + int devnum; rme96xx_info *s; struct dmabuf* dma; DECLARE_WAITQUEUE(wait, current); DBG(printk("device num %d open\n",devnum)); -/* ??? */ for (list = devs.next; ; list = list->next) { if (list == &devs) return -ENODEV; s = list_entry(list, rme96xx_info, devs); - if (!((s->dspnum[devnum] ^ minor) & ~0xf)) + for (devnum=0; devnumdspnum[devnum] ^ minor) & ~0xf)) + break; + if (devnumdma[devnum]; f->private_data = dma; /* wait for device to become free */ - down(&s->dma[devnum].open_sem); + down(&dma->open_sem); while (dma->open_mode & f->f_mode) { if (f->f_flags & O_NONBLOCK) { up(&dma->open_sem); @@ -1219,11 +1490,11 @@ COMM ("hardware open") - if (!s->dma[devnum].opened) rme96xx_dmabuf_init(dma->s,dma,dma->inoffset,dma->outoffset); + if (!dma->opened) rme96xx_dmabuf_init(dma->s,dma,dma->inoffset,dma->outoffset); - s->dma[devnum].open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE)); - s->dma[devnum].opened = 1; - up(&s->dma[devnum].open_sem); + dma->open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE)); + dma->opened = 1; + up(&dma->open_sem); DBG(printk("device num %d open finished\n",devnum)); return 0; @@ -1232,7 +1503,7 @@ static int rme96xx_release(struct inode *in, struct file *file) { struct dmabuf * dma = (struct dmabuf*) file->private_data; - /* int hwp; */ + /* int hwp; ... was unused HP20020201 */ DBG(printk(__FUNCTION__"\n")); COMM ("draining") @@ -1261,8 +1532,7 @@ } -static ssize_t rme96xx_write(struct file *file, const char *buffer, - size_t count, loff_t *ppos) +static ssize_t rme96xx_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct dmabuf *dma = (struct dmabuf *)file->private_data; ssize_t ret = 0; @@ -1296,7 +1566,6 @@ dma->readptr = hwp; dma->writeptr = hwp; dma->started = 1; - COMM ("first write done") } while (count > 0) { @@ -1331,11 +1600,11 @@ return ret; } -static ssize_t rme96xx_read(struct file *file, char *buffer,size_t count, loff_t *ppos) +static ssize_t rme96xx_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct dmabuf *dma = (struct dmabuf *)file->private_data; ssize_t ret = 0; - int cnt; + int cnt; /* number of bytes from "buffer" that will/can be used */ int hop = count/dma->inchannels; int hwp; int exact = (file->f_flags & O_NONBLOCK); @@ -1356,9 +1625,6 @@ if (! (dma->open_mode & FMODE_READ)) return -ENXIO; - if (count > ((dma->s->fragsize*dma->inchannels)>>dma->formatshift)) - return -EFAULT; - if (!dma->s->started) rme96xx_startcard(dma->s,exact); hwp = rme96xx_gethwptr(dma->s,0); @@ -1444,7 +1710,7 @@ /* this is the mapping */ - + vma->vm_flags &= ~VM_IO; dma->mmapped = 1; unlock_kernel(); return 0; @@ -1529,8 +1795,12 @@ { rme96xx_info *s = (rme96xx_info *)file->private_data; u32 status; + int spdifrate; status = readl(s->iobase + RME96xx_status_register); + /* hack to convert rev 1.5 SPDIF rate to "crystalrate" format HP 20020201 */ + rme96xx_spdif_sample_rate(s,&spdifrate); + status = (status & ~RME96xx_F) | ((spdifrate<<22) & RME96xx_F); VALIDATE_STATE(s); if (cmd == SOUND_MIXER_PRIVATE1) { @@ -1538,9 +1808,21 @@ if (copy_from_user(&mixer,(void*)arg,sizeof(mixer))) return -EFAULT; - if (file->f_mode & FMODE_WRITE) { - s->dma[mixer.devnr].outoffset = mixer.o_offset; - s->dma[mixer.devnr].inoffset = mixer.i_offset; + mixer.devnr &= RME96xx_MASK_DEVS; + if (mixer.devnr >= devices) + mixer.devnr = devices-1; + if (file->f_mode & FMODE_WRITE && !s->dma[mixer.devnr].opened) { + /* modify only if device not open */ + if (mixer.o_offset < 0) + mixer.o_offset = 0; + if (mixer.o_offset >= RME96xx_CHANNELS_PER_CARD) + mixer.o_offset = RME96xx_CHANNELS_PER_CARD-1; + if (mixer.i_offset < 0) + mixer.i_offset = 0; + if (mixer.i_offset >= RME96xx_CHANNELS_PER_CARD) + mixer.i_offset = RME96xx_CHANNELS_PER_CARD-1; + s->dma[mixer.devnr].outoffset = mixer.o_offset; + s->dma[mixer.devnr].inoffset = mixer.i_offset; } mixer.o_offset = s->dma[mixer.devnr].outoffset; @@ -1552,13 +1834,14 @@ return put_user(status, (int *)arg); } if (cmd == SOUND_MIXER_PRIVATE3) { - u32 control; - if (copy_from_user(&control,(void*)arg,sizeof(control))) - return -EFAULT; - if (file->f_mode & FMODE_WRITE) { - s->control_register = control; - writel(control,s->iobase + RME96xx_control_register); - } + u32 control; + if (copy_from_user(&control,(void*)arg,sizeof(control))) + return -EFAULT; + if (file->f_mode & FMODE_WRITE) { + s->control_register &= ~RME96xx_mixer_allowed; + s->control_register |= control & RME96xx_mixer_allowed; + writel(control,s->iobase + RME96xx_control_register); + } return put_user(s->control_register, (int *)arg); } diff -Nru a/sound/oss/rme96xx.h b/sound/oss/rme96xx.h --- a/sound/oss/rme96xx.h Fri Feb 14 00:27:27 2003 +++ b/sound/oss/rme96xx.h Fri Feb 14 00:27:27 2003 @@ -1,5 +1,12 @@ /* (C) 2000 Guenter Geiger with copy/pastes from the driver of Winfried Ritsch + +Modifications - Heiko Purnhagen + HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c + HP20020201 completed? + +A text/graphic control panel (rmectrl/xrmectrl) is available from + http://gige.xdv.org/pages/soft/pages/rme */ @@ -7,55 +14,65 @@ #define AFMT_S32_BLOCKED 0x0000400 #endif +/* AFMT_S16_BLOCKED not yet supported */ #ifndef AFMT_S16_BLOCKED #define AFMT_S16_BLOCKED 0x0000800 #endif typedef struct rme_status { - unsigned int irq:1; /* high or low */ - unsigned int lockmask:3; /* ADAT1, ADAT2, ADAT3 */ - unsigned int sr48:1; /* current sample rate */ - unsigned int wclock:1; /* wordclock used ? */ - unsigned int bufpoint:10; - - unsigned int syncmask:3; /* ADAT1, ADAT2, ADAT3 */ - unsigned int doublespeed:1; - unsigned int tc_busy:1; - unsigned int tc_out:1; - unsigned int crystalrate:3; - unsigned int spdif_error:1; - unsigned int bufid:1; - unsigned int tc_valid:1; + unsigned int irq:1; + unsigned int lockmask:3; /* ADAT input PLLs locked */ + /* 100=ADAT1, 010=ADAT2, 001=ADAT3 */ + unsigned int sr48:1; /* sample rate: 0=44.1/88.2 1=48/96 kHz */ + unsigned int wclock:1; /* 1=wordclock used */ + unsigned int bufpoint:10; + unsigned int syncmask:3; /* ADAT input in sync with system clock */ + /* 100=ADAT1, 010=ADAT2, 001=ADAT3 */ + unsigned int doublespeed:1; /* sample rate: 0=44.1/48 1=88.2/96 kHz */ + unsigned int tc_busy:1; + unsigned int tc_out:1; + unsigned int crystalrate:3; /* spdif input sample rate: */ + /* 000=64kHz, 100=88.2kHz, 011=96kHz */ + /* 111=32kHz, 110=44.1kHz, 101=48kHz */ + unsigned int spdif_error:1; /* 1=no spdif lock */ + unsigned int bufid:1; + unsigned int tc_valid:1; /* 1=timecode input detected */ + unsigned int spdif_read:1; } rme_status_t; +/* only fields marked W: can be modified by writing to SOUND_MIXER_PRIVATE3 */ typedef struct rme_control { - unsigned int start:1; - unsigned int latency:3; - - unsigned int master:1; - unsigned int ie:1; - unsigned int sr48:1; - unsigned int spare:1; - - unsigned int doublespeed:1; - unsigned int pro:1; - unsigned int emphasis:1; - unsigned int dolby:1; - - unsigned int opt_out:1; - unsigned int wordclock:1; - unsigned int spdif_in:2; - - unsigned int sync_ref:2; + unsigned int start:1; + unsigned int latency:3; /* buffer size / latency [samples]: */ + /* 0=64 ... 7=8192 */ + unsigned int master:1; /* W: clock mode: 1=master 0=slave/auto */ + unsigned int ie:1; + unsigned int sr48:1; /* samplerate 0=44.1/88.2, 1=48/96 kHz */ + unsigned int spare:1; + unsigned int doublespeed:1; /* double speed 0=44.1/48, 1=88.2/96 Khz */ + unsigned int pro:1; /* W: SPDIF-OUT 0=consumer, 1=professional */ + unsigned int emphasis:1; /* W: SPDIF-OUT emphasis 0=off, 1=on */ + unsigned int dolby:1; /* W: SPDIF-OUT non-audio bit 1=set, 0=unset */ + unsigned int opt_out:1; /* W: use 1st optical OUT as SPDIF: 1=yes, 0=no */ + unsigned int wordclock:1; /* W: use Wordclock as sync (overwrites master) */ + unsigned int spdif_in:2; /* W: SPDIF-IN: */ + /* 00=optical (ADAT1), 01=coaxial (Cinch), 10=internal CDROM */ + unsigned int sync_ref:2; /* W: preferred sync-source in autosync */ + /* 00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */ + unsigned int spdif_reset:1; + unsigned int spdif_select:1; + unsigned int spdif_clock:1; + unsigned int spdif_write:1; + unsigned int adat1_cd:1; /* W: Rev 1.5+: if set, internal CD connector carries ADAT */ } rme_ctrl_t; typedef struct _rme_mixer { - int i_offset; - int o_offset; - int devnr; - int spare[8]; + int i_offset; + int o_offset; + int devnr; + int spare[8]; } rme_mixer; diff -Nru a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c --- a/sound/oss/vwsnd.c Fri Feb 14 00:27:28 2003 +++ b/sound/oss/vwsnd.c Fri Feb 14 00:27:28 2003 @@ -3260,7 +3260,7 @@ li_writel(&lith, LI_HOST_CONTROLLER, LI_HC_LINK_ENABLE); do { w = li_readl(&lith, LI_HOST_CONTROLLER); - } while (w == LI_HC_LINK_ENABLE && jiffies < later); + } while (w == LI_HC_LINK_ENABLE && time_before(jiffies, later)); li_destroy(&lith); diff -Nru a/sound/pci/ens1370.c b/sound/pci/ens1370.c --- a/sound/pci/ens1370.c Fri Feb 14 00:27:29 2003 +++ b/sound/pci/ens1370.c Fri Feb 14 00:27:29 2003 @@ -1664,7 +1664,7 @@ if (!request_region(ensoniq->gameport.io, 8, "ens137x: gameport")) { #define ES___GAMEPORT_LOG_DELAY (30*HZ) // avoid log pollution: limit to 2 infos per minute - if (jiffies > last_jiffies + ES___GAMEPORT_LOG_DELAY) { + if (time_after(jiffies, last_jiffies + ES___GAMEPORT_LOG_DELAY)) { last_jiffies = jiffies; snd_printk("gameport io port 0x%03x in use", ensoniq->gameport.io); } diff -Nru a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c --- a/sound/pci/korg1212/korg1212.c Fri Feb 14 00:27:26 2003 +++ b/sound/pci/korg1212/korg1212.c Fri Feb 14 00:27:26 2003 @@ -598,7 +598,7 @@ return; if (!korg1212->inIRQ) schedule(); - } while (jiffies < endtime); + } while (time_before(jiffies, endtime)); writel(0, &korg1212->sharedBufferPtr->cardCommand); }